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

📄 hci_bcsp.cpp

📁 CSR蓝牙HCI层驱动源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        {
            result = BCSP_STATUS_CONNECTED;
        }
        else
        {
            result = BCSP_STATUS_SYNC;
        }
    }
    else
    {
        result = BCSP_STATUS_DISCONNECTED;
    }

    return result;
}

#ifdef STATISTICS
BOOL BcspCommunication::GetStatistics(BcspStatisticsT* bcspStatistics)
{
    BOOL result = FALSE;

    EnterCriticalSection(&lock);

    bcspStatistics->headerCrcErrors         = headerCrcErrors;
    bcspStatistics->inBytes                 = inBytes;
    bcspStatistics->inPackets               = inPackets;
    bcspStatistics->markerErrors            = markerErrors;
    bcspStatistics->outBytes                = outBytes;
    bcspStatistics->outPackets              = outPackets;
    bcspStatistics->overflowErrors          = overflowErrors;
    bcspStatistics->packetCrcErrors         = packetCrcErrors;
    bcspStatistics->packetSizeErrors        = packetSizeErrors;
    bcspStatistics->retransmissions         = retransmissions;
    bcspStatistics->retransmissionsTimeout  = retransmissionsTimeout;
    bcspStatistics->syncErrors              = syncErrors;
    bcspStatistics->receiveReady            = receiveReady;
    bcspStatistics->receiveTotal            = receiveTotal;
    
    result = TRUE;

    LeaveCriticalSection(&lock);

    return result;
}
#endif

void BcspCommunication::LinkLost()
{
    EnterCriticalSection(&lock);

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::LinkLost@%s> LINK LOST"), name));

    shuttingDown = TRUE;

    SetEvent(writePacketEvent);
    SetEvent(packetAvailable);
    SetEvent(bccmdEvent);
    SetEvent(terminateEvent);

    LeaveCriticalSection(&lock);

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::LinkLost@%s> LINK LOST COMPLETE"), name));
}

DWORD BcspCommunication::OpenConnection(const TCHAR* portName, DWORD baudrate, DWORD maxACLBufferSize, DWORD priority, BOOL waitForSync, BOOL useSafeTimeouts)
{
    COMMTIMEOUTS        commTimeOuts;
    DCB        dcb;
    DWORD        result = ERROR_SUCCESS;

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::OpenConnection@%s> PORT: %s, BAUD: %u, ACL: %u, SERIALTIMEOUTCONSTANT: %u, SERIALINTERVALTIMEOUT: %u"), name, portName, baudrate, maxACLBufferSize, serialTimeoutConstant, serialIntervalTimeout));

    if (serialPortHandle != INVALID_HANDLE_VALUE)
    {
        return ERROR_SUCCESS;
    }

    state                           = BCSP_STATE_SYNC;
    sendSyncResp                    = FALSE;
    sendConfResp                    = FALSE;
    serialPortError                 = FALSE;
    sendTransmitAck                 = FALSE;
    serialPortError                 = FALSE;
    shuttingDown                    = TRUE;
    receivePosition                 = 0;
    receiveInsertPosition           = 0;
    receiveSequence                 = 0;
    receivePositionAcknowledge      = 0;
    transmitPosition                = 0;
    transmitPositionUnacknowledged  = 0;
    transmitInsertPosition          = 0;
    transmitWindow                  = 4;
    transmitTimeout                 = (24000 * maxACLBufferSize * transmitWindow) / baudrate;  // 8 bit * 1.5 (slip overhead) * 2 (room for transmit) * 1000 ms = 24000

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::OpenConnection@%s> TIMEOUT: %u"), name, transmitTimeout));

    shuttingDown = FALSE;

#ifndef UNDER_CE
    serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
#else
    serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#endif
    if (serialPortHandle == INVALID_HANDLE_VALUE)
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO OPEN PORT"), name));
        return GetLastError();
    }

    if (!SetupComm (serialPortHandle, serialBufferSize, serialBufferSize)) 
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET BUFFERS"), name));
        return GetLastError();
    }

    if (!GetCommState(serialPortHandle, &dcb))
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO GET STATE"), name));
        return GetLastError();
    }

    dcb.BaudRate        = baudrate;
    dcb.fBinary         = TRUE;
    dcb.fOutxCtsFlow    = FALSE;
    dcb.fOutxDsrFlow    = FALSE;
    dcb.fOutX           = FALSE;
    dcb.fInX            = FALSE;
    dcb.fNull           = FALSE;
    dcb.fDtrControl     = DTR_CONTROL_DISABLE;
    dcb.fRtsControl     = RTS_CONTROL_DISABLE;
    dcb.fAbortOnError   = FALSE;
    dcb.ByteSize        = 8;
    dcb.fParity         = TRUE;
    dcb.Parity          = EVENPARITY;
    dcb.StopBits        = ONESTOPBIT;
    dcb.ErrorChar       = (char) 0xC0;

    if (!SetCommState(serialPortHandle, &dcb))
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET STATE"), name));
        return GetLastError();
    }

    if (useSafeTimeouts)
    {
        commTimeOuts.ReadIntervalTimeout           = 1;
        commTimeOuts.ReadTotalTimeoutMultiplier    = 0;
        commTimeOuts.ReadTotalTimeoutConstant      = 1000;
        commTimeOuts.WriteTotalTimeoutMultiplier   = 0;
        commTimeOuts.WriteTotalTimeoutConstant     = 1000;
    }
    else
    {
        commTimeOuts.ReadIntervalTimeout           = serialIntervalTimeout;
        commTimeOuts.ReadTotalTimeoutMultiplier    = 0;
        commTimeOuts.ReadTotalTimeoutConstant      = serialTimeoutConstant;
        commTimeOuts.WriteTotalTimeoutMultiplier   = 0;
        commTimeOuts.WriteTotalTimeoutConstant     = serialTimeoutConstant;
    }

    if (!SetCommTimeouts (serialPortHandle, &commTimeOuts))
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET TIMEOUTS"), name));
        return GetLastError();
    }

    serialPortError         = FALSE;
    writePacketEvent        = CreateEvent(NULL, FALSE, FALSE, NULL);
    packetAvailable         = CreateEvent(NULL, FALSE, FALSE, NULL);
    inSyncEvent             = CreateEvent(NULL, FALSE, FALSE, NULL);
    bccmdEvent              = CreateEvent(NULL, FALSE, FALSE, NULL);
    terminateEvent          = CreateEvent(NULL, TRUE, FALSE, NULL);
    transmitHandle          = CreateSemaphore(NULL, 8, 8, NULL);
    writeThread             = CreateThread(NULL, 0, BCSPWriteThreadExecute, this, 0, 0);
    Sleep(65);
    readThread              = CreateThread(NULL, 0, BCSPReadThreadExecute, this, 0, 0);
    Sleep(65);
    CeSetThreadPriority(writeThread, priority);
    CeSetThreadPriority(readThread, priority);


    if (waitForSync)
    {
        result = WaitForSingleObject(inSyncEvent, INFINITE) == WAIT_OBJECT_0 ? ERROR_SUCCESS : ERROR_OPEN_FAILED;
    }

    return result;
}

DWORD BcspCommunication::ReadExecute()
{
    DWORD            commEvent;
    DWORD            bytesRead;
    DWORD            index;
    BOOL             inSync         = FALSE;
    BOOL             inMarker       = FALSE;
    DWORD            inPacketSize   = 0;
    unsigned char    buffer[4096];
    unsigned char    inBuffer[4096];
    PurgeComm(serialPortHandle, PURGE_RXCLEAR);

    if (!SetCommMask(serialPortHandle, EV_RXCHAR))
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> SetCommMask returned: %u"), name, GetLastError()));
        serialPortError = TRUE;
        return ERROR_SUCCESS;
    }

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadExecute@%s> STARTING READING THREAD"), name));

    __try
    {
        while (!shuttingDown && !serialPortError)
        {

            if (!WaitCommEvent(serialPortHandle, &commEvent, NULL))
            {
                IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> WaitCommEvent returned: %u"), name, GetLastError()));
                serialPortError = TRUE;
                LinkLost();
                break;
            }


            if (!SetCommMask (serialPortHandle, EV_RXCHAR))
            {
                IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> SetCommMask returned: %u"), name, GetLastError()));
                serialPortError = TRUE;
                LinkLost();
                break;
            }

            if (!(commEvent & EV_RXCHAR))
            {
                IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> CommEvent != EV_RXCHAR"), name));
                serialPortError = TRUE;
                LinkLost();
                break;
            }

            if (!ReadFile(serialPortHandle, &buffer, sizeof(buffer), &bytesRead, NULL))
            {
                IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> ReadFile returned: %u"), name, GetLastError()));
                serialPortError = TRUE;
                LinkLost();
                break;
            }

            IFDBG(DebugOut(DEBUG_BCSP_INIT, TEXT("<BcspCommunication::ReadExecute@%s> READ DATA (SIZE: %u)"), name, bytesRead));

            IFSTAT(inBytes += bytesRead);

            if (bytesRead)
            {
                for (index = 0; index < bytesRead; index++)
                {
                    if (buffer[index] == 0xC0)
                    {
                        IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SYNC FOUND (inPacketSize: %u)"), name, inPacketSize));

                        if (inPacketSize)
                        {
                            IFSTAT(inPackets++);

                            if (sniffMode == 1)
                            {
                            HCIFileWritePacket(1, inBuffer, inPacketSize);
                            }

                            DecodeBCSPPacket(inBuffer, inPacketSize);

                            inSync = 0;
                        }
                        else
                        {
                            inSync = 1;
                        }

                        inMarker    = FALSE;
                        inPacketSize    = 0;
                    }
                    else if (buffer[index] == 0xDB)
                    {
                        inMarker = TRUE;
                    }
                    else
                    {
                        if (inSync)
                        {
                            if (inMarker)
                            {
                            if (buffer[index] == 0xDC)
                            {
                                inBuffer[inPacketSize++] = 0xC0;
                            }
                            else if (buffer[index] == 0xDD)
                            {
                                inBuffer[inPacketSize++] = 0xDB;
                            }
                            else
                            {
                                IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> MARKER ERROR"), name));
                                inSync = FALSE;
                                IFSTAT(markerErrors++);
                            }

                            inMarker = FALSE;
                            }
                            else
                            {
                            inBuffer[inPacketSize++] = buffer[index];
                            }

                            if (inPacketSize == sizeof(inBuffer))
                            {
                            IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SYNC ERROR 1"), name));
                            inSync = FALSE;
                            IFSTAT(overflowErrors++);
                            }
                        }
                        else
                        {
                            IFSTAT(syncErrors++);
                        }
                    }
                }
            }

            IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SLIP DECODE COMPLETE"), name));
        }
    }
    __except(1)
    {
        IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> READ DATA EXCEPTION"), name));
    }

    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadExecute@%s> TERMINATED (shuttingDown: %u, serialPortError: %u)"), name, shuttingDown, serialPortError));

    return ERROR_SUCCESS;
}

DWORD BcspCommunication::ReadPacket(BcspChannelT* channel, unsigned char** buffer, DWORD* size)
{
    BOOL                found = FALSE;
    BcspQueueElementT*  bcspQueueElement = NULL;
    unsigned char       incValue = 0;

    if (shuttingDown || serialPortError)
    {
        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadPacket@%s> SHUTING DOWN OR SERIAL ERROR"), name));
        CloseConnection();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    EnterCriticalSection(&lock);

    while (!shuttingDown && !found)
    {
        if (incomingSCOData.present)
        {
            bcspQueueElement = &incomingSCOData;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -