📄 ircomm.c
字号:
// for all read and write operations on a specified
// communications device
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_GET_TIMEOUTS
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Pointer to a <f COMMTIMEOUTS> structure
// for the returned data
// @parm DWORD | dwLenOut | should be sizeof(COMMTIMEOUTS)
// @parm PDWORD | pdwActualOut | Points to DWORD to return length
// of returned data (should be set to sizeof(COMMTIMEOUTS)
// if no error)
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @xref <f IOCTL_SERIAL_GET_TIMEOUTS>
//
case IOCTL_SERIAL_GET_TIMEOUTS:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_GET_TIMEOUTS\r\n")));
if ((dwLenOut < sizeof(COMMTIMEOUTS)) ||
(NULL == pBufOut) ||
(NULL == pdwActualOut))
{
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Clear the structure
memset ((char *) ((COMMTIMEOUTS *)pBufOut), 0, sizeof(COMMTIMEOUTS));
memcpy((LPCOMMTIMEOUTS)pBufOut, &CommTimeouts, sizeof(COMMTIMEOUTS));
// Return the size
*pdwActualOut = sizeof(COMMTIMEOUTS);
break;
// @func BOOL | IOCTL_SERIAL_PURGE |
// Device IO control routine to discard characters from the
// output or input buffer of a specified communications
// resource. It can also terminate pending read or write
// operations on the resource
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_PURGE
// @parm PBYTE | pBufIn | Pointer to a DWORD containing the action
// @parm DWORD | dwLenIn | Should be sizeof(DWORD)
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
//
case IOCTL_SERIAL_PURGE:
DEBUGMSG(ZONE_FUNCTION,
(TEXT("IRCOMM: IOCTL_SERIAL_PURGE 0x%X\r\n"), *(DWORD *) pBufIn));
if ((dwLenIn < sizeof(DWORD)) || (NULL == pBufIn))
{
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Normally we would do something with the passed in parameter.
break;
// @func BOOL | IOCTL_SERIAL_SET_QUEUE_SIZE |
// Device IO control routine to set the queue sizes of of a
// communications device
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_QUEUE_SIZE
// @parm PBYTE | pBufIn | Pointer to a <f SERIAL_QUEUE_SIZES>
// structure
// @parm DWORD | dwLenIn | should be sizeof(<f SERIAL_QUEUE_SIZES>)
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
//
case IOCTL_SERIAL_SET_QUEUE_SIZE:
DEBUGMSG(ZONE_FUNCTION,
(TEXT("IRCOMM: IOCTL_SERIAL_SET_QUEUE_SIZE (%d,%d,%d,%d,%d)\r\n"),
((SERIAL_QUEUE_SIZES *)pBufIn)->cbInQueue,
((SERIAL_QUEUE_SIZES *)pBufIn)->cbOutQueue));
if ((dwLenIn < sizeof(SERIAL_QUEUE_SIZES)) || (NULL == pBufIn))
{
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Normally we would do something with the passed in parameter.
break;
// @func BOOL | IOCTL_SERIAL_IMMEDIATE_CHAR |
// Device IO control routine to transmit a specified character
// ahead of any pending data in the output buffer of the
// communications device
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_IMMEDIATE_CHAR
// @parm PBYTE | pBufIn | Pointer to a UCHAR to send
// @parm DWORD | dwLenIn | should be sizeof(UCHAR)
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
//
case IOCTL_SERIAL_IMMEDIATE_CHAR:
DEBUGMSG(ZONE_FUNCTION,
(TEXT("IRCOMM: IOCTL_SERIAL_IMMEDIATE_CHAR 0x%X\r\n"), (UCHAR *) pBufIn));
if ((dwLenIn < sizeof(UCHAR)) || (NULL == pBufIn))
{
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Normally we would do something with the passed in parameter.
break;
// @func BOOL | IOCTL_SERIAL_GET_DCB |
// Device IO control routine to get the device-control
// block from a specified communications device
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_GET_DCB
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Pointer to a <f DCB> structure
// @parm DWORD | dwLenOut | Should be sizeof(<f DCB>)
// @parm PDWORD | pdwActualOut | Pointer to DWORD to return length
// of returned data (should be set to sizeof(<f DCB>) if
// no error)
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
//
case IOCTL_SERIAL_GET_DCB:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_GET_DCB\r\n")));
if ((dwLenOut < sizeof(DCB)) ||
(NULL == pBufOut) ||
(NULL == pdwActualOut))
{
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Clear the structure
memset ((char *) ((DCB *)pBufOut), 0, sizeof(DCB));
// Return the size
*pdwActualOut = sizeof(DCB);
break;
// @func BOOL | IOCTL_SERIAL_SET_DCB |
// Device IO control routine to set the device-control
// block on a specified communications device
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_DCB
// @parm PBYTE | pBufIn | Pointer to a <f DCB> structure
// @parm DWORD | dwLenIn | should be sizeof(<f DCB>)
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
//
case IOCTL_SERIAL_SET_DCB:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_SET_DCB\r\n")));
if ((dwLenIn < sizeof(DCB)) || (NULL == pBufIn))
{
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
// Normally we would do something with the passed in parameter.
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
DerefOpen(dwOpenData);
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION,
(TEXT("IRCOMM:-COM_IOControl %s (len=%d)\r\n"),
(RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
(NULL == pdwActualOut) ? 0 : *pdwActualOut));
return(RetVal);
}
DWORD WINAPI
AcceptThread(PVOID pThreadParm)
{
int sizeofInt = sizeof(int);
int sizeofSockAddr = sizeof(SOCKADDR_IRDA);
DWORD dwListenInstance = (DWORD)pThreadParm;
SOCKET LocalListenSock;
SOCKADDR_IRDA SockAddrRemote;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+IRCOMM:AcceptThread: Start\r\n")));
EnterCriticalSection(&IrcommCs);
LocalListenSock = ListenSock;
LeaveCriticalSection(&IrcommCs);
while (1) {
EnterCriticalSection(&IrcommCs);
if (dwListenInstance != g_dwListenInstance) {
//
// If the global instance count has changed then the ListenSock that
// this thread was created for has been closed. Because the handle value
// itself may be reused, we keep track using this simple counter instead
// of watching the handle value or its state.
//
DEBUGMSG (ZONE_WARN, (TEXT("IRCOMM: accept() exiting, instance %08X != %08X\r\n"),
dwListenInstance, g_dwListenInstance));
LeaveCriticalSection(&IrcommCs);
break;
}
LeaveCriticalSection(&IrcommCs);
if ((AcceptSock = accept(LocalListenSock,
(struct sockaddr *) &SockAddrRemote,
&sizeofSockAddr)) == INVALID_SOCKET)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM: accept() %s\n\r"), GetLastErrorText()));
if (GetLastError() == WSAENOTSOCK) {
DEBUGMSG (ZONE_FUNCTION, (TEXT("-IRCOMM:AcceptThread: End Accept returned WASENOTSOCK\r\n")));
return(0);
} else {
continue;
}
}
if (getsockopt(AcceptSock, SOL_IRLMP, IRLMP_SEND_PDU_LEN,
(char *) &SendMaxPDU, &sizeofInt) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM: getsockopt(,,IRLMP_SEND_PDU_LEN,,) %s\n\r"), GetLastErrorText()));
closesocket(AcceptSock);
continue;
}
memcpy(&SockAddr.irdaDeviceID[0], &SockAddrRemote.irdaDeviceID, 4);
if (InitializeConnection(AcceptSock) != 0) {
// Error occured?
closesocket(AcceptSock);
AcceptSock = INVALID_SOCKET;
}
break;
}
DEBUGMSG (ZONE_FUNCTION, (TEXT("-IRCOMM:AcceptThread: End, return 0\r\n")));
return(0);
}
int
IrCOMMConnect(void)
{
// allow discovery of 5 devices
BYTE DevListBuff[sizeof(DEVICELIST) + (sizeof(IRDA_DEVICE_INFO) * 4)];
int DevListLen = sizeof(DevListBuff);
PDEVICELIST pDevList = (PDEVICELIST) &DevListBuff;
int sizeofInt = sizeof(int);
int Enable9WireMode = 1;
int i;
if (setsockopt(ConnectSock, SOL_IRLMP, IRLMP_9WIRE_MODE,
(const char *) &Enable9WireMode, sizeof(int))
== SOCKET_ERROR)
{
closesocket(ConnectSock);
ConnectSock = INVALID_SOCKET;
return(-1);
}
if (State == IRCOMM_DISCOVERY_PENDING)
{
pDevList->numDevice = 0;
for (i = 0; (i < 6) && (pDevList->numDevice == 0); i++)
{
if (getsockopt(ConnectSock, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *) pDevList, &DevListLen) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM: getsockopt(,,IRLMP_ENUM_DEVICES,,) %s\n\r"), GetLastErrorText()));
return(-1);
}
}
if (pDevList->numDevice == 0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM: No devices found\r\n")));
return(-1);
}
memcpy(&SockAddr.irdaDeviceID[0],
&pDevList->Device[0].irdaDeviceID[0], 4);
NewState(IRCOMM_CONNECT_PENDING);
#ifdef DEBUG
for (i = 0; i < (int)pDevList->numDevice; i++) {
DEBUGMSG(ZONE_CONN, (L"IRCOMM: Device %d = %a\n", i, pDevList->Device[i].irdaDeviceName));
}
#endif
}
if (State == IRCOMM_CONNECT_PENDING)
{
if (connect(ConnectSock, (const struct sockaddr *) &SockAddr,
sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("IRCOMM: connect() %s\n\r"), GetLastErrorText()));
return(-1);
}
else
{
if (getsockopt(ConnectSock, SOL_IRLMP, IRLMP_SEND_PDU_LEN,
(char *) &SendMaxPDU, &sizeofInt) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("IRCOMM: getsockopt(,,IRLMP_SEND_PDU_LEN,,) %s\n\r"),
GetLastErrorText()));
return(-1);
}
return InitializeConnection(ConnectSock);
}
}
return(0);
}
int
InitializeConnection(SOCKET p_DataSock)
{
HANDLE hThrd;
int result = -1;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:+InitializeConnection %d\n"), p_DataSock));
EnterCriticalSection(&IrcommCs);
if (DataSock != INVALID_SOCKET) {
// A connection is already established, and only 1 connection is allowed at a time.
DEBUGMSG(ZONE_FUNCTION|ZONE_WARN, (TEXT("IRCOMM:-InitializeConnection - WARNING connection already established\n")));
LeaveCriticalSection(&IrcommCs);
return result;
}
NewState(IRCOMM_CONNECTED);
ASSERT(DataSock == INVALI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -