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

📄 hci_bcsp.cpp

📁 CSR蓝牙HCI层驱动源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
        else if (receiveQueue[receivePosition].present)
        {
            bcspQueueElement    = &receiveQueue[receivePosition];
            receivePosition    = (++receivePosition) & 0x07;
            incValue        = 1;
        }
        else 
        {
            HANDLE handles[] = { packetAvailable, terminateEvent };

            LeaveCriticalSection(&lock);

            switch (WaitForMultipleObjects(2, handles, FALSE, INFINITE))
            {
                case WAIT_OBJECT_0 + 0:
                {
                    break;
                }
                case WAIT_OBJECT_0 + 1:
                {
                    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadPacket@%s> SHUTING DOWN"), name));
                    
                    return ERROR_SERVICE_NOT_ACTIVE;
                }
                default:
                {
                    IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadPacket@%s> WAIT FAILED"), name));

                    return GetLastError();
                }
            }

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

            EnterCriticalSection(&lock);
        }

        if (bcspQueueElement)
        {
            if (sniffMode == 2)
            {
                if (bcspQueueElement->channel == BCSP_CHANNEL_HCI)
                {
                    HCIFileWritePacket(3, bcspQueueElement->buffer, bcspQueueElement->size);
                }
                else if (bcspQueueElement->channel == BCSP_CHANNEL_ACL)
                {
                    HCIFileWritePacket(1, bcspQueueElement->buffer, bcspQueueElement->size);
                }
            }

            *buffer     = (unsigned char*) bcspQueueElement->buffer;
            *channel    = (BcspChannelT) bcspQueueElement->channel;
            *size       = bcspQueueElement->size;
            
            bcspQueueElement->buffer    = NULL;
            bcspQueueElement->present   = FALSE;

            receivePositionAcknowledge = (receivePositionAcknowledge + incValue) & 0x07;

            found = TRUE;
        }
    }

    LeaveCriticalSection(&lock);

    return !shuttingDown ? ERROR_SUCCESS : ERROR_SERVICE_NOT_ACTIVE;
}

DWORD BcspCommunication::SetSerialPortParameter(DWORD serialTimeoutConstant, DWORD serialIntervalTimeout, DWORD serialBufferSize)
{
    this->serialTimeoutConstant = serialTimeoutConstant;
    this->serialIntervalTimeout = serialIntervalTimeout;

    if (serialBufferSize)
    {
        this->serialBufferSize = serialBufferSize;
    }

    return ERROR_SUCCESS;
}

#ifdef UNDER_CE
void BcspCommunication::SetCallback(HCI_TransportCallback callback)
{
    EnterCriticalSection(&lock);

    this->callback = callback;

    LeaveCriticalSection(&lock);
}

DWORD BcspCommunication::StartHardware()
{
    if (serialPortHandle != INVALID_HANDLE_VALUE)
    {
        return TRUE;
    }
    
    if (!callback)
    {
        return FALSE;
    }
    
    return ERROR_SUCCESS == callback(DEVICE_UP, NULL);    
}

DWORD BcspCommunication::StopHardware()
{
    if (serialPortHandle == INVALID_HANDLE_VALUE)
    {
        return TRUE;
    }
    
    if (!callback)
    {
        return FALSE;
    }

    return ERROR_SUCCESS == callback(DEVICE_DOWN, NULL);    
}
#endif

void BcspCommunication::StartSniffing(DWORD sniffMode)
{
    EnterCriticalSection(&lock);

    if (HCIFileInit(HCI_SNIFFER_DEFAULT_FILENAME, sniffMode == 1 ? 1003 : 1001) == ERROR_SUCCESS)
    {
        this->sniffMode = sniffMode;
    }    

    LeaveCriticalSection(&lock);
}

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

    HCIFileClose();

    sniffMode = 0;    

    LeaveCriticalSection(&lock);
}

DWORD BcspCommunication::WriteExecute()
{
    unsigned char   linkEstablishPacket[sizeof(BCSPHeader) + sizeof(syncPayload) + 2];
    BCSPHeader*     bcspHeader;
    unsigned char*  bchsPayload;
    unsigned char*  bchsPacket;
    DWORD           currentTimeout;
    DWORD           totalLength;
    DWORD           written;
    DWORD           totalWritten;
    unsigned char   outBuffer[4096];
    DWORD           outPacketSize;
    DWORD           index;
    DWORD           result;
    unsigned short  crc;

    EnterCriticalSection(&lock);
    while (!shuttingDown && !serialPortError)
    {
        bcspHeader = NULL;
        bchsPayload = NULL;

        switch (state)
        {
            case BCSP_STATE_SYNC:
            {
                bcspHeader    = (BCSPHeader*) &linkEstablishPacket;
                bchsPayload    = (unsigned char*) (bcspHeader + 1);

                bcspHeader->flags        = 0;
                bcspHeader->protocolID    = 1;
                bcspHeader->payloadLength    = 4;
                if (sendSyncResp)
                {
                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: SYNC RESP"), name));

                    memcpy(bchsPayload, syncRespPayload, sizeof(syncRespPayload));
                    sendSyncResp = FALSE;
                    currentTimeout = 0;
                }
                else
                {
                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: SYNC"), name));

                    memcpy(bchsPayload, syncPayload, sizeof(syncPayload));
                    currentTimeout = 250;
                    if (!--numberOfSyncs)
                    {
                    SetEvent(inSyncEvent);
                    CloseHandle(inSyncEvent);
                    inSyncEvent = INVALID_HANDLE_VALUE;    
                    serialPortError = TRUE;
                    }
                }

                break;
            }
            case BCSP_STATE_CONF:
            {
                bcspHeader    = (BCSPHeader*) &linkEstablishPacket;
                bchsPayload    = (unsigned char*) (bcspHeader + 1);

                bcspHeader->flags           = 0;
                bcspHeader->protocolID      = 1;
                bcspHeader->payloadLength   = 4;

                currentTimeout = 0;

                if (sendSyncResp)
                {
                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: SYNC RESP"), name));

                    memcpy(bchsPayload, syncRespPayload, sizeof(syncRespPayload));
                    sendSyncResp = FALSE;
                }
                else if (sendConfResp)
                {
                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: CONF RESP"), name));

                    memcpy(bchsPayload, confRespPayload, sizeof(confRespPayload));
                    sendConfResp = FALSE;
                }
                else
                {
                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: CONF"), name));

                    memcpy(bchsPayload, confPayload, sizeof(confPayload));
                    currentTimeout = 250;
                }

                break;
            }
            case BCSP_STATE_RUNNING:
            {
                if (sendConfResp)
                {
                    bcspHeader    = (BCSPHeader*) &linkEstablishPacket;
                    bchsPayload   = (unsigned char*) (bcspHeader + 1);

                    bcspHeader->flags           = 0;
                    bcspHeader->protocolID      = 1;
                    bcspHeader->payloadLength   = 4;

                    IFDBG(DebugOut(DEBUG_BCSP_SYNC, TEXT("<BcspCommunication::WriteExecute@%s> SEND: CONF RESP"), name));

                    memcpy(bchsPayload, confRespPayload, sizeof(confRespPayload));
                    sendConfResp      = FALSE;
                    currentTimeout    = 0;
                    
                    SetEvent(inSyncEvent);
                }
                else
                {
                    currentTimeout = INFINITE;

                    if (outgoingSCOData.present)
                    {
                    bcspHeader    = (BCSPHeader*) &linkEstablishPacket;
            
                    bcspHeader->protocolType     = 0;
                    bcspHeader->protocolID       = BCSP_CHANNEL_SCO;
                    bcspHeader->payloadLength    = outgoingSCOData.size;
                    bcspHeader->seq              = 0;
                    bcspHeader->ack              = 0;
                    outgoingSCOData.present      = FALSE;
                    }
                    else if (transmitQueue[transmitPosition].present && transmitWindow)
                    {
                    bcspHeader    = (BCSPHeader*) &linkEstablishPacket;
                    bchsPayload    = (unsigned char*) transmitQueue[transmitPosition].buffer;

                    bcspHeader->protocolType    = 1;
                    bcspHeader->protocolID      = transmitQueue[transmitPosition].channel;
                    bcspHeader->payloadLength   = transmitQueue[transmitPosition].size;
                    bcspHeader->seq             = transmitPosition;
                    bcspHeader->ack             = receiveSequence;
                    
                    transmitQueue[transmitPosition].transmittedTime = GetTickCount();
                    transmitQueue[transmitPosition].sent            = TRUE;
                    if (transmitPositionUnacknowledged == transmitPosition)
                    {
                        currentTimeout = transmitTimeout;
                    }

                    transmitWindow--;
                    transmitPosition = (++transmitPosition) & 0x07;
                    sendTransmitAck = FALSE;
                    }
                    else if (sendTransmitAck)
                    {
                    bcspHeader    = (BCSPHeader*) &linkEstablishPacket;

                    bcspHeader->protocolType     = 0;
                    bcspHeader->protocolID       = 0; 
                    bcspHeader->payloadLength    = 0;
                    bcspHeader->seq              = 0;
                    bcspHeader->ack              = receiveSequence;
                    sendTransmitAck = FALSE;
                    }
                }
                break;
            }
        }

        if (serialPortError)
        {
            break;
        }

        if (bcspHeader)
        {
            totalLength     = sizeof(BCSPHeader) + bcspHeader->payloadLength + (useCrc ? 2 : 0);
            outPacketSize   = 0;
            totalWritten    = 0;
            crc             = 0xFFFF;
            bchsPacket      = (unsigned char*) bcspHeader;

            bcspHeader->crcPresent = (useCrc ? 1 : 0);    
            bcspHeader->SetChecksum();

#ifdef BCSP_TEST_MODE
            if (enableTestMode)
            {
                if (rand() < properbility.headerCrcErrorProperbility)
                {
                    bcspHeader->checksum++;
                }
            }
#endif
            if (sniffMode == 1)
            {
                unsigned char* tempBufferSniff = (unsigned char*) LocalAlloc(LPTR, totalLength);
                if (tempBufferSniff)
                {
                    unsigned short    sniffCrc = 0xFFFF;

                    memcpy(tempBufferSniff, bcspHeader, sizeof(bcspHeader));
                    memcpy(&tempBufferSniff[sizeof(bcspHeader)], bchsPayload, bcspHeader->payloadLength);

                    if (useCrc)
                    {
                        DWORD index;

                        for (index = 0; index < totalLength - 2; index++)
                        {
                            sniffCrc = (sniffCrc >> 8) ^ crc_table[(sniffCrc & 255) ^ tempBufferSniff[index]];
                        }
                        sniffCrc = ((sniffCrc & 0x00ff) << 8) | (sniffCrc >> 8);
                        sniffCrc = ((sniffCrc & 0x0f0f) << 4) | ((sniffCrc & 0xf0f0) >> 4);

⌨️ 快捷键说明

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