⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ircomm.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        //      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 + -