📄 openclos.c
字号:
NdisCloseConfiguration(hConfig);
}
DEBUGMSG(ZONE_INIT, (TEXT("-GetDeviceConfiguration [0x%.8X]\r\n"), status));
return (status);
}
/*++
Function: StartDevice
Description: Opens the device's COM port and start Rx/Tx threads. Configures
COM port and dongle.
Arguments:
pIrDevice - Pointer to IR device object.
Returns:
NDIS_STATUS
NDIS_STATUS_SUCCESS - COM port opened and threads started.
NDIS_STATUS_NOT_ACCEPTED - Cannot configure serial port.
Comments:
--*/
NDIS_STATUS
StartDevice(
IN PIR_DEVICE pIrDevice
)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
BOOL fDongleInit = FALSE;
DWORD dwTxThreadId;
DWORD dwRxThreadId;
WCHAR lpszPortName[64];
NdisAcquireSpinLock(&pIrDevice->slDevice);
DEBUGMSG(ZONE_INIT, (TEXT("IrSir: +StartDevice(0x%x)\r\n"), pIrDevice));
//
// First, open the serial port.
//
pIrDevice->pCurrBaud = &v_rgSupportedBaudRates[DEFAULT_BAUDRATE];
wsprintf(lpszPortName, TEXT("COM%d:"), pIrDevice->dwPort);
pIrDevice->hSerial = CreateFile(
lpszPortName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (pIrDevice->hSerial == INVALID_HANDLE_VALUE)
{
status = NDIS_STATUS_OPEN_FAILED;
DEBUGMSG(ZONE_ERROR,
(TEXT("Irsir: Create file [%s] failure = 0x%.8X [%d]\r\n"),
lpszPortName, GetLastError(), GetLastError())
);
goto done;
}
//
// Need to set default serial line control, stopbits, parity, timeouts...
//
pIrDevice->Dcb.DCBlength = sizeof(DCB);
GetCommState(pIrDevice->hSerial, &pIrDevice->Dcb);
pIrDevice->Dcb.BaudRate = 9600;
pIrDevice->Dcb.fBinary = TRUE;
pIrDevice->Dcb.fParity = FALSE;
pIrDevice->Dcb.fOutxCtsFlow = FALSE;
pIrDevice->Dcb.fOutxDsrFlow = FALSE;
pIrDevice->Dcb.fDtrControl = DTR_CONTROL_DISABLE;
pIrDevice->Dcb.fDsrSensitivity = FALSE;
pIrDevice->Dcb.fOutX = FALSE;
pIrDevice->Dcb.fInX = FALSE;
pIrDevice->Dcb.fErrorChar = 0;
pIrDevice->Dcb.fNull = 0;
pIrDevice->Dcb.fRtsControl = RTS_CONTROL_ENABLE;
pIrDevice->Dcb.fAbortOnError = FALSE;
pIrDevice->Dcb.ByteSize = 8;
pIrDevice->Dcb.Parity = NOPARITY;
pIrDevice->Dcb.StopBits = ONESTOPBIT;
pIrDevice->Dcb.XonChar = 17;
pIrDevice->Dcb.XoffChar = 19;
pIrDevice->Dcb.ErrorChar = 63;
pIrDevice->Dcb.EofChar = 26;
pIrDevice->Dcb.EvtChar = 0;
if (SetCommState(pIrDevice->hSerial, &pIrDevice->Dcb) == FALSE)
{
status = NDIS_STATUS_FAILURE;
goto done;
}
//
// Set the CommMask.
//
pIrDevice->dwCommMask = EV_RXCHAR;
if (SetCommMask(pIrDevice->hSerial, pIrDevice->dwCommMask) == FALSE)
{
status = NDIS_STATUS_FAILURE;
goto done;
}
DEBUGMSG(ZONE_COMMMASK,
(TEXT("StartDevice:SetCommMask 0x%.8X\r\n"),
pIrDevice->dwCommMask)
);
//
// If we are using internal IR...
//
if (pIrDevice->fIntIR == TRUE)
{
if (EscapeCommFunction(pIrDevice->hSerial, SETIR) == FALSE)
{
status = NDIS_STATUS_FAILURE;
goto done;
}
}
//
// Initialize the dongle.
//
status = pIrDevice->IDongle.Initialize(
pIrDevice->hSerial
);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
fDongleInit = TRUE;
ASSERT(pIrDevice->capsDongle.dwSpeedMask & NDIS_IRDA_SPEED_9600);
//
// Set UART/dongle speed.
//
status = pIrDevice->IDongle.SetSpeed(
pIrDevice->hSerial,
&pIrDevice->Dcb,
9600
);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
// Setup recv state and start the receive thread.
pIrDevice->RxState = RX_STATE_READY;
pIrDevice->cbRxNumBytes = 0;
pIrDevice->iRxCurrByte = 0;
pIrDevice->hRxThread = CreateThread(NULL, 0, IrsirRxThread,
pIrDevice, 0, &dwRxThreadId);
if (pIrDevice->hRxThread == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
// Set the thread priority as required. We set this now rather than
// in the thread, since we may get a set media busy. We want the
// receive thread to be a stable state.
SetThreadPriority(pIrDevice->hRxThread, THREAD_PRIORITY_HIGHEST);
// Start the send thread.
ASSERT(pIrDevice->pSendHead == NULL &&
pIrDevice->pSendTail == NULL &&
pIrDevice->pSendActive == NULL);
pIrDevice->cbSendBuf = MAX_IRDA_DATA_SIZE;
pIrDevice->hTxThread = CreateThread(NULL, 0, IrsirTxThread,
pIrDevice, 0, &dwTxThreadId);
if (pIrDevice->hTxThread == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
done:
if (status == NDIS_STATUS_SUCCESS)
{
status = StartFIR(pIrDevice);
}
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("IrSIR: StartDevice failed - 0x%x.\r\n"),
status)
);
if (fDongleInit == TRUE)
{
pIrDevice->IDongle.Deinitialize(pIrDevice->hSerial);
}
StopDevice(pIrDevice);
}
NdisReleaseSpinLock(&pIrDevice->slDevice);
DEBUGMSG(ZONE_INIT, (TEXT("IrSir: -StartDevice [0x%x]\r\n"), status));
return (status);
}
/*++
Function: StopDevice
Description: Closes the devices COM port and stops Tx/Rx threads.
Arguments:
pIrDevice - Pointer to IR device object.
Returns:
NDIS_STATUS_SUCCESS
Comments:
--*/
NDIS_STATUS
StopDevice(
IN PIR_DEVICE pIrDevice
)
{
DEBUGMSG(ZONE_INIT, (TEXT("IrSir: +StopDevice(0x%x)\r\n"), pIrDevice));
NdisAcquireSpinLock(&pIrDevice->slDevice);
if (pIrDevice->hSerial != INVALID_HANDLE_VALUE)
{
// We indicate to the receive to shutdown by going to shutdown state.
// Since the handle was closed, the ReadFile will return.
pIrDevice->RxState = RX_STATE_SHUTDOWN;
pIrDevice->IDongle.Deinitialize(pIrDevice->hSerial);
// We indicate to the send thread to shutdown by giving a NULL
// send buffer and signalling the send event.
pIrDevice->pSendActive = NULL;
SetEvent(pIrDevice->hSendEvent);
// Close the handle, this will wake up the recv if blocked waiting
// for a byte.
CloseHandle(pIrDevice->hSerial);
pIrDevice->hSerial = INVALID_HANDLE_VALUE;
NdisZeroMemory(&pIrDevice->Dcb, sizeof(DCB));
StopFIR(pIrDevice);
NdisReleaseSpinLock(&pIrDevice->slDevice);
ASSERT(pIrDevice->hTxThread != NULL);
ASSERT(pIrDevice->hRxThread != NULL);
if (pIrDevice->hTxThread != NULL)
{
// Wait for TX thread to exit.
if (WaitForSingleObject(pIrDevice->hTxThread, INFINITE) == WAIT_FAILED)
{
ASSERT(FALSE);
return (NDIS_STATUS_FAILURE);
}
else
{
CloseHandle(pIrDevice->hTxThread);
pIrDevice->hTxThread = NULL;
}
}
if (pIrDevice->hRxThread != NULL)
{
// Wait for RX thread to exit.
if (WaitForSingleObject(pIrDevice->hRxThread, INFINITE) == WAIT_FAILED)
{
ASSERT(FALSE);
return (NDIS_STATUS_FAILURE);
}
else
{
CloseHandle(pIrDevice->hRxThread);
pIrDevice->hRxThread = NULL;
}
}
}
else
{
ASSERT(pIrDevice->hRxThread == NULL);
ASSERT(pIrDevice->hTxThread == NULL);
NdisReleaseSpinLock(&pIrDevice->slDevice);
}
DEBUGMSG(ZONE_INIT, (TEXT("IrSir: -StopDevice\r\n"), pIrDevice));
return (NDIS_STATUS_SUCCESS);
}
/*++
Function: MergeSpeedMasks
Description: Merges speed masks from
1) Registry - NDIS_IRDA_SPEED_Xxx
2) DongleCaps - NDIS_IRDA_SPEED_Xxx
3) Uart - BAUD_Xxx from GetCommProperties.
Arguments:
dwDongleSpeedMask - Mask returned by IDongle.GetCaps.
dwRegSpeedMask - Mask found in registry.
dwUartSpeedMask - Mask returned by GetCommProperties.
Returns:
DWORD - Merged speed mask of supported speeds for driver: NDIS_IRDA_SPEED_Xxx.
Comments:
--*/
DWORD
MergeSpeedMasks(
DWORD dwDongleSpeedMask,
DWORD dwRegSpeedMask,
DWORD dwUartSpeedMask
)
{
DWORD dwSpeedMask;
DWORD dwNewUartSpeedMask;
DWORD i;
#ifdef DEBUG
TCHAR szPrintBuf[1024];
TCHAR *pBuf;
DWORD cchAdded;
#endif
#ifdef DEBUG
if (ZONE_INIT)
{
// Dongle speeds.
pBuf = szPrintBuf;
cchAdded = wsprintf(pBuf, TEXT("Supported dongle speeds: "));
pBuf += cchAdded;
for (i = 0; i < NUM_BAUDRATES; i++)
{
if (dwDongleSpeedMask & v_rgSupportedBaudRates[i].dwSpeedMask)
{
cchAdded = wsprintf(pBuf, TEXT("%s"),
v_rgSupportedBaudRates[i].lpszDbgSpeed);
pBuf += cchAdded;
}
}
DEBUGMSG(ZONE_INIT, (TEXT("%s\r\n"), szPrintBuf));
// Reg speeds.
pBuf = szPrintBuf;
cchAdded = wsprintf(pBuf, TEXT("Supported reg speeds: "));
pBuf += cchAdded;
for (i = 0; i < NUM_BAUDRATES; i++)
{
if (dwRegSpeedMask & v_rgSupportedBaudRates[i].dwSpeedMask)
{
cchAdded = wsprintf(pBuf, TEXT("%s"),
v_rgSupportedBaudRates[i].lpszDbgSpeed);
pBuf += cchAdded;
}
}
DEBUGMSG(ZONE_INIT, (TEXT("%s\r\n"), szPrintBuf));
// Uart speeds.
pBuf = szPrintBuf;
cchAdded = wsprintf(pBuf, TEXT("Supported UART speeds: "));
pBuf += cchAdded;
for (i = 0; i < NUM_BAUDRATES; i++)
{
if (dwUartSpeedMask & v_rgSupportedBaudRates[i].dwCommSpeedMask)
{
cchAdded = wsprintf(pBuf, TEXT("%s"),
v_rgSupportedBaudRates[i].lpszDbgSpeed);
pBuf += cchAdded;
}
}
DEBUGMSG(ZONE_INIT, (TEXT("%s\r\n"), szPrintBuf));
}
#endif
//
// Get UART speed mask in terms of NDIS_IRDA_SPEED_Xxx.
//
dwNewUartSpeedMask = 0;
for (i = 0; i < NUM_BAUDRATES; i++)
{
if (dwUartSpeedMask & v_rgSupportedBaudRates[i].dwCommSpeedMask)
{
dwNewUartSpeedMask |= v_rgSupportedBaudRates[i].dwSpeedMask;
}
}
//
// Merge masks.
//
dwSpeedMask = dwNewUartSpeedMask & dwRegSpeedMask & dwDongleSpeedMask;
#ifdef DEBUG
if (ZONE_INIT)
{
// Final speed mask.
pBuf = szPrintBuf;
cchAdded = wsprintf(pBuf, TEXT("Supported speeds: "));
pBuf += cchAdded;
for (i = 0; i < NUM_BAUDRATES; i++)
{
if (dwSpeedMask & v_rgSupportedBaudRates[i].dwSpeedMask)
{
cchAdded = wsprintf(pBuf, TEXT("%s"),
v_rgSupportedBaudRates[i].lpszDbgSpeed);
pBuf += cchAdded;
}
}
DEBUGMSG(ZONE_INIT, (TEXT("%s\r\n"), szPrintBuf));
}
#endif
return (dwSpeedMask);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -