?? tapifun.c
字號:
/* Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved. */
#include "windows.h"
#include "ndis.h"
#include "ndiswan.h"
#include "tapi.h"
#include "ndistapi.h"
#include "asyncmac.h"
#include "windev.h" // For IsAPIReady()
#define DEV_CLASS_COMM_DATAMODEM TEXT("comm/datamodem")
// ----------------------------------------------------------------
//
//
// @func DWORD | TapiLineGetID |
// Get the handle to the underlying serial port.
//
// @rdesc Returns the port handle or INVALID_HANDLE_VALUE.
//
// @parm HCALL | hCall | The handle to the call
//
// @comm
// This function will get the handle to the underlying port of
// a TAPI call. This can be used by ReadFile/WriteFile etc.
//
// @ex An example of how to use this function follows |
// No Example
//
//
HANDLE
TapiLineGetID(HLINE hLine, HCALL hCall)
{
LPVARSTRING pVStr;
long lReturn;
DWORD dwNeededSize;
DWORD dwPortID = (DWORD)INVALID_HANDLE_VALUE;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+TapilineGetID(0x%X, 0x%X)\r\n"), hLine, hCall));
dwNeededSize = sizeof(VARSTRING);
while (1) {
pVStr = (LPVARSTRING)LocalAlloc (LPTR, dwNeededSize);
if (NULL == pVStr) {
break;
}
pVStr->dwTotalSize = dwNeededSize;
lReturn = lineGetID(hLine, 0, hCall, LINECALLSELECT_CALL,
pVStr, DEV_CLASS_COMM_DATAMODEM);
if (lReturn) {
DEBUGMSG (ZONE_ERROR,
(TEXT(" lineGetID returned 0x%X\r\n"),
lReturn));
LocalFree (pVStr);
pVStr = NULL;
break;
}
if (pVStr->dwNeededSize > pVStr->dwTotalSize) {
dwNeededSize = pVStr->dwNeededSize;
LocalFree (pVStr);
pVStr = NULL;
continue;
}
break;
}
if (pVStr) {
dwPortID = *((LPDWORD)((LPBYTE)pVStr + pVStr->dwStringOffset));
DEBUGMSG (ZONE_FUNCTION,
(TEXT(" TapilineGetID ID=0x%X\r\n"), dwPortID));
LocalFree (pVStr);
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-TapilineGetID Returning 0x%X\r\n"), dwPortID));
return (HANDLE)dwPortID;
}
void
SendLineDown(
PASYNCMAC_OPEN_LINE pOpenLine)
{
NDIS_MAC_LINE_DOWN MacLineDown;
PASYNCMAC_ADAPTER pAdapter;
ASSERT (CHK_AOL(pOpenLine));
pAdapter = pOpenLine->pAdapter;
ASSERT (CHK_AA(pAdapter));
if (!(pOpenLine->dwFlags & AOL_FLAGS_SENT_LINE_UP))
{
RETAILMSG (1, (TEXT("SendLineDown: Can't send line down if we never sent a line up\n")));
}
else
{
memset ((char *)&MacLineDown, 0, sizeof(MacLineDown));
MacLineDown.NdisLinkContext = pOpenLine->hNdisLinkContext;
NdisMIndicateStatus (pAdapter->hMiniportAdapter,
NDIS_STATUS_WAN_LINE_DOWN,
&MacLineDown, sizeof(MacLineDown));
// Turn off the flag
pOpenLine->dwFlags &= ~(AOL_FLAGS_SENT_LINE_UP);
}
}
// -----------------------------------------------------------------------------
//
// FUNCTION: lineCallbackFunc(..)
//
// PURPOSE: Receive asynchronous TAPI events
//
// PARAMETERS:
// dwDevice - Device associated with the event, if any
// dwMsg - TAPI event that occurred.
// dwCallbackInstance - User defined data supplied when opening the line.
// dwParam1 - dwMsg specific information
// dwParam2 - dwMsg specific information
// dwParam3 - dwMsg specific information
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This is the function where all asynchronous events will come.
// Almost all events will be specific to an open line, but a few
// will be general TAPI events (such as LINE_REINIT).
//
//
// -----------------------------------------------------------------------------
void CALLBACK
lineCallbackFunc(DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
PASYNCMAC_OPEN_LINE pOpenLine = (PASYNCMAC_OPEN_LINE)dwCallbackInstance;
PASYNCMAC_ADAPTER pAdapter;
NDIS_TAPI_EVENT TapiEvent;
NDIS_MAC_LINE_UP MacLineUp;
DWORD dwID;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+lineCallbackFunc(0x%X, %d, %d, 0x%X, 0x%X, 0x%X)\r\n"),
dwDevice, dwMsg, dwCallbackInstance,
dwParam1, dwParam2, dwParam3));
TapiEvent.htLine = 0;
TapiEvent.htCall = 0;
TapiEvent.ulMsg = dwMsg;
TapiEvent.ulParam1 = dwParam1;
TapiEvent.ulParam2 = dwParam2;
TapiEvent.ulParam3 = dwParam3;
if (dwMsg == LINE_CREATE)
{
extern PASYNCMAC_ADAPTER v_pAdapter;
// A new TAPI device like a PCMCIA card modem has been created.
// Note that TAPI devices never go away, so their is no LINE_DESTROY message.
DEBUGMSG (ZONE_FUNCTION, (TEXT(" lineCallbackFunc: LINE_CREATE\n")));
if (v_pAdapter != NULL)
{
// Inform the protocol that the count of devices has changed.
NdisMIndicateStatus (v_pAdapter->hMiniportAdapter,
NDIS_STATUS_TAPI_INDICATION,
&TapiEvent, sizeof(NDIS_TAPI_EVENT));
}
DEBUGMSG (ZONE_FUNCTION, (TEXT("-lineCallbackFunc\n")));
return;
}
if (0 == dwCallbackInstance) {
DEBUGMSG (ZONE_ERROR, (TEXT("-lineCallbackFunc: dwCallbackInstance==NULL\r\n")));
return;
}
if (NULL == (pOpenLine = GetOpenLinePtr ((void *)dwCallbackInstance))) {
DEBUGMSG (ZONE_ERROR, (TEXT("-lineCallbackFunc: dwCallbackInstance(0x%X) not a valid pOpenLine\r\n"),
dwCallbackInstance));
return;
}
ASSERT (CHK_AOL(pOpenLine));
pAdapter = pOpenLine->pAdapter;
ASSERT (CHK_AA(pAdapter));
switch (dwMsg)
{
case LINE_CALLINFO:
// Information about the call has changed.
break;
case LINE_CALLSTATE :
// Save away the callstate
pOpenLine->dwCallState = dwParam1;
switch (dwParam1) {
case LINECALLSTATE_CONNECTED :
DEBUGMSG(ZONE_INTERFACE, (TEXT("LINECALLSTATE_CONNECTED\n")));
// Let's get the handle to the serial port.
pOpenLine->hPort = TapiLineGetID(pOpenLine->hLine, pOpenLine->hCall);
ASSERT (pOpenLine->hRxThrd == NULL);
// Keep track of the line up.
pOpenLine->dwFlags |= AOL_FLAGS_SENT_LINE_UP;
pOpenLine->hRxThrd = CreateThread (NULL, 0, MacRxThread, pOpenLine, 0, &dwID);
ASSERT (pOpenLine->hRxThrd != INVALID_HANDLE_VALUE);
// Set the receive thread priority
CeSetThreadPriority(pOpenLine->hRxThrd, pAdapter->dwRecvThreadPrio);
memset ((char *)&MacLineUp, 0, sizeof(MacLineUp));
MacLineUp.LinkSpeed = pOpenLine->dwBaudRate;
// TODO MacLineUp.Quality =
MacLineUp.SendWindow = 1;
MacLineUp.ConnectionWrapperID = (NDIS_HANDLE)pOpenLine->htCall;
MacLineUp.NdisLinkHandle = pOpenLine;
NdisMIndicateStatus (pAdapter->hMiniportAdapter,
NDIS_STATUS_WAN_LINE_UP,
&MacLineUp, sizeof(MacLineUp));
// Save the NdisLinkContext;
pOpenLine->hNdisLinkContext = MacLineUp.NdisLinkContext;
break;
case LINECALLSTATE_IDLE :
DEBUGMSG(ZONE_INTERFACE, (TEXT("ASYNCMAC: LINECALLSTATE_IDLE\n")));
if (pOpenLine->dwFlags & AOL_FLAGS_SENT_LINE_UP) {
SendLineDown (pOpenLine);
// Kill recv thread.
while (pOpenLine->hRxThrd) {
DEBUGMSG (ZONE_TAPI, (TEXT(" lineCallbackFunc: Calling SetCommMask\n")));
if (SetCommMask (pOpenLine->hPort, 0) == FALSE)
{
// Port is invalid
DEBUGMSG (ZONE_ERROR, (TEXT(" lineCallbackFunc: SetCommMask failed, error=%d\n"), GetLastError()));
break;
}
Sleep (20);
}
}
break;
case LINECALLSTATE_DISCONNECTED:
DEBUGMSG (ZONE_FUNCTION, (TEXT(" lineCallbackFunc: LINECALLSTATE_DISCONNECTED\n")));
break;
default :
DEBUGMSG (1, (TEXT(" lineCallbackFunc: Unhandled LINE_CALLSTATE Callback %d\n"), dwParam1));
break;
}
break;
case LINE_REPLY :
//
// dwParam2 has the error code. If non-zero then something bad has happened.
//
if (dwParam2) {
// Tell the caller that this failed.
// SetEvent (s_p->TapiEvent);
}
break;
default :
DEBUGMSG (1, (TEXT(" lineCallbackFunc: Unhandled callback %d\r\n"), dwMsg));
break;
}
// Let's just let the NDISWAN layer know what happened
if (pOpenLine->hCall) {
// Check again just in case we had to wait for the lock......
if (pOpenLine->hCall) {
TapiEvent.htLine = pOpenLine->htLine;
TapiEvent.htCall = pOpenLine->htCall;
NdisMIndicateStatus (pAdapter->hMiniportAdapter,
NDIS_STATUS_TAPI_INDICATION,
&TapiEvent, sizeof(NDIS_TAPI_EVENT));
}
}
ReleaseOpenLinePtr (pOpenLine);
DEBUGMSG (ZONE_FUNCTION, (TEXT("-lineCallbackFunc\r\n")));
return;
}
VOID NDISAPI
DoLineInitialize(PVOID SystemSpecific1,
PVOID FunctionContext,
PVOID SystemSpecific2,
PVOID SystemSpecific3)
{
PASYNCMAC_ADAPTER pAdapter = (PASYNCMAC_ADAPTER)FunctionContext;
long lReturn;
NDIS_TAPI_EVENT TapiEvent;
DWORD i;
LINEEXTENSIONID lineExtensionID;
if (IsAPIReady(SH_TAPI)) {
// Sleep an extra 5 seconds anyway, why? I don't know but it seems
// like a good idea, this allows all of the initial devices to be
// created.
Sleep(5000);
lReturn = lineInitialize (&(pAdapter->hLineApp),
v_hInstance, lineCallbackFunc,
TEXT("ASYNCMAC"), &(pAdapter->dwNumDevs));
if (lReturn == 0) {
DEBUGMSG (1, (TEXT("lineInitialize say's there's %d devices\r\n"),
pAdapter->dwNumDevs));
// Let's figure out the version number to use?
// We'll just ask for device 0?
if (lineNegotiateAPIVersion(pAdapter->hLineApp, 0,
TAPI_CURRENT_VERSION, TAPI_CURRENT_VERSION,
&(pAdapter->dwAPIVersion), &lineExtensionID)) {
DEBUGMSG (1, (TEXT("Error from lineNegotiateAPIVersion?\r\n")));
}
// Now inform PPP that we have new devices
memset ((char *)&TapiEvent, 0, sizeof(TapiEvent));
//TapiEvent.htLine = 0;
//TapiEvent.htCall = 0;
TapiEvent.ulMsg = LINE_CREATE;
for (i=0; i < pAdapter->dwNumDevs; i++) {
// Indicate device num
TapiEvent.ulParam1 = i;
NdisMIndicateStatus(pAdapter->hMiniportAdapter, NDIS_STATUS_TAPI_INDICATION, &TapiEvent, sizeof(TapiEvent));
}
}
DEBUGMSG (ZONE_ERROR && lReturn,
(TEXT("ASYNCMAC: Error %d from lineInitialize\r\n")));
} else {
DEBUGMSG (1, (TEXT("ASYNCMAC:Tapi not ready yet... Resetting Timer\r\n")));
NdisMSetTimer (&(pAdapter->ntLineInit), 1000);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -