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

📄 hci_bcsp.cpp

📁 CSR蓝牙HCI层驱动源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    tempCrc = ((tempCrc & 0x00ff) << 8) | (tempCrc >> 8);
    tempCrc = ((tempCrc & 0x0f0f) << 4) | ((tempCrc & 0xf0f0) >> 4);
    tempCrc = ((tempCrc & 0x3333) << 2) | ((tempCrc & 0xcccc) >> 2);
    tempCrc = ((tempCrc & 0x5555) << 1) | ((tempCrc & 0xaaaa) >> 1);

    *crc = tempCrc;
}

DWORD BcspCommunication::CloseConnection()
{
    uint8_t index;
    
    EnterCriticalSection(&lock);
    if (serialPortHandle != INVALID_HANDLE_VALUE)
    {
        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection>")));

        IFSTAT(TCHAR buffer[512]);
        IFSTAT(_stprintf(buffer, TEXT("state_%u.txt"), GetTickCount()));
        IFSTAT(FILE* f = _tfopen(buffer, TEXT("w+")));
        IFSTAT(_ftprintf(f, TEXT("STATS1 (In bytes: %u, In packets: %u, Out bytes: %u, Out packets: %u)\n"), inBytes, inPackets, outBytes, outPackets));
        IFSTAT(_ftprintf(f, TEXT("STATS2 (Retransmissions: %u, Retransmissions Timeout: %u, ReceiveReady: %u, ReceiveTotal: %u)\n"), retransmissions, retransmissionsTimeout, receiveReady, receiveTotal));
        IFSTAT(_ftprintf(f, TEXT("ERRORS (Sync: %u, Marker: %u, Overflow: %u, Header CRC: %u, Packet CRC: %u, Incorrect Size: %u)\n"), syncErrors, markerErrors, overflowErrors, headerCrcErrors, packetCrcErrors, packetSizeErrors));
        IFSTAT(fclose(f));
        
        IFSTAT(IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection@%s> STATS  (In bytes: %u, In packets: %u, Out bytes: %u, Out packets: %u)"), name, inBytes, inPackets, outBytes, outPackets)));
        IFSTAT(IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection@%s> ERRORS (Sync: %u, Marker: %u, Overflow: %u, Header CRC: %u, Packet CRC: %u, Incorrect Size: %u)"), name, syncErrors, markerErrors, overflowErrors, headerCrcErrors, packetCrcErrors, packetSizeErrors)));

        shuttingDown    = TRUE;

        SetEvent(terminateEvent);
        SetEvent(packetAvailable);

        CloseHandle(serialPortHandle);
        serialPortHandle = INVALID_HANDLE_VALUE;

        CloseHandle(transmitHandle);
        SetEvent(writePacketEvent);

        LeaveCriticalSection(&lock);

        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection> Waiting for threads to terminate (readThread: 0x%08x, writeThread: 0x%08x)"), readThread, writeThread));

        WaitForSingleObject(readThread, 2000);
        WaitForSingleObject(writeThread, 2000);

        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection> Threads terminated")));

        EnterCriticalSection(&lock);

        CloseHandle(readThread);
        CloseHandle(writeThread);
        CloseHandle(writePacketEvent);
        CloseHandle(packetAvailable);
        CloseHandle(inSyncEvent);
        CloseHandle(bccmdEvent);
        CloseHandle(terminateEvent);

        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection> Handles closed")));

        for (index = 0; index < 8; index++)
        {
            free(transmitQueue[index].buffer);
            free(receiveQueue[index].buffer);
        }
        
        ZeroMemory(&transmitQueue, sizeof(transmitQueue));
        ZeroMemory(&receiveQueue, sizeof(receiveQueue));

        free(incomingSCOData.buffer);
        free(outgoingSCOData.buffer);
        
        ZeroMemory(&incomingSCOData, sizeof(incomingSCOData));
        ZeroMemory(&outgoingSCOData, sizeof(outgoingSCOData));
        
        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection> Memory freed")));

        free(bccmdBuffer);

        transmitHandle      = NULL;
        readThread          = NULL;
        writeThread         = NULL;
        writePacketEvent    = NULL;
        packetAvailable     = NULL;
        inSyncEvent         = NULL;
        terminateEvent      = NULL;
        numberOfSyncs       = 40;
        bccmdBuffer         = NULL;
        bccmdSize           = 0;
        bccmdEvent          = NULL;
        
        IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::CloseConnection@%s> Complete"), name));
    }

    LeaveCriticalSection(&lock);

    return ERROR_SUCCESS;
}

DWORD BcspCommunication::DecodeBCSPPacket(unsigned char* buffer, DWORD size)
{
    BCSPHeader*    bcspHeader    = (BCSPHeader*) buffer;
    unsigned char*    bchsPayload    = (unsigned char*) (bcspHeader + 1);

    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> New packet (Size: %u)"), name, size));

    if (size < 4)
    {
        IFSTAT(packetSizeErrors++);
        return ERROR_INVALID_DATA;
    }

    if (bcspHeader->checksum != bcspHeader->GetChecksum())
    {
        IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> Header checksum error"), name));
        IFSTAT(headerCrcErrors++);
        return ERROR_INVALID_DATA;
    }

    if (bcspHeader->crcPresent)
    {
        if (size < 6 || (DWORD) bcspHeader->payloadLength + 6 > size)
        {
            IFSTAT(packetSizeErrors++);
            return ERROR_INVALID_DATA;
        }
    }
    else
    {
        if ((DWORD) bcspHeader->payloadLength + 4 > size)
        {
            IFSTAT(packetSizeErrors++);
            return ERROR_INVALID_DATA;
        }
    }
    if (bcspHeader->crcPresent && bcspHeader->payloadLength)
    {
        unsigned short crc;
        unsigned char* bchsChecksum = bchsPayload + bcspHeader->payloadLength;

        CalculateCRC(buffer, bcspHeader->payloadLength + sizeof(BCSPHeader), &crc);

        if (((*bchsChecksum) << 8 | (*(bchsChecksum + 1))) != crc)
        {
            IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> Payload checksum error"), name));
            IFSTAT(packetCrcErrors++);
            return ERROR_INVALID_DATA;
        }
    }

    if (!bcspHeader->protocolType && (bcspHeader->protocolID == 1))
    {
        if (bcspHeader->payloadLength != 4)
        {
            return ERROR_INVALID_DATA;
        }

        EnterCriticalSection(&lock);
    
        if (!memcmp(bchsPayload, syncPayload, sizeof(syncPayload)))
        {
            IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> RECV: SYNC"), name));
            
            if (state == BCSP_STATE_RUNNING)
            {
                LinkLost();
            }
            sendSyncResp = TRUE;
        }
        else if (!memcmp(bchsPayload, syncRespPayload, sizeof(syncRespPayload)))
        {
            IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> RECV: SYNC RESP"), name));

            state = BCSP_STATE_CONF;
        }
        else if (!memcmp(bchsPayload, confPayload, sizeof(confPayload)))
        {
            IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> RECV: CONF"), name));

            sendConfResp = TRUE;
        }
        else if (!memcmp(bchsPayload, confRespPayload, sizeof(confRespPayload)))
        {
            IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> RECV: CONF RESP"), name));

            state = BCSP_STATE_RUNNING;
            SetEvent(inSyncEvent);
        }

        SetEvent(writePacketEvent);

        LeaveCriticalSection(&lock);
    }
    else
    {
        EnterCriticalSection(&lock);

        if (state == BCSP_STATE_RUNNING)
        {
            BOOL    changed = FALSE;

            if ((!bcspHeader->protocolType && !bcspHeader->payloadLength && !bcspHeader->seq) || (bcspHeader->protocolType &&
            bcspHeader->ack != transmitPositionUnacknowledged))
            {
                unsigned char index;

                if (transmitPositionUnacknowledged == bcspHeader->ack)
                {
                    IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> CHIP DIDN'T UNDERSTAND DATA, RESENDING"), name));

                    for (index = 0; index < 8; index++)
                    {
                        if (transmitQueue[index].sent)
                        {
                            IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> %u MARKED SENT"), name, index));
                            IFSTAT(retransmissions++);
                        }
                        transmitQueue[index].sent = FALSE;
                    }
            
                    transmitWindow = 4;
                    transmitPosition = transmitPositionUnacknowledged;
                    if (++transmitQueue[transmitPosition].retries == 20)
                    {
                        LinkLost();    
                    }
                    else
                    {
                        changed = TRUE;
                    }
                }
                else
                {
                    for (index = transmitPositionUnacknowledged; index != bcspHeader->ack; index = (++index) & 0x07)
                    {
                        if (transmitQueue[index].sent)
                        {
                            free(transmitQueue[index].buffer);
                            transmitQueue[index].present    = FALSE;
                            transmitQueue[index].sent    = FALSE;
                            transmitQueue[index].buffer    = NULL;
                            transmitPositionUnacknowledged    = (++transmitPositionUnacknowledged) & 0x07;
                            transmitWindow++;
                            ReleaseSemaphore(transmitHandle, 1, NULL);
                            changed = TRUE;
                        }
                        else
                        {
                            IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> NOT ACK (%u)"), name, index));
                            break;
                        }
                    }
                }
            }

            if (!bcspHeader->protocolType)
            {
                if (bcspHeader->protocolID == BCSP_CHANNEL_SCO)
                {
                    free(incomingSCOData.buffer);

                    incomingSCOData.buffer = malloc(bcspHeader->payloadLength);
                    if (incomingSCOData.buffer)
                    {
                        memcpy(incomingSCOData.buffer, bchsPayload, bcspHeader->payloadLength);
                        incomingSCOData.size = bcspHeader->payloadLength;
                        SetEvent(packetAvailable);
                    }
                }

                if (changed)
                {
                    SetEvent(writePacketEvent);
                }
            }
            else
            {
                if (bcspHeader->payloadLength && bcspHeader->seq == receiveSequence)
                {
                    if (bcspHeader->protocolID == BCSP_CHANNEL_BCCMD)
                    {
                        bccmdBuffer = malloc(bcspHeader->payloadLength);
                        if (bccmdBuffer)
                        {
                            bccmdSize = bcspHeader->payloadLength;
                            memcpy(bccmdBuffer, bchsPayload, bcspHeader->payloadLength);
                        }
                        receiveSequence = (++receiveSequence) & 0x07;
                        SetEvent(bccmdEvent);
                    }
                    else
                    {
                        if (!receiveQueue[receiveInsertPosition].present)
                        {
                            receiveQueue[receiveInsertPosition].buffer = malloc(bcspHeader->payloadLength);
                            if (receiveQueue[receiveInsertPosition].buffer)
                            {
                                IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> PACKET RECV"), name));

                                memcpy(receiveQueue[receiveInsertPosition].buffer, bchsPayload, bcspHeader->payloadLength);
                                receiveQueue[receiveInsertPosition].channel    = (BcspChannelT) bcspHeader->protocolID;
                                receiveQueue[receiveInsertPosition].size    = bcspHeader->payloadLength;
                                receiveQueue[receiveInsertPosition].present    = TRUE;
                                receiveInsertPosition = (++receiveInsertPosition) & 0x07;
                                SetEvent(packetAvailable);
                                IFSTAT(receiveReady++);
                            }
                            receiveSequence = (++receiveSequence) & 0x07;
                        }
                    }
                }
                else
                {
                    sendTransmitAck = TRUE;
                }

                IFSTAT(receiveTotal++);

                sendTransmitAck = TRUE;
                SetEvent(writePacketEvent);
            }
        }

        IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::DecodeBCSPPacket@%s> PACKET IN  (TIME: %u, TYPE: %u, CHL: %u, ACK: %u, SEQ: %u, SIZE: %u)"), name, GetTickCount(), bcspHeader->protocolType, bcspHeader->protocolID, bcspHeader->ack, bcspHeader->seq, bcspHeader->payloadLength));
        if (bcspHeader->payloadLength && bchsPayload)
        {
            IFDBG(DumpBuff(DEBUG_BCSP_MSG, bchsPayload, bcspHeader->payloadLength));
        }

        LeaveCriticalSection(&lock);
    }

    return ERROR_SUCCESS;
}



#ifdef BCSP_TEST_MODE
DWORD BcspCommunication::DisableTestMode()
{
    enableTestMode = FALSE;

    return ERROR_SUCCESS;
}

DWORD BcspCommunication::EnableTestMode(BcspProperbilityT* properbility)
{
    this->properbility  = *properbility;
    enableTestMode      = TRUE;

    return ERROR_SUCCESS;
}
#endif

BcspStatusT BcspCommunication::GetCommunicationStatus()
{
    BcspStatusT result;

    if (serialPortHandle != INVALID_HANDLE_VALUE)
    {
        if (state == BCSP_STATE_RUNNING)

⌨️ 快捷键说明

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