diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/htdsu/tapi.c | 5001 |
1 files changed, 5001 insertions, 0 deletions
diff --git a/private/ntos/ndis/htdsu/tapi.c b/private/ntos/ndis/htdsu/tapi.c new file mode 100644 index 000000000..f1622edda --- /dev/null +++ b/private/ntos/ndis/htdsu/tapi.c @@ -0,0 +1,5001 @@ +/***************************************************************************\ +|* Copyright (c) 1994 Microsoft Corporation *| +|* Developed for Microsoft by TriplePoint, Inc. Beaverton, Oregon *| +|* *| +|* This file is part of the HT Communications DSU41 WAN Miniport Driver. *| +\***************************************************************************/ +#include "version.h" +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Module Name: + + tapi.c + +Abstract: + + This module contains all the Miniport TAPI OID processing routines. It + is called by the MiniportSetInformation and MiniportQueryInformation + routines to handle the TAPI OIDs. + + This driver conforms to the NDIS 3.0 Miniport interface and provides + extensions to support Telephonic Services. + +Author: + + Larry Hattery - TriplePoint, Inc. (larryh@tpi.com) Jun-94 + +Environment: + + Windows NT 3.5 kernel mode Miniport driver or equivalent. + +Revision History: + +---------------------------------------------------------------------------*/ + +#define __FILEID__ 8 // Unique file ID for error logging + +#include "htdsu.h" + +# define TAPI_DEVICECLASS_NAME "tapi/line" +# define TAPI_DEVICECLASS_ID 1 +# define NDIS_DEVICECLASS_NAME "ndis" +# define NDIS_DEVICECLASS_ID 2 + +/* +// The following is a list of all the possible TAPI OIDs. +*/ +const NDIS_OID TapiSupportedArray[] = +{ +/* +// REQUIRED TAPI SPECIFIC OIDS +*/ + OID_TAPI_ANSWER, + OID_TAPI_CLOSE, + OID_TAPI_CLOSE_CALL, + OID_TAPI_CONDITIONAL_MEDIA_DETECTION, + OID_TAPI_DROP, + OID_TAPI_GET_ADDRESS_CAPS, + OID_TAPI_GET_ADDRESS_ID, + OID_TAPI_GET_ADDRESS_STATUS, + OID_TAPI_GET_CALL_ADDRESS_ID, + OID_TAPI_GET_CALL_INFO, + OID_TAPI_GET_CALL_STATUS, + OID_TAPI_GET_DEV_CAPS, + OID_TAPI_GET_DEV_CONFIG, + OID_TAPI_GET_EXTENSION_ID, + OID_TAPI_GET_ID, + OID_TAPI_GET_LINE_DEV_STATUS, + OID_TAPI_MAKE_CALL, + OID_TAPI_OPEN, + OID_TAPI_PROVIDER_INITIALIZE, + OID_TAPI_PROVIDER_SHUTDOWN, + OID_TAPI_SET_APP_SPECIFIC, + OID_TAPI_SET_CALL_PARAMS, + OID_TAPI_SET_DEFAULT_MEDIA_DETECTION, + OID_TAPI_SET_DEV_CONFIG, + OID_TAPI_SET_MEDIA_MODE, + OID_TAPI_SET_STATUS_MESSAGES, +/* +// OPTIONAL TAPI SPECIFIC OIDS +*/ + OID_TAPI_ACCEPT, + OID_TAPI_CONFIG_DIALOG, + OID_TAPI_DEV_SPECIFIC, + OID_TAPI_DIAL, + OID_TAPI_NEGOTIATE_EXT_VERSION, + OID_TAPI_SECURE_CALL, + OID_TAPI_SELECT_EXT_VERSION, + OID_TAPI_SEND_USER_USER_INFO, +}; + +#if DBG + +/* +// Make sure the following list is in the same order as the list above! +*/ +char *TapiSupportedNames[] = +{ +/* +// REQUIRED TAPI SPECIFIC OIDS +*/ + "OID_TAPI_ANSWER", + "OID_TAPI_CLOSE", + "OID_TAPI_CLOSE_CALL", + "OID_TAPI_CONDITIONAL_MEDIA_DETECTION", + "OID_TAPI_DROP", + "OID_TAPI_GET_ADDRESS_CAPS", + "OID_TAPI_GET_ADDRESS_ID", + "OID_TAPI_GET_ADDRESS_STATUS", + "OID_TAPI_GET_CALL_ADDRESS_ID", + "OID_TAPI_GET_CALL_INFO", + "OID_TAPI_GET_CALL_STATUS", + "OID_TAPI_GET_DEV_CAPS", + "OID_TAPI_GET_DEV_CONFIG", + "OID_TAPI_GET_EXTENSION_ID", + "OID_TAPI_GET_ID", + "OID_TAPI_GET_LINE_DEV_STATUS", + "OID_TAPI_MAKE_CALL", + "OID_TAPI_OPEN", + "OID_TAPI_PROVIDER_INITIALIZE", + "OID_TAPI_PROVIDER_SHUTDOWN", + "OID_TAPI_SET_APP_SPECIFIC", + "OID_TAPI_SET_CALL_PARAMS", + "OID_TAPI_SET_DEFAULT_MEDIA_DETECTION", + "OID_TAPI_SET_DEV_CONFIG", + "OID_TAPI_SET_MEDIA_MODE", + "OID_TAPI_SET_STATUS_MESSAGES", +/* +// OPTIONAL TAPI SPECIFIC OIDS +*/ + "OID_TAPI_ACCEPT", + "OID_TAPI_CONFIG_DIALOG", + "OID_TAPI_DEV_SPECIFIC", + "OID_TAPI_DIAL", + "OID_TAPI_NEGOTIATE_EXT_VERSION", + "OID_TAPI_SECURE_CALL", + "OID_TAPI_SELECT_EXT_VERSION", + "OID_TAPI_SEND_USER_USER_INFO", + + "OID_TAPI_UNKNOWN" +}; + +#define NUM_OID_ENTRIES (sizeof(TapiSupportedArray) / sizeof(TapiSupportedArray[0])) + +/* +// This debug routine will lookup the printable name for the selected OID. +*/ +char * +HtTapiGetOidString(NDIS_OID Oid) +{ + UINT i; + + for (i = 0; i < NUM_OID_ENTRIES-1; i++) + { + if (TapiSupportedArray[i] == Oid) + { + break; + } + } + return(TapiSupportedNames[i]); +} + +#endif // DBG + + +NDIS_STATUS +HtTapiQueryInformation( + IN PHTDSU_ADAPTER Adapter, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + The HtTapiQueryInformation 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 driver until + this request has been completed. + + Interrupts are in any state during this call. + +Parameters: + + MiniportAdapterContext _ The adapter handle passed to NdisMSetAttributes + during MiniportInitialize. + + Oid _ The OID. (See section 2.2.1 of the Extensions to NDIS 3.0 Miniports + to support Telephonic Services specification for a complete + description of the OIDs.) + + InformationBuffer _ The buffer that will receive the information. + + InformationBufferLength _ The length in bytes of InformationBuffer. + + BytesWritten _ Returns the number of bytes written into + InformationBuffer. + + BytesNeeded _ This parameter returns the number of additional bytes + needed to satisfy the OID. + +Return Values: + + NDIS_STATUS_INVALID_DATA + NDIS_STATUS_INVALID_LENGTH + NDIS_STATUS_INVALID_OID + NDIS_STATUS_NOT_ACCEPTED + NDIS_STATUS_NOT_SUPPORTED + NDIS_STATUS_PENDING + NDIS_STATUS_RESOURCES + NDIS_STATUS_SUCCESS + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiQueryInformation") + + /* + // Assume the worst, and initialize to handle failure. + */ + NDIS_STATUS Status = NDIS_STATUS_INVALID_LENGTH; + ULONG NumBytesNeeded = 0; + ULONG NumBytesWritten = 0; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter,DBG_REQUEST_ON, + ("(OID=%s=%08x)\n\t\tInfoLength=%d InfoBuffer=%Xh\n", + HtTapiGetOidString(Oid),Oid, + InformationBufferLength, + InformationBuffer + )); + + /* + // Determine which OID is being requested and do the right thing. + // The switch code will just call the approriate service function + // to do the real work, so there's not much to worry about here. + */ + switch (Oid) + { + case OID_TAPI_CONFIG_DIALOG: // OPTIONAL + if(InformationBufferLength < sizeof(NDIS_TAPI_CONFIG_DIALOG)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_CONFIG_DIALOG); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiConfigDialog(Adapter, + (PNDIS_TAPI_CONFIG_DIALOG) InformationBuffer); + break; + + case OID_TAPI_DEV_SPECIFIC: // OPTIONAL + if(InformationBufferLength < sizeof(NDIS_TAPI_DEV_SPECIFIC)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_DEV_SPECIFIC); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiDevSpecific(Adapter, + (PNDIS_TAPI_DEV_SPECIFIC) InformationBuffer); + break; + + case OID_TAPI_GET_ADDRESS_CAPS: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_ADDRESS_CAPS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_ADDRESS_CAPS); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetAddressCaps(Adapter, + (PNDIS_TAPI_GET_ADDRESS_CAPS) InformationBuffer); + break; + + case OID_TAPI_GET_ADDRESS_ID: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_ADDRESS_ID)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_ADDRESS_ID); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetAddressID(Adapter, + (PNDIS_TAPI_GET_ADDRESS_ID) InformationBuffer); + break; + + case OID_TAPI_GET_ADDRESS_STATUS: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_ADDRESS_STATUS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_ADDRESS_STATUS); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetAddressStatus(Adapter, + (PNDIS_TAPI_GET_ADDRESS_STATUS) InformationBuffer); + break; + + case OID_TAPI_GET_CALL_ADDRESS_ID: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_CALL_ADDRESS_ID)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_CALL_ADDRESS_ID); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetCallAddressID(Adapter, + (PNDIS_TAPI_GET_CALL_ADDRESS_ID) InformationBuffer); + break; + + case OID_TAPI_GET_CALL_INFO: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_CALL_INFO)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_CALL_INFO); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetCallInfo(Adapter, + (PNDIS_TAPI_GET_CALL_INFO) InformationBuffer); + break; + + case OID_TAPI_GET_CALL_STATUS: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_CALL_STATUS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_CALL_STATUS); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetCallStatus(Adapter, + (PNDIS_TAPI_GET_CALL_STATUS) InformationBuffer); + break; + + case OID_TAPI_GET_DEV_CAPS: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_DEV_CAPS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_DEV_CAPS); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetDevCaps(Adapter, + (PNDIS_TAPI_GET_DEV_CAPS) InformationBuffer); + break; + + case OID_TAPI_GET_DEV_CONFIG: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_DEV_CONFIG)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_DEV_CONFIG); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetDevConfig(Adapter, + (PNDIS_TAPI_GET_DEV_CONFIG) InformationBuffer); + break; + + case OID_TAPI_GET_EXTENSION_ID: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_EXTENSION_ID)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_EXTENSION_ID); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetExtensionID(Adapter, + (PNDIS_TAPI_GET_EXTENSION_ID) InformationBuffer); + break; + + case OID_TAPI_GET_ID: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_ID)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_ID); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetID(Adapter, + (PNDIS_TAPI_GET_ID) InformationBuffer); + break; + + case OID_TAPI_GET_LINE_DEV_STATUS: + if(InformationBufferLength < sizeof(NDIS_TAPI_GET_LINE_DEV_STATUS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_GET_LINE_DEV_STATUS); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiGetLineDevStatus(Adapter, + (PNDIS_TAPI_GET_LINE_DEV_STATUS) InformationBuffer); + break; + + case OID_TAPI_MAKE_CALL: + if(InformationBufferLength < sizeof(NDIS_TAPI_MAKE_CALL)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_MAKE_CALL); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiMakeCall(Adapter, + (PNDIS_TAPI_MAKE_CALL) InformationBuffer); + break; + + case OID_TAPI_NEGOTIATE_EXT_VERSION:// OPTIONAL + if(InformationBufferLength < sizeof(NDIS_TAPI_NEGOTIATE_EXT_VERSION)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_NEGOTIATE_EXT_VERSION); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiNegotiateExtVersion(Adapter, + (PNDIS_TAPI_NEGOTIATE_EXT_VERSION) InformationBuffer); + break; + + case OID_TAPI_OPEN: + if(InformationBufferLength < sizeof(NDIS_TAPI_OPEN)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_OPEN); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiOpen(Adapter, + (PNDIS_TAPI_OPEN) InformationBuffer); + break; + + case OID_TAPI_PROVIDER_INITIALIZE: + if(InformationBufferLength < sizeof(OID_TAPI_PROVIDER_INITIALIZE)) + { + NumBytesNeeded = sizeof(OID_TAPI_PROVIDER_INITIALIZE); + break; + } + NumBytesWritten = NumBytesNeeded = InformationBufferLength; + Status = HtTapiProviderInitialize(Adapter, + (PNDIS_TAPI_PROVIDER_INITIALIZE) InformationBuffer); + break; + + default: + /* + // Unknown OID + */ + Status = NDIS_STATUS_INVALID_OID; + break; + } + + /* + // Fill in the size fields before we leave as indicated by the + // status we are returning. + */ + if (Status == NDIS_STATUS_INVALID_LENGTH) + { + *BytesNeeded = NumBytesNeeded; + *BytesWritten = 0; + } + else + { + *BytesNeeded = *BytesWritten = NumBytesWritten; + } + DBG_FILTER(Adapter,DBG_REQUEST_ON, + ("RETURN: Status=%Xh Needed=%d Written=%d\n", + Status, *BytesNeeded, *BytesWritten)); + + DBG_LEAVE(Adapter); + + return (Status); +} + + +NDIS_STATUS +HtTapiSetInformation( + IN PHTDSU_ADAPTER Adapter, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + The HtTapiQueryInformation request allows for control of the TAPI + portion of the driver's settings and current line status. + + If the Miniport does not complete the call immediately (by returning + NDIS_STATUS_PENDING), it must call NdisMSetInformationComplete to + complete the call. The Miniport controls the buffers pointed to by + InformationBuffer, BytesRead, and BytesNeeded until the request completes. + + Interrupts are in any state during the call, and no other requests will + be submitted to the Miniport until this request is completed. + +Parameters: + + MiniportAdapterContext _ The adapter handle passed to NdisMSetAttributes + during MiniportInitialize. + + Oid _ The OID. (See section 2.2.2 of the Extensions to NDIS 3.0 Miniports + to support Telephonic Services specification for a complete + description of the OIDs.) + + InformationBuffer _ The buffer that will receive the information. + + InformationBufferLength _ The length in bytes of InformationBuffer. + + BytesRead_ Returns the number of bytes read from InformationBuffer. + + BytesNeeded _ This parameter returns the number of additional bytes + expected to satisfy the OID. + +Return Values: + + NDIS_STATUS_INVALID_DATA + NDIS_STATUS_INVALID_LENGTH + NDIS_STATUS_INVALID_OID + NDIS_STATUS_NOT_ACCEPTED + NDIS_STATUS_NOT_SUPPORTED + NDIS_STATUS_PENDING + NDIS_STATUS_RESOURCES + NDIS_STATUS_SUCCESS + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetInformation") + + /* + // Assume the worst, and initialize to handle failure. + */ + NDIS_STATUS Status = NDIS_STATUS_INVALID_LENGTH; + ULONG NumBytesNeeded = 0; + ULONG NumBytesRead = 0; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter,DBG_REQUEST_ON, + ("(OID=%s=%08x)\n\t\tInfoLength=%d InfoBuffer=%Xh\n", + HtTapiGetOidString(Oid),Oid, + InformationBufferLength, + InformationBuffer + )); + + /* + // Determine which OID is being requested and do the right thing. + // The switch code will just call the approriate service function + // to do the real work, so there's not much to worry about here either. + */ + switch (Oid) + { + case OID_TAPI_ACCEPT: // OPTIONAL + if (InformationBufferLength < sizeof(NDIS_TAPI_ACCEPT)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_ACCEPT); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiAccept(Adapter, + (PNDIS_TAPI_ACCEPT) InformationBuffer); + break; + + case OID_TAPI_ANSWER: + if (InformationBufferLength < sizeof(NDIS_TAPI_ANSWER)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_ANSWER); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiAnswer(Adapter, + (PNDIS_TAPI_ANSWER) InformationBuffer); + break; + + case OID_TAPI_CLOSE: + if (InformationBufferLength < sizeof(NDIS_TAPI_CLOSE)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_CLOSE); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiClose(Adapter, + (PNDIS_TAPI_CLOSE) InformationBuffer); + break; + + case OID_TAPI_CLOSE_CALL: + if (InformationBufferLength < sizeof(NDIS_TAPI_CLOSE_CALL)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_CLOSE_CALL); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiCloseCall(Adapter, + (PNDIS_TAPI_CLOSE_CALL) InformationBuffer); + break; + + case OID_TAPI_CONDITIONAL_MEDIA_DETECTION: + if (InformationBufferLength < sizeof(NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiConditionalMediaDetection(Adapter, + (PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION) InformationBuffer); + break; + + case OID_TAPI_DIAL: // OPTIONAL + if (InformationBufferLength < sizeof(NDIS_TAPI_DIAL)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_DIAL); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiDial(Adapter, + (PNDIS_TAPI_DIAL) InformationBuffer); + break; + + case OID_TAPI_DROP: + if (InformationBufferLength < sizeof(NDIS_TAPI_DROP)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_DROP); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiDrop(Adapter, + (PNDIS_TAPI_DROP) InformationBuffer); + break; + + case OID_TAPI_PROVIDER_SHUTDOWN: + if (InformationBufferLength < sizeof(NDIS_TAPI_PROVIDER_SHUTDOWN)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_PROVIDER_SHUTDOWN); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiProviderShutdown(Adapter, + (PNDIS_TAPI_PROVIDER_SHUTDOWN) InformationBuffer); + break; + + case OID_TAPI_SECURE_CALL: // OPTIONAL + if (InformationBufferLength < sizeof(NDIS_TAPI_SECURE_CALL)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SECURE_CALL); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSecureCall(Adapter, + (PNDIS_TAPI_SECURE_CALL) InformationBuffer); + break; + + case OID_TAPI_SELECT_EXT_VERSION: // OPTIONAL + if (InformationBufferLength < sizeof(NDIS_TAPI_SELECT_EXT_VERSION)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SELECT_EXT_VERSION); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSelectExtVersion(Adapter, + (PNDIS_TAPI_SELECT_EXT_VERSION) InformationBuffer); + break; + + case OID_TAPI_SEND_USER_USER_INFO: // OPTIONAL + if (InformationBufferLength < sizeof(NDIS_TAPI_SEND_USER_USER_INFO)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SEND_USER_USER_INFO); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSendUserUserInfo(Adapter, + (PNDIS_TAPI_SEND_USER_USER_INFO) InformationBuffer); + break; + + case OID_TAPI_SET_APP_SPECIFIC: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_APP_SPECIFIC)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_APP_SPECIFIC); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetAppSpecific(Adapter, + (PNDIS_TAPI_SET_APP_SPECIFIC) InformationBuffer); + break; + + case OID_TAPI_SET_CALL_PARAMS: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_CALL_PARAMS)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_CALL_PARAMS); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetCallParams(Adapter, + (PNDIS_TAPI_SET_CALL_PARAMS) InformationBuffer); + break; + + case OID_TAPI_SET_DEFAULT_MEDIA_DETECTION: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetDefaultMediaDetection(Adapter, + (PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION) InformationBuffer); + break; + + case OID_TAPI_SET_DEV_CONFIG: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_DEV_CONFIG)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_DEV_CONFIG); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetDevConfig(Adapter, + (PNDIS_TAPI_SET_DEV_CONFIG) InformationBuffer); + break; + + case OID_TAPI_SET_MEDIA_MODE: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_MEDIA_MODE)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_MEDIA_MODE); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetMediaMode(Adapter, + (PNDIS_TAPI_SET_MEDIA_MODE) InformationBuffer); + break; + + case OID_TAPI_SET_STATUS_MESSAGES: + if (InformationBufferLength < sizeof(NDIS_TAPI_SET_STATUS_MESSAGES)) + { + NumBytesNeeded = sizeof(NDIS_TAPI_SET_STATUS_MESSAGES); + break; + } + NumBytesRead = NumBytesNeeded = InformationBufferLength; + Status = HtTapiSetStatusMessages(Adapter, + (PNDIS_TAPI_SET_STATUS_MESSAGES) InformationBuffer); + break; + + default: + Status = NDIS_STATUS_INVALID_OID; + break; + } + + /* + // Fill in the size fields before we leave as indicated by the + // status we are returning. + */ + if (Status == NDIS_STATUS_INVALID_LENGTH) + { + *BytesNeeded = NumBytesNeeded; + *BytesRead = 0; + } + else + { + *BytesNeeded = *BytesRead = NumBytesRead; + } + DBG_FILTER(Adapter,DBG_REQUEST_ON, + ("RETURN: Status=%Xh Needed=%d Read=%d\n", + Status, *BytesNeeded, *BytesRead)); + + DBG_LEAVE(Adapter); + + return (Status); +} + + +NDIS_STATUS +HtTapiGetID( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_ID Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns a device ID for the specified device class + associated with the selected line, address or call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_ID + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulAddressID; + IN HDRV_CALL hdCall; + IN ULONG ulSelect; + IN ULONG ulDeviceClassSize; + IN ULONG ulDeviceClassOffset; + OUT VAR_STRING DeviceID; + + } NDIS_TAPI_GET_ID, *PNDIS_TAPI_GET_ID; + + typedef struct _VAR_STRING + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulStringFormat; + ULONG ulStringSize; + ULONG ulStringOffset; + + } VAR_STRING, *PVAR_STRING; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALDEVICECLASS + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_INVALADDRESSID + NDIS_STATUS_TAPI_INVALCALLHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetID") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Remember which device class is being requested. + */ + UINT DeviceClass; + + /* + // A pointer to the requested device ID, and its size in bytes. + */ + PUCHAR IDPtr; + UINT IDLength; + ULONG DeviceID; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulAddressID=%d\n" + "hdCall=%Xh\n" + "ulSelect=%Xh\n" + "ulDeviceClassSize=%d\n" + "ulDeviceClassOffset=%Xh\n", + Request->hdLine, + Request->ulAddressID, + Request->hdCall, + Request->ulSelect, + Request->ulDeviceClassSize, + Request->ulDeviceClassOffset + )); + /* + // Make sure this is a tapi/line or ndis request. + */ + if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = NDIS_DEVICECLASS_ID; + } + else if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = TAPI_DEVICECLASS_ID; + } + else + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + + /* + // Find the link structure associated with the request/deviceclass. + */ + if (Request->ulSelect == LINECALLSELECT_LINE) + { + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + if (DeviceClass == TAPI_DEVICECLASS_ID) + { + /* + // TAPI just wants the ulDeviceID for this line. + */ + DeviceID = (ULONG) GET_DEVICEID_FROM_LINK(Adapter, Link); + IDLength = sizeof(DeviceID); + IDPtr = (PUCHAR) &DeviceID; + } + else // UNSUPPORTED DEVICE CLASS + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + } + else if (Request->ulSelect == LINECALLSELECT_ADDRESS) + { + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + if (Request->ulAddressID >= HTDSU_TAPI_NUM_ADDRESSES) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n")); + return (NDIS_STATUS_TAPI_INVALADDRESSID); + } + + /* + // Currently, there is no defined return value for this case... + // This is just a place holder for future extensions. + */ + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + else if (Request->ulSelect == LINECALLSELECT_CALL) + { + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + if (DeviceClass == NDIS_DEVICECLASS_ID) + { + /* + // This must match ConnectionWrapperID used in LINE_UP event! + */ + DeviceID = (ULONG) Link->htCall; + IDLength = sizeof(DeviceID); + IDPtr = (PUCHAR) &DeviceID; + } + else // UNSUPPORTED DEVICE CLASS + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + } + else + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_FAILURE\n")); + return (NDIS_STATUS_FAILURE); + } + + DBG_NOTICE(Adapter, ("GETID-%d=%Xh\n",Request->ulSelect,DeviceID)); + + /* + // Now we need to adjust the variable field to place the device ID. + */ + Request->DeviceID.ulNeededSize = sizeof(VAR_STRING) + IDLength; + if (Request->DeviceID.ulTotalSize >= Request->DeviceID.ulNeededSize) + { + Request->DeviceID.ulUsedSize = Request->DeviceID.ulNeededSize; + Request->DeviceID.ulStringFormat = STRINGFORMAT_BINARY; + Request->DeviceID.ulStringSize = IDLength; + Request->DeviceID.ulStringOffset = sizeof(VAR_STRING); + + /* + // Now we return the requested ID value. + */ + NdisMoveMemory( + (PCHAR) &Request->DeviceID + sizeof(VAR_STRING), + IDPtr, + IDLength + ); + } + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetDevConfig( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_DEV_CONFIG Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns a data structure object, the contents of which are + specific to the line (miniport) and device class, giving the current + configuration of a device associated one-to-one with the line device. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_DEV_CONFIG + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulDeviceClassSize; + IN ULONG ulDeviceClassOffset; + OUT VAR_STRING DeviceConfig; + + } NDIS_TAPI_GET_DEV_CONFIG, *PNDIS_TAPI_GET_DEV_CONFIG; + + typedef struct _VAR_STRING + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulStringFormat; + ULONG ulStringSize; + ULONG ulStringOffset; + + } VAR_STRING, *PVAR_STRING; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALDEVICECLASS + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetDevConfig") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Remember which device class is being requested. + */ + UINT DeviceClass; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulDeviceClassSize=%d\n" + "ulDeviceClassOffset=%Xh\n", + Request->ulDeviceID, + Request->ulDeviceClassSize, + Request->ulDeviceClassOffset + )); + /* + // Make sure this is a tapi/line or ndis request. + */ + if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = NDIS_DEVICECLASS_ID; + } + else if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = TAPI_DEVICECLASS_ID; + } + else + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + + /* + // Now we need to adjust the variable field to place the requested device + // configuration. + */ +# define SIZEOF_DEVCONFIG sizeof(ULONG) + Request->DeviceConfig.ulNeededSize = sizeof(VAR_STRING) + SIZEOF_DEVCONFIG; + if (Request->DeviceConfig.ulTotalSize >= Request->DeviceConfig.ulNeededSize) + { + Request->DeviceConfig.ulUsedSize = Request->DeviceConfig.ulNeededSize; + Request->DeviceConfig.ulStringFormat = STRINGFORMAT_BINARY; + Request->DeviceConfig.ulStringSize = SIZEOF_DEVCONFIG; + Request->DeviceConfig.ulStringOffset = sizeof(VAR_STRING); + + /* + // There are currently no return values defined for this case. + // This is just a place holder for future extensions. + */ + *((ULONG *) ((PCHAR) &Request->DeviceConfig + sizeof(VAR_STRING))) = + 0xDEADBEEF; + } + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiSetDevConfig( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_DEV_CONFIG Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request restores the configuration of a device associated one-to-one + with the line device from an “” data structure previously obtained using + OID_TAPI_GET_DEV_CONFIG. The contents of this data structure are specific + to the line (miniport) and device class. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_DEV_CONFIG + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulDeviceClassSize; + IN ULONG ulDeviceClassOffset; + IN ULONG ulDeviceConfigSize; + IN UCHAR DeviceConfig[1]; + + } NDIS_TAPI_SET_DEV_CONFIG, *PNDIS_TAPI_SET_DEV_CONFIG; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALDEVICECLASS + NDIS_STATUS_TAPI_INVALPARAM + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetDevConfig") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Remember which device class is being requested. + */ + UINT DeviceClass; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulDeviceClassSize=%d\n" + "ulDeviceClassOffset=%d\n" + "ulDeviceConfigSize=%d\n", + Request->ulDeviceID, + Request->ulDeviceClassSize, + Request->ulDeviceClassOffset, + Request->ulDeviceConfigSize + )); + /* + // Make sure this is a tapi/line or ndis request. + */ + if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = NDIS_DEVICECLASS_ID; + } + else if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = TAPI_DEVICECLASS_ID; + } + else + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + + /* + // Make sure this configuration is the proper size. + */ + if (Request->ulDeviceConfigSize != SIZEOF_DEVCONFIG) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALPARAM\n")); + return (NDIS_STATUS_TAPI_INVALPARAM); + } + + /* + // Retore the configuration information returned by HtTapiGetDevConfig. + // + // There are currently no configuration values defined this case. + // This is just a place holder for future extensions. + */ + if (*((ULONG *) ((PCHAR) Request->DeviceConfig)) != 0xDEADBEEF) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALPARAM\n")); + return (NDIS_STATUS_TAPI_INVALPARAM); + } + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiConfigDialog( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_CONFIG_DIALOG Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request retrieves the name of a user-mode dynamic link library that + can be loaded and called to configure the specified device. The + configuration DLL shall export the following function by name: + + LONG WINAPI + ConfigDialog( + IN HWND hwndOwner, + IN ULONG ulDeviceID, + IN LPCSTR lpszDeviceClass + ); + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_CONFIG_DIALOG + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulDeviceClassSize; + IN ULONG ulDeviceClassOffset; + IN ULONG ulLibraryNameTotalSize; + OUT ULONG ulLibraryNameNeededSize; + OUT CHAR szLibraryName[1]; + + } NDIS_TAPI_CONFIG_DIALOG, *PNDIS_TAPI_CONFIG_DIALOG; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALDEVICECLASS + NDIS_STATUS_STRUCTURETOOSMALL + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiConfigDialog") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Remember which device class is being requested. + */ + UINT DeviceClass; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulDeviceClassSize=%d\n" + "ulDeviceClassOffset=%Xh\n" + "ulLibraryNameTotalSize=%d\n", + Request->ulDeviceID, + Request->ulDeviceClassSize, + Request->ulDeviceClassOffset, + Request->ulLibraryNameTotalSize + )); + /* + // Make sure this is a tapi/line or ndis request. + */ + if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = NDIS_DEVICECLASS_ID; + } + else if (_strnicmp((PCHAR) Request + Request->ulDeviceClassOffset, + TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize) == 0) + { + DeviceClass = TAPI_DEVICECLASS_ID; + } + else + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n")); + return (NDIS_STATUS_TAPI_INVALDEVICECLASS); + } + + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + + /* + // Copy the name of our configuration DLL which we read from the registry + // during startup, and which was placed there during installation. + // + // This driver does not provide a configuration DLL. + // This is just a place holder for future extensions. + */ + Request->ulLibraryNameNeededSize = strlen(Adapter->ConfigDLLName) + 1; + if (Request->ulLibraryNameTotalSize < Request->ulLibraryNameNeededSize) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_STRUCTURETOOSMALL\n")); + return (NDIS_STATUS_TAPI_STRUCTURETOOSMALL); + } + NdisMoveMemory( + Request->szLibraryName, + Adapter->ConfigDLLName, + Request->ulLibraryNameNeededSize + ); + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiDevSpecific( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_DEV_SPECIFIC Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request is used as a general extension mechanism to enable miniports + to provide access to features not described in other operations. The meaning + of the extensions are device-specific, and taking advantage of these + extensions requires the application to be fully aware of them. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_DEV_SPECIFIC + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulAddressID; + IN HDRV_CALL hdCall; + IN OUT ULONG ulParamsSize; + IN OUT UCHAR Params[1]; + + } NDIS_TAPI_DEV_SPECIFIC, *PNDIS_TAPI_DEV_SPECIFIC; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiDevSpecific") + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulAddressID=%d\n" + "hdCall=%Xh\n" + "ulParamsSize=%d\n" + "Params=%Xh\n", + Request->hdLine, + Request->ulAddressID, + Request->hdCall, + Request->ulParamsSize, + Request->Params + )); + /* + // You can do what ever you want here, so long as the application + // agrees with you. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiGetAddressID( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_ADDRESS_ID Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns the address ID associated with address in a different + format on the specified line. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_ADDRESS_ID + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + OUT ULONG ulAddressID; + IN ULONG ulAddressMode; + IN ULONG ulAddressSize; + IN CHAR szAddress[1]; + + } NDIS_TAPI_GET_ADDRESS_ID, *PNDIS_TAPI_GET_ADDRESS_ID; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_RESOURCEUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetAddressID") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulAddressMode=%Xh\n" + "ulAddressSize=%d\n" + "szAddress=%Xh\n", + Request->hdLine, + Request->ulAddressMode, + Request->ulAddressSize, + Request->szAddress + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // The spec sez it has to be this mode! Otherwise, we already know + // that the address ID is (0..N-1). + */ + if (Request->ulAddressMode != LINEADDRESSMODE_DIALABLEADDR) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_FAILURE\n")); + return (NDIS_STATUS_FAILURE); + } + + /* + // Make sure we have enough room set aside for this address string. + */ + if (Request->ulAddressSize > sizeof(Link->LineAddress)-1) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_RESOURCEUNAVAIL\n")); + return (NDIS_STATUS_TAPI_RESOURCEUNAVAIL); + } + + /* + // You may need to search each link to find the associated Address. + // However, this adapter has only one address per link so it's an + // easy task. + */ + Request->ulAddressID = HTDSU_TAPI_ADDRESSID; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetAddressCaps( + PHTDSU_ADAPTER Adapter, + PNDIS_TAPI_GET_ADDRESS_CAPS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request queries the specified address on the specified line device + to determine its telephony capabilities. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_ADDRESS_CAPS + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulAddressID; + IN ULONG ulExtVersion; + OUT LINE_ADDRESS_CAPS LineAddressCaps; + + } NDIS_TAPI_GET_ADDRESS_CAPS, *PNDIS_TAPI_GET_ADDRESS_CAPS; + + typedef struct _LINE_ADDRESS_CAPS + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulLineDeviceID; + + ULONG ulAddressSize; + ULONG ulAddressOffset; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + ULONG ulAddressSharing; + ULONG ulAddressStates; + ULONG ulCallInfoStates; + ULONG ulCallerIDFlags; + ULONG ulCalledIDFlags; + ULONG ulConnectedIDFlags; + ULONG ulRedirectionIDFlags; + ULONG ulRedirectingIDFlags; + ULONG ulCallStates; + ULONG ulDialToneModes; + ULONG ulBusyModes; + ULONG ulSpecialInfo; + ULONG ulDisconnectModes; + + ULONG ulMaxNumActiveCalls; + ULONG ulMaxNumOnHoldCalls; + ULONG ulMaxNumOnHoldPendingCalls; + ULONG ulMaxNumConference; + ULONG ulMaxNumTransConf; + + ULONG ulAddrCapFlags; + ULONG ulCallFeatures; + ULONG ulRemoveFromConfCaps; + ULONG ulRemoveFromConfState; + ULONG ulTransferModes; + ULONG ulParkModes; + + ULONG ulForwardModes; + ULONG ulMaxForwardEntries; + ULONG ulMaxSpecificEntries; + ULONG ulMinFwdNumRings; + ULONG ulMaxFwdNumRings; + + ULONG ulMaxCallCompletions; + ULONG ulCallCompletionConds; + ULONG ulCallCompletionModes; + ULONG ulNumCompletionMessages; + ULONG ulCompletionMsgTextEntrySize; + ULONG ulCompletionMsgTextSize; + ULONG ulCompletionMsgTextOffset; + + } LINE_ADDRESS_CAPS, *PLINE_ADDRESS_CAPS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALADDRESSID + NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetAddressCaps") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Length of the address string assigned to this line device. + */ + UINT AddressLength; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulAddressID=%d\n" + "ulExtVersion=%Xh\n", + Request->ulDeviceID, + Request->ulAddressID, + Request->ulExtVersion + )); + /* + // Make sure the address is within range - we only support one per line. + */ + if (Request->ulAddressID >= HTDSU_TAPI_NUM_ADDRESSES) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n")); + return (NDIS_STATUS_TAPI_INVALADDRESSID); + } + + /* + // Make sure we are speaking the same language. + */ +#ifdef NDISTAPI_BUG_FIXED + if (Request->ulExtVersion != 0 && + Request->ulExtVersion != HTDSU_TAPI_EXT_VERSION) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION\n")); + return (NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION); + } +#endif + + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineAddressCaps.ulNeededSize = + Request->LineAddressCaps.ulUsedSize = sizeof(Request->LineAddressCaps); +#endif + + Request->LineAddressCaps.ulLineDeviceID = Request->ulDeviceID; + + /* + // RASTAPI requires the "I L A" be placed in the Address field at the end + // of this structure. Where: + // I = The device intance assigned to this adapter in the registry + // \LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\I + // L = The device line number associated with this line (1..NumLines) + // A = The address (channel) to be used on this line (0..NumAddresses-1) + */ + AddressLength = strlen(Link->LineAddress) + 1; + Request->LineAddressCaps.ulNeededSize += AddressLength; + if (Request->LineAddressCaps.ulNeededSize <= Request->LineAddressCaps.ulTotalSize) + { + Request->LineAddressCaps.ulAddressSize = AddressLength; + Request->LineAddressCaps.ulAddressOffset = sizeof(Request->LineAddressCaps); + NdisMoveMemory((PUCHAR) &Request->LineAddressCaps + + Request->LineAddressCaps.ulAddressOffset, + Link->LineAddress, + AddressLength + ); + Request->LineAddressCaps.ulUsedSize += AddressLength; + } + + /* + // Return the various address capabilites for the adapter. + */ + Request->LineAddressCaps.ulAddressSharing = LINEADDRESSSHARING_PRIVATE; + Request->LineAddressCaps.ulAddressStates = Link->AddressStatesCaps; + Request->LineAddressCaps.ulCallStates = Link->CallStatesCaps; + Request->LineAddressCaps.ulDialToneModes = LINEDIALTONEMODE_NORMAL; + Request->LineAddressCaps.ulSpecialInfo = LINESPECIALINFO_UNAVAIL; + Request->LineAddressCaps.ulDisconnectModes = + LINEDISCONNECTMODE_NORMAL | + LINEDISCONNECTMODE_UNKNOWN | + LINEDISCONNECTMODE_BUSY | + LINEDISCONNECTMODE_NOANSWER; + /* + // This device does not support conference calls, transfers, or holds. + */ + Request->LineAddressCaps.ulMaxNumActiveCalls = 1; + Request->LineAddressCaps.ulMaxNumTransConf = 1; + Request->LineAddressCaps.ulAddrCapFlags = + Link->LineMode == HTDSU_LINEMODE_LEASED ? 0 : LINEADDRCAPFLAGS_DIALED; + Request->LineAddressCaps.ulCallFeatures = + LINECALLFEATURE_ACCEPT | + LINECALLFEATURE_ANSWER | + LINECALLFEATURE_COMPLETECALL | + LINECALLFEATURE_DIAL | + LINECALLFEATURE_DROP; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetAddressStatus( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_ADDRESS_STATUS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request queries the specified address for its current status. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_ADDRESS_STATUS + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulAddressID; + OUT LINE_ADDRESS_STATUS LineAddressStatus; + + } NDIS_TAPI_GET_ADDRESS_STATUS, *PNDIS_TAPI_GET_ADDRESS_STATUS; + + typedef struct _LINE_ADDRESS_STATUS + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulNumInUse; + ULONG ulNumActiveCalls; + ULONG ulNumOnHoldCalls; + ULONG ulNumOnHoldPendCalls; + ULONG ulAddressFeatures; + + ULONG ulNumRingsNoAnswer; + ULONG ulForwardNumEntries; + ULONG ulForwardSize; + ULONG ulForwardOffset; + + ULONG ulTerminalModesSize; + ULONG ulTerminalModesOffset; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + } LINE_ADDRESS_STATUS, *PLINE_ADDRESS_STATUS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_INVALADDRESSID + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetAddressStatus") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulAddressID=%d\n", + Request->hdLine, + Request->ulAddressID + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // Make sure the address is within range - we only support one per line. + */ + if (Request->ulAddressID >= HTDSU_TAPI_NUM_ADDRESSES) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n")); + return (NDIS_STATUS_TAPI_INVALADDRESSID); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineAddressStatus.ulNeededSize = + Request->LineAddressStatus.ulUsedSize = sizeof(Request->LineAddressStatus); +#endif + + /* + // Return the current status information for the line. + */ + Request->LineAddressStatus.ulNumInUse = + Link->CallState == LINECALLSTATE_IDLE ? 0 : 1; + Request->LineAddressStatus.ulNumActiveCalls = + Link->CallState == LINECALLSTATE_IDLE ? 0 : 1; + Request->LineAddressStatus.ulAddressFeatures = + Link->CallState == LINECALLSTATE_IDLE ? + LINEADDRFEATURE_MAKECALL : 0; + Request->LineAddressStatus.ulNumRingsNoAnswer = 999; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetCallAddressID( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_CALL_ADDRESS_ID Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request retrieves the address ID for the indicated call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_CALL_ADDRESS_ID + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + OUT ULONG ulAddressID; + + } NDIS_TAPI_GET_CALL_ADDRESS_ID, *PNDIS_TAPI_GET_CALL_ADDRESS_ID; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetCallAddressID") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n", + Request->hdCall + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // Return the address ID associated with this call. + */ + Request->ulAddressID = HTDSU_TAPI_ADDRESSID; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetCallInfo( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_CALL_INFO Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns detailed information about the specified call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_CALL_INFO + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + OUT LINE_CALL_INFO LineCallInfo; + + } NDIS_TAPI_GET_CALL_INFO, *PNDIS_TAPI_GET_CALL_INFO; + + typedef struct _LINE_CALL_INFO + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG hLine; + ULONG ulLineDeviceID; + ULONG ulAddressID; + + ULONG ulBearerMode; + ULONG ulRate; + ULONG ulMediaMode; + + ULONG ulAppSpecific; + ULONG ulCallID; + ULONG ulRelatedCallID; + ULONG ulCallParamFlags; + ULONG ulCallStates; + + ULONG ulMonitorDigitModes; + ULONG ulMonitorMediaModes; + LINE_DIAL_PARAMS DialParams; + + ULONG ulOrigin; + ULONG ulReason; + ULONG ulCompletionID; + ULONG ulNumOwners; + ULONG ulNumMonitors; + + ULONG ulCountryCode; + ULONG ulTrunk; + + ULONG ulCallerIDFlags; + ULONG ulCallerIDSize; + ULONG ulCallerIDOffset; + ULONG ulCallerIDNameSize; + ULONG ulCallerIDNameOffset; + + ULONG ulCalledIDFlags; + ULONG ulCalledIDSize; + ULONG ulCalledIDOffset; + ULONG ulCalledIDNameSize; + ULONG ulCalledIDNameOffset; + + ULONG ulConnectedIDFlags; + ULONG ulConnectedIDSize; + ULONG ulConnectedIDOffset; + ULONG ulConnectedIDNameSize; + ULONG ulConnectedIDNameOffset; + + ULONG ulRedirectionIDFlags; + ULONG ulRedirectionIDSize; + ULONG ulRedirectionIDOffset; + ULONG ulRedirectionIDNameSize; + ULONG ulRedirectionIDNameOffset; + + ULONG ulRedirectingIDFlags; + ULONG ulRedirectingIDSize; + ULONG ulRedirectingIDOffset; + ULONG ulRedirectingIDNameSize; + ULONG ulRedirectingIDNameOffset; + + ULONG ulAppNameSize; + ULONG ulAppNameOffset; + + ULONG ulDisplayableAddressSize; + ULONG ulDisplayableAddressOffset; + + ULONG ulCalledPartySize; + ULONG ulCalledPartyOffset; + + ULONG ulCommentSize; + ULONG ulCommentOffset; + + ULONG ulDisplaySize; + ULONG ulDisplayOffset; + + ULONG ulUserUserInfoSize; + ULONG ulUserUserInfoOffset; + + ULONG ulHighLevelCompSize; + ULONG ulHighLevelCompOffset; + + ULONG ulLowLevelCompSize; + ULONG ulLowLevelCompOffset; + + ULONG ulChargingInfoSize; + ULONG ulChargingInfoOffset; + + ULONG ulTerminalModesSize; + ULONG ulTerminalModesOffset; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + } LINE_CALL_INFO, *PLINE_CALL_INFO; + + typedef struct _LINE_DIAL_PARAMS + { + ULONG ulDialPause; + ULONG ulDialSpeed; + ULONG ulDigitDuration; + ULONG ulWaitForDialtone; + + } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetCallInfo") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n", + Request->hdCall + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineCallInfo.ulNeededSize = + Request->LineCallInfo.ulUsedSize = sizeof(Request->LineCallInfo); +#endif + + /* + // We don't expect user user info. + */ + ASSERT(Request->LineCallInfo.ulUserUserInfoSize == 0); + + /* + // The link has all the call information we need to return. + */ + Request->LineCallInfo.hLine = (ULONG) Link; + Request->LineCallInfo.ulLineDeviceID = GET_DEVICEID_FROM_LINK(Adapter, Link); + Request->LineCallInfo.ulAddressID = HTDSU_TAPI_ADDRESSID; + + Request->LineCallInfo.ulBearerMode = LINEBEARERMODE_DATA; + Request->LineCallInfo.ulRate = Link->LinkSpeed; + Request->LineCallInfo.ulMediaMode = Link->MediaModesMask; + + Request->LineCallInfo.ulCallParamFlags = LINECALLPARAMFLAGS_IDLE; + Request->LineCallInfo.ulCallStates = Link->CallStatesMask; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetCallStatus( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_CALL_STATUS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns detailed information about the specified call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_CALL_STATUS + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + OUT LINE_CALL_STATUS LineCallStatus; + + } NDIS_TAPI_GET_CALL_STATUS, *PNDIS_TAPI_GET_CALL_STATUS; + + typedef struct _LINE_CALL_STATUS + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulCallState; + ULONG ulCallStateMode; + ULONG ulCallPrivilege; + ULONG ulCallFeatures; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + } LINE_CALL_STATUS, *PLINE_CALL_STATUS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetCallStatus") + + /* + // Holds the status result returned this function. + */ + NDIS_STATUS Status; + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n", + Request->hdCall + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineCallStatus.ulNeededSize = + Request->LineCallStatus.ulUsedSize = sizeof(Request->LineCallStatus); +#endif + + /* + // The link has all the call information. + */ + Request->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER; + Request->LineCallStatus.ulCallState = Link->CallState; + + /* + // Tag CallStateMode with appropriate value for the current CallState. + */ + if (Link->CallState == LINECALLSTATE_DIALTONE) + { + Request->LineCallStatus.ulCallStateMode = LINEDIALTONEMODE_NORMAL; + } + else if (Link->CallState == LINECALLSTATE_BUSY) + { + Request->LineCallStatus.ulCallStateMode = LINEBUSYMODE_STATION; + } + else if (Link->CallState == LINECALLSTATE_DISCONNECTED) + { + /* + // We need to query/save the line status to find out what happened. + */ + if (CardStatusNoAnswer(Adapter, Link->CardLine)) + { + Request->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_NOANSWER; + } + else if (CardStatusNoDialTone(Adapter, Link->CardLine)) + { + Request->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_BUSY; + } + else + { + Request->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_UNKNOWN; + } + } + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetDevCaps( + PHTDSU_ADAPTER Adapter, + PNDIS_TAPI_GET_DEV_CAPS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request queries a specified line device to determine its telephony + capabilities. The returned information is valid for all addresses on the + line device. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_DEV_CAPS + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulExtVersion; + OUT LINE_DEV_CAPS LineDevCaps; + + } NDIS_TAPI_GET_DEV_CAPS, *PNDIS_TAPI_GET_DEV_CAPS; + + typedef struct _LINE_DEV_CAPS + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulProviderInfoSize; + ULONG ulProviderInfoOffset; + + ULONG ulSwitchInfoSize; + ULONG ulSwitchInfoOffset; + + ULONG ulPermanentLineID; + ULONG ulLineNameSize; + ULONG ulLineNameOffset; + ULONG ulStringFormat; + + ULONG ulAddressModes; + ULONG ulNumAddresses; + ULONG ulBearerModes; + ULONG ulMaxRate; + ULONG ulMediaModes; + + ULONG ulGenerateToneModes; + ULONG ulGenerateToneMaxNumFreq; + ULONG ulGenerateDigitModes; + ULONG ulMonitorToneMaxNumFreq; + ULONG ulMonitorToneMaxNumEntries; + ULONG ulMonitorDigitModes; + ULONG ulGatherDigitsMinTimeout; + ULONG ulGatherDigitsMaxTimeout; + + ULONG ulMedCtlDigitMaxListSize; + ULONG ulMedCtlMediaMaxListSize; + ULONG ulMedCtlToneMaxListSize; + ULONG ulMedCtlCallStateMaxListSize; + + ULONG ulDevCapFlags; + ULONG ulMaxNumActiveCalls; + ULONG ulAnswerMode; + ULONG ulRingModes; + ULONG ulLineStates; + + ULONG ulUUIAcceptSize; + ULONG ulUUIAnswerSize; + ULONG ulUUIMakeCallSize; + ULONG ulUUIDropSize; + ULONG ulUUISendUserUserInfoSize; + ULONG ulUUICallInfoSize; + + LINE_DIAL_PARAMS MinDialParams; + LINE_DIAL_PARAMS MaxDialParams; + LINE_DIAL_PARAMS DefaultDialParams; + + ULONG ulNumTerminals; + ULONG ulTerminalCapsSize; + ULONG ulTerminalCapsOffset; + ULONG ulTerminalTextEntrySize; + ULONG ulTerminalTextSize; + ULONG ulTerminalTextOffset; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + } LINE_DEV_CAPS, *PLINE_DEV_CAPS; + + typedef struct _LINE_DIAL_PARAMS + { + ULONG ulDialPause; + ULONG ulDialSpeed; + ULONG ulDigitDuration; + ULONG ulWaitForDialtone; + + } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetDevCaps") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulExtVersion=%Xh\n" + "LineDevCaps=%Xh\n", + Request->ulDeviceID, + Request->ulExtVersion, + &Request->LineDevCaps + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineDevCaps.ulNeededSize = + Request->LineDevCaps.ulUsedSize = sizeof(Request->LineDevCaps); +#endif + + /* + // The driver numbers lines sequentially from 1, so this will always + // be the same number. + */ + Request->LineDevCaps.ulPermanentLineID = Link->CardLine; + + /* + // RASTAPI requires the "MediaType\0DeviceName" be placed in the + // ProviderInfo field at the end of this structure. + */ + Request->LineDevCaps.ulNeededSize += Adapter->ProviderInfoSize; + if (Request->LineDevCaps.ulNeededSize <= Request->LineDevCaps.ulTotalSize) + { + Request->LineDevCaps.ulProviderInfoSize = Adapter->ProviderInfoSize; + Request->LineDevCaps.ulProviderInfoOffset = sizeof(Request->LineDevCaps); + NdisMoveMemory((PUCHAR) &Request->LineDevCaps + + Request->LineDevCaps.ulProviderInfoOffset, + Adapter->ProviderInfo, + Adapter->ProviderInfoSize + ); + Request->LineDevCaps.ulUsedSize += Adapter->ProviderInfoSize; + } + Request->LineDevCaps.ulStringFormat = STRINGFORMAT_ASCII; + + /* + // This device is a switched 56kb line for digital data only. + */ + Request->LineDevCaps.ulAddressModes = LINEADDRESSMODE_ADDRESSID | + LINEADDRESSMODE_DIALABLEADDR; + Request->LineDevCaps.ulNumAddresses = 1; + Request->LineDevCaps.ulBearerModes = LINEBEARERMODE_DATA; + Request->LineDevCaps.ulMaxRate = Link->LinkSpeed; + Request->LineDevCaps.ulMediaModes = Link->MediaModesCaps; + + /* + // Each line on the DSU only supports a single call. + */ + Request->LineDevCaps.ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP; + Request->LineDevCaps.ulMaxNumActiveCalls = 1; + Request->LineDevCaps.ulAnswerMode = LINEANSWERMODE_DROP; + Request->LineDevCaps.ulRingModes = 1; + Request->LineDevCaps.ulLineStates = Link->DevStatesCaps; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetExtensionID( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_EXTENSION_ID Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns the extension ID that the miniport supports for the + indicated line device. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_EXTENSION_ID + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + OUT LINE_EXTENSION_ID LineExtensionID; + + } NDIS_TAPI_GET_EXTENSION_ID, *PNDIS_TAPI_GET_EXTENSION_ID; + + typedef struct _LINE_EXTENSION_ID + { + ULONG ulExtensionID0; + ULONG ulExtensionID1; + ULONG ulExtensionID2; + ULONG ulExtensionID3; + + } LINE_EXTENSION_ID, *PLINE_EXTENSION_ID; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetExtensionID") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n", + Request->ulDeviceID + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + + /* + // This driver does not support any extensions, so we return zeros. + */ + Request->LineExtensionID.ulExtensionID0 = 0; + Request->LineExtensionID.ulExtensionID1 = 0; + Request->LineExtensionID.ulExtensionID2 = 0; + Request->LineExtensionID.ulExtensionID3 = 0; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiGetLineDevStatus( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_GET_LINE_DEV_STATUS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request queries the specified open line device for its current status. + The information returned is global to all addresses on the line. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_GET_LINE_DEV_STATUS + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + OUT LINE_DEV_STATUS LineDevStatus; + + } NDIS_TAPI_GET_LINE_DEV_STATUS, *PNDIS_TAPI_GET_LINE_DEV_STATUS; + + typedef struct _LINE_DEV_STATUS + { + ULONG ulTotalSize; + ULONG ulNeededSize; + ULONG ulUsedSize; + + ULONG ulNumOpens; + ULONG ulOpenMediaModes; + ULONG ulNumActiveCalls; + ULONG ulNumOnHoldCalls; + ULONG ulNumOnHoldPendCalls; + ULONG ulLineFeatures; + ULONG ulNumCallCompletions; + ULONG ulRingMode; + ULONG ulSignalLevel; + ULONG ulBatteryLevel; + ULONG ulRoamMode; + + ULONG ulDevStatusFlags; + + ULONG ulTerminalModesSize; + ULONG ulTerminalModesOffset; + + ULONG ulDevSpecificSize; + ULONG ulDevSpecificOffset; + + } LINE_DEV_STATUS, *PLINE_DEV_STATUS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALLINEHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiGetLineDevStatus") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n", + Request->hdLine + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + +#ifndef NDISTAPI_BUG_FIXED + Request->LineDevStatus.ulNeededSize = + Request->LineDevStatus.ulUsedSize = sizeof(Request->LineDevStatus); +#endif + + /* + // Return the current line status information. + */ + Request->LineDevStatus.ulNumActiveCalls; + Link->CallState == LINECALLSTATE_IDLE ? 0 : 1; + Request->LineDevStatus.ulLineFeatures; + Link->CallState == LINECALLSTATE_IDLE ? + LINEFEATURE_MAKECALL : 0; + Request->LineDevStatus.ulRingMode = + Link->DevState == LINEDEVSTATE_RINGING ? 1: 0; + Request->LineDevStatus.ulDevStatusFlags = + Link->DevState == LINEDEVSTATE_CONNECTED ? + LINEDEVSTATUSFLAGS_INSERVICE | LINEDEVSTATUSFLAGS_CONNECTED : 0; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiMakeCall( + PHTDSU_ADAPTER Adapter, + PNDIS_TAPI_MAKE_CALL Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request places a call on the specified line to the specified + destination address. Optionally, call parameters can be specified if + anything but default call setup parameters are requested. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_MAKE_CALL + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN HTAPI_CALL htCall; + OUT HDRV_CALL hdCall; + IN ULONG ulDestAddressSize; + IN ULONG ulDestAddressOffset; + IN BOOLEAN bUseDefaultLineCallParams; + IN LINE_CALL_PARAMS LineCallParams; + + } NDIS_TAPI_MAKE_CALL, *PNDIS_TAPI_MAKE_CALL; + + typedef struct _LINE_CALL_PARAMS // Defaults: + { + ULONG ulTotalSize; // --------- + + ULONG ulBearerMode; // voice + ULONG ulMinRate; // (3.1kHz) + ULONG ulMaxRate; // (3.1kHz) + ULONG ulMediaMode; // interactiveVoice + + ULONG ulCallParamFlags; // 0 + ULONG ulAddressMode; // addressID + ULONG ulAddressID; // (any available) + + LINE_DIAL_PARAMS DialParams; // (0, 0, 0, 0) + + ULONG ulOrigAddressSize; // 0 + ULONG ulOrigAddressOffset; + ULONG ulDisplayableAddressSize; + ULONG ulDisplayableAddressOffset; + + ULONG ulCalledPartySize; // 0 + ULONG ulCalledPartyOffset; + + ULONG ulCommentSize; // 0 + ULONG ulCommentOffset; + + ULONG ulUserUserInfoSize; // 0 + ULONG ulUserUserInfoOffset; + + ULONG ulHighLevelCompSize; // 0 + ULONG ulHighLevelCompOffset; + + ULONG ulLowLevelCompSize; // 0 + ULONG ulLowLevelCompOffset; + + ULONG ulDevSpecificSize; // 0 + ULONG ulDevSpecificOffset; + + } LINE_CALL_PARAMS, *PLINE_CALL_PARAMS; + + typedef struct _LINE_DIAL_PARAMS + { + ULONG ulDialPause; + ULONG ulDialSpeed; + ULONG ulDigitDuration; + ULONG ulWaitForDialtone; + + } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS; + +Return Values: + + NDIS_STATUS_TAPI_ADDRESSBLOCKED + NDIS_STATUS_TAPI_BEARERMODEUNAVAIL + NDIS_STATUS_TAPI_CALLUNAVAIL + NDIS_STATUS_TAPI_DIALBILLING + NDIS_STATUS_TAPI_DIALQUIET + NDIS_STATUS_TAPI_DIALDIALTONE + NDIS_STATUS_TAPI_DIALPROMPT + NDIS_STATUS_TAPI_INUSE + NDIS_STATUS_TAPI_INVALADDRESSMODE + NDIS_STATUS_TAPI_INVALBEARERMODE + NDIS_STATUS_TAPI_INVALMEDIAMODE + NDIS_STATUS_TAPI_INVALLINESTATE + NDIS_STATUS_TAPI_INVALRATE + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_INVALADDRESS + NDIS_STATUS_TAPI_INVALADDRESSID + NDIS_STATUS_TAPI_INVALCALLPARAMS + NDIS_STATUS_RESOURCES + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_RESOURCEUNAVAIL + NDIS_STATUS_TAPI_RATEUNAVAIL + NDIS_STATUS_TAPI_USERUSERINFOTOOBIG + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiMakeCall") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "htCall=%Xh\n" + "ulDestAddressSize=%d\n" + "ulDestAddressOffset=%Xh\n" + "bUseDefaultLineCallParams=%d\n" + "LineCallParams=%Xh\n", + Request->hdLine, + Request->htCall, + Request->ulDestAddressSize, + Request->ulDestAddressOffset, + Request->bUseDefaultLineCallParams, + Request->LineCallParams + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // We should be idle when this call comes down, but if we're out of + // state for seom reason, don't let this go any further. + */ + if (Link->CallState != LINECALLSTATE_IDLE) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INUSE\n")); + return (NDIS_STATUS_TAPI_INUSE); + } + + /* + // Currently, the defaultCallParams feature is not used by RASTAPI. + // Normally, you would save the default params passed into + // OID_TAPI_SET_CALL_PARAM and apply them here. + */ + ASSERT(Request->bUseDefaultLineCallParams == FALSE); + + /* + // We don't expect user user info. + */ + ASSERT(Request->LineCallParams.ulUserUserInfoSize == 0); + + /* + // We gotta make sure the line is in the right state before attempt. + */ + if (Link->LineMode != HTDSU_LINEMODE_DIALUP || + CardStatusNoSignal(Adapter, Link->CardLine) || + CardStatusOutOfService(Adapter, Link->CardLine) || + CardStatusCarrierDetect(Adapter, Link->CardLine)) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_OPERATIONUNAVAIL\n")); + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); + } + + /* + // Remember the TAPI call connection handle. + */ + Link->htCall = Request->htCall; + + /* + // Since we only allow one call per line, we use the same handle. + */ + Request->hdCall = (HDRV_CALL)Link; + + /* + // Dial the number if it's available, otherwise it may come via + // OID_TAPI_DIAL. Be aware the the phone number format may be + // different for other applications. I'm assuming an ASCII digits + // string. + */ + if (Request->ulDestAddressSize) + { + PUCHAR DialString = ((PUCHAR)Request) + Request->ulDestAddressOffset; + + DBG_NOTICE(Adapter,("Dialing: '%s'\n",DialString)); + + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DIALTONE, LINEDIALTONEMODE_NORMAL); + CardDialNumber(Adapter, + Link->CardLine, + DialString, + Request->ulDestAddressSize + ); + /* + // We should see a HTDSU_NO_DIAL_TONE within 5 seconds if the + // call will not go through. + */ + HtTapiCallStateHandler(Adapter, Link, LINECALLSTATE_DIALING, 0); + NdisMSetTimer(&Link->CallTimer, HTDSU_NO_DIALTONE_TIMEOUT); + } + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiNegotiateExtVersion( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_NEGOTIATE_EXT_VERSION Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request returns the highest extension version number the service + provider is willing to operate under for this device given the range of + possible extension versions. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_NEGOTIATE_EXT_VERSION + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN ULONG ulLowVersion; + IN ULONG ulHighVersion; + OUT ULONG ulExtVersion; + } NDIS_TAPI_NEGOTIATE_EXT_VERSION, *PNDIS_TAPI_NEGOTIATE_EXT_VERSION; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiNegotiateExtVersion") + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "ulLowVersion=%Xh\n" + "ulHighVersion=%Xh\n", + Request->ulDeviceID, + Request->ulLowVersion, + Request->ulHighVersion + )); + /* + // Make sure the miniport's version number is within the allowable + // range requested by the caller. We ignore the ulDeviceID because + // the version information applies to all devices on this adapter. + */ + if (HTDSU_TAPI_EXT_VERSION < Request->ulLowVersion || + HTDSU_TAPI_EXT_VERSION > Request->ulHighVersion) + { + DBG_WARNING(Adapter, ("NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION\n")); + return (NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION); + } + + /* + // Looks like we're compatible, so tell the caller what we expect. + */ + Request->ulExtVersion = HTDSU_TAPI_EXT_VERSION; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiOpen( + PHTDSU_ADAPTER Adapter, + PNDIS_TAPI_OPEN Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This function opens the line device whose device ID is given, returning + the miniport’s handle for the device. The miniport must retain the + Connection Wrapper's handle for the device for use in subsequent calls to + the LINE_EVENT callback procedure. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request - A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_OPEN + { + IN ULONG ulRequestID; + IN ULONG ulDeviceID; + IN HTAPI_LINE htLine; + OUT HDRV_LINE hdLine; + + } NDIS_TAPI_OPEN, *PNDIS_TAPI_OPEN; + +Return Values: + + NDIS_STATUS_PENDING + NDIS_STATUS_TAPI_ALLOCATED + NDIS_STATUS_TAPI_NODRIVER + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiOpen") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceID=%d\n" + "htLine=%Xh\n", + Request->ulDeviceID, + Request->htLine + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_DEVICEID(Adapter, Request->ulDeviceID); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n")); + return (NDIS_STATUS_TAPI_NODRIVER); + } + + /* + // Make sure the requested line device is not already in use. + */ + Link = LinkAllocate(Adapter, Request->htLine, + (USHORT) (Link->CardLine-HTDSU_CMD_LINE1)); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_ALLOCATED\n")); + return (NDIS_STATUS_TAPI_ALLOCATED); + } + + /* + // Tell the wrapper the line context and set the line/call state. + */ + Request->hdLine = (HDRV_LINE)Link; + HtTapiLineDevStateHandler(Adapter, Link, LINEDEVSTATE_OPEN); + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiProviderInitialize( + PHTDSU_ADAPTER Adapter, + PNDIS_TAPI_PROVIDER_INITIALIZE Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request initializes the TAPI portion of the miniport. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + 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; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_RESOURCEUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiProviderInitialize") + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("ulDeviceIDBase=%d\n", + Request->ulDeviceIDBase + )); + /* + // Save the device ID base value. + */ + Adapter->DeviceIdBase = Request->ulDeviceIDBase; + + /* + // Return the number of DSU lines. Assumes the miniport has initialized, + // self-tested, etc. + */ + Request->ulNumLineDevs = Adapter->NumLineDevs; + + /* + // 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)Adapter; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiAccept( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_ACCEPT Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request accepts the specified offered call. It may optionally send + the specified user-to-user information to the calling party. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_ACCEPT + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulUserUserInfoSize; + IN UCHAR UserUserInfo[1]; + + } NDIS_TAPI_ACCEPT, *PNDIS_TAPI_ACCEPT; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiAccept") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulUserUserInfoSize=%d\n" + "UserUserInfo=%Xh\n", + Request->hdCall, + Request->ulUserUserInfoSize, + Request->UserUserInfo + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // We don't expect user user info. + */ + ASSERT(Request->ulUserUserInfoSize == 0); + + /* + // Note that the call has been accepted, we should see and answer soon. + */ + HtTapiCallStateHandler(Adapter, Link, LINECALLSTATE_ACCEPTED, 0); + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiAnswer( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_ANSWER Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request answers the specified offering call. It may optionally send + the specified user-to-user information to the calling party. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_ANSWER + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulUserUserInfoSize; + IN UCHAR UserUserInfo[1]; + + } NDIS_TAPI_ANSWER, *PNDIS_TAPI_ANSWER; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiAnswer") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulUserUserInfoSize=%d\n" + "UserUserInfo=%Xh\n", + Request->hdCall, + Request->ulUserUserInfoSize, + Request->UserUserInfo + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // We don't expect user user info. + */ + ASSERT(Request->ulUserUserInfoSize == 0); + + /* + // Tell the adapter to pick up the line, and wait for a connect interrupt. + */ + CardLineAnswer(Adapter, Link->CardLine); + NdisMSetTimer(&Link->CallTimer, HTDSU_NO_CONNECT_TIMEOUT); + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiClose( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_CLOSE Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request closes the specified open line device after completing or + aborting all outstanding calls and asynchronous requests on the device. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_CLOSE + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + + } NDIS_TAPI_CLOSE, *PNDIS_TAPI_CLOSE; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_PENDING + NDIS_STATUS_TAPI_INVALLINEHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiClose") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // The results of this call. + */ + NDIS_STATUS Status; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n", + Request->hdLine + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // Mark the link as closing, so no more packets will be accepted, + // and when the last transmit is complete, the link will be closed. + */ + if (Link->NumTxQueued) + { + Status = NDIS_STATUS_PENDING; + Link->Closing = TRUE; + } + else + { + HtTapiLineDevStateHandler(Adapter, Link, LINEDEVSTATE_CLOSE); + LinkRelease(Link); + Status = NDIS_STATUS_SUCCESS; + } + + DBG_LEAVE(Adapter); + + return (Status); +} + + +NDIS_STATUS +HtTapiCloseCall( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_CLOSE_CALL Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request deallocates the call after completing or aborting all + outstanding asynchronous requests on the call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_CLOSE_CALL + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + + } NDIS_TAPI_CLOSE_CALL, *PNDIS_TAPI_CLOSE_CALL; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiCloseCall") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // The results of this call. + */ + NDIS_STATUS Status; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n", + Request->hdCall + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // Mark the link as closing, so no more packets will be accepted, + // and when the last transmit is complete, the link will be closed. + */ + if (Link->NumTxQueued) + { + Link->CallClosing = TRUE; + Status = NDIS_STATUS_PENDING; + } + else + { + HtTapiCallStateHandler(Adapter, Link, LINECALLSTATE_IDLE, 0); + Status = NDIS_STATUS_SUCCESS; + } + + DBG_LEAVE(Adapter); + + return (Status); +} + + +NDIS_STATUS +HtTapiConditionalMediaDetection( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request is invoked by the Connection Wrapper whenever a client + application uses LINEMAPPER as the dwDeviceID in the lineOpen function + to request that lines be scanned to find one that supports the desired + media mode(s) and call parameters. The Connection Wrapper scans based on + the union of the desired media modes and the other media modes currently + being monitored on the line, to give the miniport the opportunity to + indicate if it cannot simultaneously monitor for all of the requested + media modes. If the miniport can monitor for the indicated set of media + modes AND support the capabilities indicated in CallParams, it replies + with a “success” inidication. It leaves the active media monitoring modes + for the line unchanged. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulMediaModes; + IN LINE_CALL_PARAMS LineCallParams; + + } NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION, *PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION; + + typedef struct _LINE_CALL_PARAMS // Defaults: + { + ULONG ulTotalSize; // --------- + + ULONG ulBearerMode; // voice + ULONG ulMinRate; // (3.1kHz) + ULONG ulMaxRate; // (3.1kHz) + ULONG ulMediaMode; // interactiveVoice + + ULONG ulCallParamFlags; // 0 + ULONG ulAddressMode; // addressID + ULONG ulAddressID; // (any available) + + LINE_DIAL_PARAMS DialParams; // (0, 0, 0, 0) + + ULONG ulOrigAddressSize; // 0 + ULONG ulOrigAddressOffset; + ULONG ulDisplayableAddressSize; + ULONG ulDisplayableAddressOffset; + + ULONG ulCalledPartySize; // 0 + ULONG ulCalledPartyOffset; + + ULONG ulCommentSize; // 0 + ULONG ulCommentOffset; + + ULONG ulUserUserInfoSize; // 0 + ULONG ulUserUserInfoOffset; + + ULONG ulHighLevelCompSize; // 0 + ULONG ulHighLevelCompOffset; + + ULONG ulLowLevelCompSize; // 0 + ULONG ulLowLevelCompOffset; + + ULONG ulDevSpecificSize; // 0 + ULONG ulDevSpecificOffset; + + } LINE_CALL_PARAMS, *PLINE_CALL_PARAMS; + + typedef struct _LINE_DIAL_PARAMS + { + ULONG ulDialPause; + ULONG ulDialSpeed; + ULONG ulDigitDuration; + ULONG ulWaitForDialtone; + + } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALLINEHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiConditionalMediaDetection") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulMediaModes=%Xh\n" + "LineCallParams=%Xh\n", + Request->hdLine, + Request->ulMediaModes, + &Request->LineCallParams + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // We don't expect user user info. + */ + ASSERT(Request->LineCallParams.ulUserUserInfoSize == 0); + + /* + // I pretty much ignore all this since this adapter only supports + // digital data. If your adapter supports different medias or + // voice and data, you will need to save the necessary paramters. + */ + Link->MediaModesMask = Request->ulMediaModes; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiDial( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_DIAL Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request dials the specified dialable number on the specified call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_DIAL + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulDestAddressSize; + IN CHAR szDestAddress[1]; + + } NDIS_TAPI_DIAL, *PNDIS_TAPI_DIAL; + +Return Values: + + NDIS_STATUS_TAPI_INVALCALLHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiDial") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulDestAddressSize=%d\n" + "szDestAddress=%Xh\n", + Request->hdCall, + Request->ulDestAddressSize, + Request->szDestAddress + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // RASTAPI only places calls through the MAKE_CALL interface. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiDrop( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_DROP Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request drops or disconnects the specified call. User-to-user + information can optionally be transmitted as part of the call disconnect. + This function can be called by the application at any time. When + OID_TAPI_DROP returns with success, the call should be idle. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_DROP + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulUserUserInfoSize; + IN UCHAR UserUserInfo[1]; + + } NDIS_TAPI_DROP, *PNDIS_TAPI_DROP; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiDrop") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulUserUserInfoSize=%d\n" + "UserUserInfo=%Xh\n", + Request->hdCall, + Request->ulUserUserInfoSize, + Request->UserUserInfo + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // We don't expect user user info. + */ + ASSERT(Request->ulUserUserInfoSize == 0); + + /* + // The user wants to disconnect, so make it happen cappen. + */ + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NORMAL); + + /* + // Under some conditions, we may not get a CLOSE_CALL, so the + // line would be left unusable if we don't timeout and force a + // close call condition. + */ + NdisMSetTimer(&Link->CallTimer, HTDSU_NO_CLOSECALL_TIMEOUT); + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiProviderShutdown( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_PROVIDER_SHUTDOWN Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request shuts down the miniport. The miniport should terminate any + activities it has in progress. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_PROVIDER_SHUTDOWN + { + IN ULONG ulRequestID; + + } NDIS_TAPI_PROVIDER_SHUTDOWN, *PNDIS_TAPI_PROVIDER_SHUTDOWN; + +Return Values: + + NDIS_STATUS_SUCCESS + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiProviderShutdown") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + /* + // Used to interate over the links. + */ + USHORT LinkIndex; + + DBG_ENTER(Adapter); + + /* + // Hangup all of the lines. + */ + for (LinkIndex = 0; LinkIndex < Adapter->NumLineDevs; LinkIndex++) + { + Link = GET_LINK_FROM_LINKINDEX(Adapter, LinkIndex); + + if (Link->Adapter) + { + /* + // Force the call to drop + */ + if (Link->CallState != LINECALLSTATE_IDLE) + { + CardLineDisconnect(Adapter, Link->CardLine); + } + + /* + // Indicate LINE_DOWN status and release the link structure. + */ + LinkLineDown(Link); + LinkRelease(Link); + } + } + Adapter->NumOpens = 0; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiSecureCall( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SECURE_CALL Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request secures the call from any interruptions or interference that + may affect the call’s media stream. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SECURE_CALL + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + + } NDIS_TAPI_SECURE_CALL, *PNDIS_TAPI_SECURE_CALL; + +Return Values: + + NDIS_STATUS_TAPI_INVALCALLHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSecureCall") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n", + Request->hdCall + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // RASTAPI has no support for this feature yet. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiSelectExtVersion( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SELECT_EXT_VERSION Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request selects the indicated extension version for the indicated + line device. Subsequent requests operate according to that extension + version. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SELECT_EXT_VERSION + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulExtVersion; + + } NDIS_TAPI_SELECT_EXT_VERSION, *PNDIS_TAPI_SELECT_EXT_VERSION; + +Return Values: + + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSelectExtVersion") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulExtVersion=%Xh\n", + Request->hdLine, + Request->ulExtVersion + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // NDISTAPI does not support this feature yet. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiSendUserUserInfo( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SEND_USER_USER_INFO Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request sends user-to-user information to the remote party on the + specified call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SEND_USER_USER_INFO + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulUserUserInfoSize; + IN UCHAR UserUserInfo[1]; + + } NDIS_TAPI_SEND_USER_USER_INFO, *PNDIS_TAPI_SEND_USER_USER_INFO; + +Return Values: + + NDIS_STATUS_TAPI_INVALCALLHANDLE + NDIS_STATUS_TAPI_OPERATIONUNAVAIL + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSendUserUserInfo") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulUserUserInfoSize=%d\n" + "UserUserInfo=%Xh\n", + Request->hdCall, + Request->ulUserUserInfoSize, + Request->UserUserInfo + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // We don't expect user user info. + */ + ASSERT(Request->ulUserUserInfoSize == 0); + + /* + // If your adapter has support for this feature, or uses it like + // ISDN, you need to find all occurances of ulUserUserInfoSize. + // It is included in a number of service provider calls. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiSetAppSpecific( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_APP_SPECIFIC Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request sets the application-specific field of the specified call’s + LINECALLINFO structure. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_APP_SPECIFIC + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulAppSpecific; + + } NDIS_TAPI_SET_APP_SPECIFIC, *PNDIS_TAPI_SET_APP_SPECIFIC; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetAppSpecific") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulAppSpecific=%d\n", + Request->hdCall, + Request->ulAppSpecific + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // You can do what ever you want here, so long as the application + // agrees with you. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_TAPI_OPERATIONUNAVAIL); +} + + +NDIS_STATUS +HtTapiSetCallParams( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_CALL_PARAMS Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request sets certain call parameters for an existing call. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_CALL_PARAMS + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulBearerMode; + IN ULONG ulMinRate; + IN ULONG ulMaxRate; + IN BOOLEAN bSetLineDialParams; + IN LINE_DIAL_PARAMS LineDialParams; + + } NDIS_TAPI_SET_CALL_PARAMS, *PNDIS_TAPI_SET_CALL_PARAMS; + + typedef struct _LINE_DIAL_PARAMS + { + ULONG ulDialPause; + ULONG ulDialSpeed; + ULONG ulDigitDuration; + ULONG ulWaitForDialtone; + + } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetCallParams") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulBearerMode=%Xh\n", + "ulMinRate=%d\n", + "ulMaxRate=%d\n", + "bSetLineDialParams=%d\n", + "LineDialParams=%Xh\n", + Request->hdCall, + Request->ulBearerMode, + Request->ulMinRate, + Request->ulMaxRate, + Request->bSetLineDialParams, + Request->LineDialParams + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // RASTAPI only places calls through the MAKE_CALL interface. + // So there's nothing to do here for the time being. + */ + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiSetDefaultMediaDetection( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request informs the miniport of the new set of media modes to detect + for the indicated line (replacing any previous set). + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulMediaModes; + + } NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION, *PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALLINEHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetDefaultMediaDetection") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulMediaModes=%Xh\n", + Request->hdLine, + Request->ulMediaModes + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // Set the media modes mask and make sure the adapter is ready to + // accept incoming calls. If you can detect different medias, you + // will need to notify the approriate interface for the media detected. + */ + Link->MediaModesMask = Request->ulMediaModes; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiSetMediaMode( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_MEDIA_MODE Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request changes a call’s media mode as stored in the call’s + LINE_CALL_INFO structure. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_MEDIA_MODE + { + IN ULONG ulRequestID; + IN HDRV_CALL hdCall; + IN ULONG ulMediaMode; + + } NDIS_TAPI_SET_MEDIA_MODE, *PNDIS_TAPI_SET_MEDIA_MODE; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_TAPI_INVALCALLHANDLE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetMediaMode") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdCall=%Xh\n" + "ulMediaMode=%Xh\n", + Request->hdCall, + Request->ulMediaMode + )); + /* + // This request must be associated with a call. + */ + Link = GET_LINK_FROM_HDCALL(Adapter, Request->hdCall); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALCALLHANDLE); + } + + /* + // If you can detect different medias, you will need to setup to use + // the selected media here. + */ + Link->MediaModesMask = Request->ulMediaMode; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +NDIS_STATUS +HtTapiSetStatusMessages( + IN PHTDSU_ADAPTER Adapter, + IN PNDIS_TAPI_SET_STATUS_MESSAGES Request + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This request enables the Connection Wrapper to specify which notification + messages the miniport should generate for events related to status changes + for the specified line or any of its addresses. By default, address and + line status reporting is initially disabled for a line. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Request _ A pointer to the NDIS_TAPI request structure for this call. + + typedef struct _NDIS_TAPI_SET_STATUS_MESSAGES + { + IN ULONG ulRequestID; + IN HDRV_LINE hdLine; + IN ULONG ulLineStates; + IN ULONG ulAddressStates; + + } NDIS_TAPI_SET_STATUS_MESSAGES, *PNDIS_TAPI_SET_STATUS_MESSAGES; + +Return Values: + + NDIS_STATUS_SUCCESS + NDIS_STATUS_TAPI_INVALLINEHANDLE + NDIS_STATUS_TAPI_INVALLINESTATE + NDIS_STATUS_TAPI_INVALADDRESSSTATE + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiSetStatusMessages") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("hdLine=%Xh\n" + "ulLineStates=%Xh\n" + "ulAddressStates=%Xh\n", + Request->hdLine, + Request->ulLineStates, + Request->ulAddressStates + )); + /* + // This request must be associated with a line device. + */ + Link = GET_LINK_FROM_HDLINE(Adapter, Request->hdLine); + if (Link == NULL) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n")); + return (NDIS_STATUS_TAPI_INVALLINEHANDLE); + } + + /* + // Make sure the line settings are all within the supported list. + */ + if (Request->ulLineStates & ~Link->DevStatesCaps) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALLINESTATE\n")); + return (NDIS_STATUS_TAPI_INVALLINESTATE); + } + + /* + // Make sure the address settings are all within the supported list. + */ + if (Request->ulAddressStates & ~Link->AddressStatesCaps) + { + DBG_WARNING(Adapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSSTATE\n")); + return (NDIS_STATUS_TAPI_INVALADDRESSSTATE); + } + + /* + // Save the new event notification masks so we will only indicate the + // appropriate events. + */ + Link->DevStatesMask = Request->ulLineStates; + Link->AddressStatesMask = Request->ulAddressStates; + + DBG_LEAVE(Adapter); + + return (NDIS_STATUS_SUCCESS); +} + + +VOID +HtTapiCallStateHandler( + IN PHTDSU_ADAPTER Adapter, + IN PHTDSU_LINK Link, + IN ULONG CallState, + IN ULONG StateParam + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This routine will indicate the given LINECALLSTATE to the Connection + wrapper if the event has been enabled by the wrapper. Otherwise the state + information is saved, but no indication is made. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Link _ A pointer to our link information structure for the selected + line device. + + CallState _ The LINECALLSTATE event to be posted to TAPI/WAN. + + StateParam _ This value depends on the event being posted, and some + events will pass in zero if they don't use this parameter. + +Return Values: + + None + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiCallStateHandler") + + /* + // The event structure passed to the connection wrapper. + */ + NDIS_TAPI_EVENT CallEvent; + + /* + // Flag tells whether call time-out routine was cancelled. + */ + BOOLEAN TimerCancelled; + + DBG_ENTER(Adapter); + DBG_FILTER(Adapter, DBG_PARAMS_ON, + ("OldState=%Xh " + "NewState=%Xh\n", + Link->CallState, + CallState + )); + /* + // Cancel any call time-outs events associated with this link. + */ + NdisMCancelTimer(&Link->CallTimer, &TimerCancelled); + + /* + // Init the optional parameters. They will be set as needed below. + */ + CallEvent.ulParam2 = StateParam; + CallEvent.ulParam3 = Link->MediaMode; + + /* + // OUTGOING) The expected sequence of events for outgoing calls is: + // LINECALLSTATE_IDLE, LINECALLSTATE_DIALTONE, LINECALLSTATE_DIALING, + // LINECALLSTATE_PROCEEDING, (LINECALLSTATE_RINGBACK | LINECALLSTATE_BUSY), + // LINECALLSTATE_CONNECTED, LINECALLSTATE_DISCONNECTED, LINECALLSTATE_IDLE + // + // INCOMING) The expected sequence of events for incoming calls is: + // LINECALLSTATE_IDLE, LINECALLSTATE_OFFERING, LINECALLSTATE_ACCEPTED, + // LINECALLSTATE_CONNECTED, LINECALLSTATE_DISCONNECTED, LINECALLSTATE_IDLE + // + // Under certain failure conditions, these sequences may be violated. + // So I used ASSERTs to verify the normal state transitions which will + // cause a debug break point if an unusual transition is detected. + */ + switch (CallState) + { + case LINECALLSTATE_IDLE: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_IDLE line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + /* + // Make sure that an idle line is disconnected. + */ + if (Link->CallState && + Link->CallState != LINECALLSTATE_IDLE && + Link->CallState != LINECALLSTATE_DISCONNECTED) + { + DBG_WARNING(Adapter, ("Disconnecting Line=%d\n",Link->CardLine)); + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_UNKNOWN); + } + Link->RingCount = 0; + break; + + case LINECALLSTATE_DIALTONE: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_DIALTONE line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_IDLE); + break; + + case LINECALLSTATE_DIALING: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_DIALING line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_DIALTONE); + break; + + case LINECALLSTATE_PROCEEDING: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_PROCEEDING line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_DIALING); + LinkLineUp(Link); + break; + + case LINECALLSTATE_RINGBACK: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_RINGBACK line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_PROCEEDING); + break; + + case LINECALLSTATE_BUSY: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_BUSY line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_DIALING); + break; + + case LINECALLSTATE_CONNECTED: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_CONNECTED line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_PROCEEDING || + Link->CallState == LINECALLSTATE_ACCEPTED); + break; + + case LINECALLSTATE_DISCONNECTED: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_DISCONNECTED line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + CardLineDisconnect(Adapter, Link->CardLine); + LinkLineDown(Link); + break; + + case LINECALLSTATE_OFFERING: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_OFFERING line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_IDLE); + LinkLineUp(Link); + NdisMSetTimer(&Link->CallTimer, HTDSU_NO_ACCEPT_TIMEOUT); + break; + + case LINECALLSTATE_ACCEPTED: + DBG_FILTER(Adapter, DBG_TAPICALL_ON, + ("LINECALLSTATE_ACCEPTED line=0x%x call=0x%x\n", + Link->CardLine, Link->htCall)); + ASSERT(Link->CallState == LINECALLSTATE_OFFERING); + break; + } + /* + // Change the current CallState and notify the connection wrapper if it + // wants to know about this event. + */ + if (Link->CallState != CallState) + { + Link->CallState = CallState; + if (Link->CallStatesMask & CallState) + { + CallEvent.htLine = Link->htLine; + CallEvent.htCall = Link->htCall; + CallEvent.ulMsg = LINE_CALLSTATE; + CallEvent.ulParam1 = CallState; + NdisMIndicateStatus( + Adapter->MiniportAdapterHandle, + NDIS_STATUS_TAPI_INDICATION, + &CallEvent, + sizeof(CallEvent) + ); + DBG_NOTICE(Adapter, ("LINE_CALLSTATE:\n" + "htLine=%Xh\n" + "htCall=%Xh\n", + Link->htLine, + Link->htCall + )); + } + else + { + DBG_NOTICE(Adapter, ("CallState Event=%Xh is not enabled\n", CallState)); + } + } + + DBG_LEAVE(Adapter); +} + + +VOID +HtTapiAddressStateHandler( + IN PHTDSU_ADAPTER Adapter, + IN PHTDSU_LINK Link, + IN ULONG AddressState + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This routine will indicate the given LINEADDRESSSTATE to the Connection + wrapper if the event has been enabled by the wrapper. Otherwise the state + information is saved, but no indication is made. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Link _ A pointer to our link information structure for the selected + line device. + + AddressState _ The LINEADDRESSSTATE event to be posted to TAPI/WAN. + +Return Values: + + None + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiAddressStateHandler") + + /* + // The event structure passed to the connection wrapper. + */ + NDIS_TAPI_EVENT Event; + + DBG_ENTER(Adapter); + + if (Link->AddressStatesMask & AddressState) + { + Event.htLine = Link->htLine; + Event.htCall = Link->htCall; + Event.ulMsg = LINE_CALLSTATE; + Event.ulParam1 = AddressState; + Event.ulParam2 = 0; + Event.ulParam3 = 0; + + /* + // We really don't have much to do here with this adapter. + // And RASTAPI doesn't accept these events anyway... + */ + switch (AddressState) + { + case LINEADDRESSSTATE_INUSEZERO: + break; + + case LINEADDRESSSTATE_INUSEONE: + break; + } + NdisMIndicateStatus( + Adapter->MiniportAdapterHandle, + NDIS_STATUS_TAPI_INDICATION, + &Event, + sizeof(Event) + ); + } + else + { + DBG_NOTICE(Adapter, ("AddressState Event=%Xh is not enabled\n", AddressState)); + } + + DBG_LEAVE(Adapter); +} + + +VOID +HtTapiLineDevStateHandler( + IN PHTDSU_ADAPTER Adapter, + IN PHTDSU_LINK Link, + IN ULONG LineDevState + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This routine will indicate the given LINEDEVSTATE to the Connection wrapper + if the event has been enabled by the wrapper. Otherwise the state + information is saved, but no indication is made. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + + Link _ A pointer to our link information structure for the selected + line device. + + LineDevState _ The LINEDEVSTATE event to be posted to TAPI/WAN. + +Return Values: + + None + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiLineDevStateHandler") + + /* + // The event structure passed to the connection wrapper. + */ + NDIS_TAPI_EVENT LineEvent; + NDIS_TAPI_EVENT CallEvent; + + /* + // The line state change may cause a call state change as well. + */ + ULONG NewCallState = 0; + ULONG StateParam = 0; + + DBG_ENTER(Adapter); + + LineEvent.ulParam2 = 0; + LineEvent.ulParam3 = 0; + + /* + // Handle the line state transition as needed. + */ + switch (LineDevState) + { + case LINEDEVSTATE_RINGING: + LineEvent.ulParam2 = 1; // only one RingMode + if ((LineEvent.ulParam3 = ++Link->RingCount) == 1) + { + NewCallState = LINECALLSTATE_OFFERING; + } + break; + + case LINEDEVSTATE_CONNECTED: + NewCallState = LINECALLSTATE_CONNECTED; + break; + + case LINEDEVSTATE_DISCONNECTED: + if (Link->CallState != LINECALLSTATE_IDLE && + Link->CallState != LINECALLSTATE_DISCONNECTED) + { + NewCallState = LINECALLSTATE_DISCONNECTED; + StateParam = LINEDISCONNECTMODE_NORMAL; + } + break; + + case LINEDEVSTATE_OUTOFSERVICE: + if (Link->CallState != LINECALLSTATE_IDLE && + Link->CallState != LINECALLSTATE_DISCONNECTED) + { + NewCallState = LINECALLSTATE_DISCONNECTED; + StateParam = LINEDISCONNECTMODE_UNKNOWN; + } + break; + + case LINEDEVSTATE_OPEN: + /* + // Make sure the line is configured for dialing when we open up. + // Then enable the interrupts we're interested in now. + */ + if (Link->CardLine == HTDSU_CMD_LINE1) + { + Adapter->InterruptEnableFlag |= HTDSU_INTR_ALL_LINE1; + } + else + { + Adapter->InterruptEnableFlag |= HTDSU_INTR_ALL_LINE2; + } + ++Adapter->NumOpens; + CardLineConfig(Adapter, Link->CardLine); + CardEnableInterrupt(Adapter); + NewCallState = LINECALLSTATE_IDLE; + break; + + case LINEDEVSTATE_CLOSE: + /* + // This must not be called until all transmits have been dequeued + // and ack'd. Otherwise the wrapper will hang waiting for transmit + // request to complete. + */ + if (Link->CardLine == HTDSU_CMD_LINE1) + { + Adapter->InterruptEnableFlag &= ~HTDSU_INTR_ALL_LINE1; + } + else + { + Adapter->InterruptEnableFlag &= ~HTDSU_INTR_ALL_LINE2; + } + CardEnableInterrupt(Adapter); + --Adapter->NumOpens; + NewCallState = LINECALLSTATE_IDLE; + break; + } + Link->DevState = LineDevState; + + /* + // If this is the first indication of an incoming call, we need to + // let TAPI know about it so we can get a htCall handle associated + // with it. + */ + if (NewCallState == LINECALLSTATE_OFFERING) + { + CallEvent.htLine = Link->htLine; + CallEvent.htCall = (HTAPI_CALL)0; + CallEvent.ulMsg = LINE_NEWCALL; + CallEvent.ulParam1 = (ULONG) Link; + CallEvent.ulParam2 = 0; + CallEvent.ulParam3 = 0; + + NdisMIndicateStatus( + Adapter->MiniportAdapterHandle, + NDIS_STATUS_TAPI_INDICATION, + &CallEvent, + sizeof(CallEvent) + ); + Link->htCall = (HTAPI_CALL)CallEvent.ulParam2; + DBG_NOTICE(Adapter, ("NEW_CALL htCall=%Xh\n",Link->htCall)); + } + + /* + // Tell TAPI what's going on here, if she cares. + */ + if (Link->DevStatesMask & LineDevState) + { + LineEvent.htLine = Link->htLine; + LineEvent.htCall = Link->htCall; + LineEvent.ulMsg = LINE_LINEDEVSTATE; + LineEvent.ulParam1 = LineDevState; + + NdisMIndicateStatus( + Adapter->MiniportAdapterHandle, + NDIS_STATUS_TAPI_INDICATION, + &LineEvent, + sizeof(LineEvent) + ); + } + else + { + DBG_NOTICE(Adapter, ("LineDevEvent %Xh is not enabled\n", LineDevState)); + } + + /* + // Tell TAPI what this event does to any call that may be in progress. + */ + if (NewCallState) + { + HtTapiCallStateHandler(Adapter, Link, NewCallState, StateParam); + } + + DBG_LEAVE(Adapter); +} + + +VOID +HtTapiResetHandler( + IN PHTDSU_ADAPTER Adapter + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This rouine 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. + +Parameters: + + Adapter _ A pointer ot our adapter information structure. + +Return Values: + + None + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiResetHandler") + + /* + // A pointer to our link information structure for the selected line device. + */ + PHTDSU_LINK Link; + + DBG_ENTER(Adapter); + + /* + // Force disconnect on both lines. + */ + Link = GET_LINK_FROM_CARDLINE(Adapter, HTDSU_CMD_LINE1); + HtTapiLineDevStateHandler(Adapter, Link, LINEDEVSTATE_DISCONNECTED); + + if (Adapter->NumLineDevs == HTDSU_NUM_LINKS) + { + Link = GET_LINK_FROM_CARDLINE(Adapter, HTDSU_CMD_LINE2); + HtTapiLineDevStateHandler(Adapter, Link, LINEDEVSTATE_DISCONNECTED); + } + + DBG_LEAVE(Adapter); +} + + +VOID +HtTapiCallTimerHandler( + IN PVOID SystemSpecific1, + IN PHTDSU_LINK Link, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Functional Description: + + This routine is called when the CallTimer timeout occurs. It will + handle the event according to the current CallState and make the + necessary indications and changes to the call state. + +Parameters: + + Link _ A pointer to our link information structure on which a call event + is in progress. + +Return Values: + + None + +---------------------------------------------------------------------------*/ + +{ + DBG_FUNC("HtTapiCallTimerHandler") + + PHTDSU_ADAPTER Adapter = Link->Adapter; + + DBG_ENTER(Adapter); + + NdisAcquireSpinLock(&Adapter->Lock); + + switch (Link->CallState) + { + case LINECALLSTATE_DIALING: + if (CardStatusNoDialTone(Adapter, Link->CardLine)) + { + LinkLineError(Link, WAN_ERROR_TIMEOUT); + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_BUSY); + } + else + { + /* + // We got a signal, so dialing must be proceeding + */ + HtTapiCallStateHandler(Adapter, Link, LINECALLSTATE_PROCEEDING, 0); + NdisMSetTimer(&Link->CallTimer, HTDSU_NO_ANSWER_TIMEOUT); + } + break; + + case LINECALLSTATE_PROCEEDING: + if (CardStatusNoAnswer(Adapter, Link->CardLine) || + !CardStatusCarrierDetect(Adapter, Link->CardLine) || + !CardStatusOnLine(Adapter, Link->CardLine)) + { + /* + // We did not get answer, so hangup and abort the call. + */ + LinkLineError(Link, WAN_ERROR_TIMEOUT); + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NOANSWER); + } + break; + + case LINECALLSTATE_OFFERING: + /* + // We did not get an accept or answer, so hangup and abort the call. + */ + LinkLineError(Link, WAN_ERROR_TIMEOUT); + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NOANSWER); + break; + + case LINECALLSTATE_ACCEPTED: + /* + // We did not get connected after answer, so hangup and abort the call. + */ + LinkLineError(Link, WAN_ERROR_TIMEOUT); + HtTapiCallStateHandler(Adapter, Link, + LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NOANSWER); + break; + + case LINECALLSTATE_DISCONNECTED: + /* + // We did not get CloseCall after DropCall, so force a close. + */ + HtTapiCallStateHandler(Adapter, Link, LINECALLSTATE_IDLE, 0); + break; + + default: + DBG_WARNING(Adapter, ("TIMEOUT in CallState=%Xh\n",Link->CallState)); + break; + } + + NdisReleaseSpinLock(&Adapter->Lock); + + DBG_LEAVE(Adapter); +} + |