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

📄 hcisdio.cpp

📁 WINCE5.0下
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include "bthsdio.h"

#if defined (SDK_BUILD) && defined (BT_USE_CELOG)
#define CELOGSDK_FILELOG    L"sdio"
#define CELOGSDK_DEFINE     1

#include "../../../../../../../../private/osinternal/pbtools/privdbg/celog_sdk.h"
#endif

#define SCO_DEFAULT_SAMPLE_SIZE             8
#define SCO_DEFAULT_WRITE_LOW_NUM_PACKETS   2
#define SCO_DEFAULT_WRITE_HIGH_NUM_PACKETS  4
#define SCO_DEFAULT_PACKET_SIZE             51


SDIO_GLOBALS    g_Data;
CSdioDevice*    g_pSdioDevice;


DECLARE_DEBUG_VARS();

BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) 
{
    BOOL fRetVal = TRUE;
    
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls((HMODULE) hinstDLL);

            DebugInit();
            if (!SDInitializeCardLib()) {
                fRetVal = FALSE;
                break;
            }

            g_pSdioDevice = new CSdioDevice;
            if (! g_pSdioDevice) {
                fRetVal = FALSE;
                break;
            }

            memset(&g_Data, 0, sizeof(SDIO_GLOBALS));
            
            break;
            
        case DLL_PROCESS_DETACH:
            delete g_pSdioDevice;
            SDDeinitializeCardLib();
            DebugDeInit();           
            
            break;
    }

    return fRetVal;
}


/*

This function is called from HCI to read transport-specific paramters.

*/
int HCI_ReadHciParameters(HCI_PARAMETERS *pParms)
{
    HKEY hk;
    int fRetVal = TRUE;

    if (pParms->uiSize < sizeof(*pParms)) {
        fRetVal = FALSE;
        goto exit;
    }

    memset(pParms, 0, sizeof(*pParms));

    pParms->uiSize                  = sizeof(*pParms);
    pParms->fInterfaceVersion       = HCI_INTERFACE_VERSION_1_1;
    pParms->iMaxSizeRead            = PACKET_SIZE_R;
    pParms->iMaxSizeWrite           = PACKET_SIZE_W;
    pParms->iWriteBufferHeader      = SDIO_HEADER_SIZE;
    pParms->iReadBufferHeader       = SDIO_HEADER_SIZE;
    pParms->fHardwareVersion        = HCI_HARDWARE_VERSION_V_1_0_B;
    pParms->uiWriteTimeout          = HCI_DEFAULT_WRITE_TIMEOUT;
    pParms->uiDriftFactor           = HCI_DEFAULT_DRIFT;
    pParms->uiFlags                 = 0;
    pParms->iScoWriteLowNumPackets  = SCO_DEFAULT_WRITE_LOW_NUM_PACKETS;
    pParms->iScoWriteNumPackets     = SCO_DEFAULT_WRITE_HIGH_NUM_PACKETS;
    pParms->iScoWritePacketSize     = SCO_DEFAULT_PACKET_SIZE;
    pParms->iScoSampleSize          = SCO_DEFAULT_SAMPLE_SIZE;

    if (RegOpenKeyEx (HKEY_BASE, L"Software\\Microsoft\\Bluetooth\\hci", 0, KEY_READ, &hk) == ERROR_SUCCESS) {
        DWORD dwType = 0;

        DWORD dwData = 0;
        DWORD dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"ResetDelay", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->uiResetDelay = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"SpecV10a", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->fHardwareVersion = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"SpecV11", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->fHardwareVersion = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"WriteTimeout", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->uiWriteTimeout = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"Flags", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->uiFlags = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx(hk, L"Drift", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->uiDriftFactor = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx (hk, L"ScoWriteLowNumPackets", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->iScoWriteLowNumPackets = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx (hk, L"ScoWriteNumPackets", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->iScoWriteNumPackets = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx (hk, L"ScoWritePacketSize", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->iScoWritePacketSize = dwData;

        dwData = 0;
        dwSize = sizeof(dwData);
        if ((RegQueryValueEx (hk, L"ScoSampleSize", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
            pParms->iScoSampleSize = dwData;

        RegCloseKey(hk);        
    }

exit:
    return fRetVal;
}


/*

This function is called from HCI to start the BT hardware.  In the case of SDIO
it just checks if we are attached.

*/
int HCI_StartHardware(void)
{
    int fRetVal = TRUE;

    IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_StartHardware\n"));

    g_Data.fStopHardware = FALSE;

    if (! g_pSdioDevice->IsAttached()) {
        IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_StartHardware - SDIO card is not attached\n"));
        fRetVal = FALSE;
        goto exit;
    }

    if (! g_Data.pfnHCICallback) {
        IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_StartHardware (not registered)\n"));
        fRetVal = FALSE;
        goto exit;
    }

    fRetVal = (ERROR_SUCCESS == g_Data.pfnHCICallback(DEVICE_UP, NULL));

exit:
    return fRetVal;    
}


/*

This function is called from HCI to stop the BT hardware.

*/
int HCI_StopHardware(void)
{
    int fRetVal = TRUE;

    IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_StopHardware\n"));

    g_Data.fStopHardware = TRUE;

    if (! g_Data.pfnHCICallback) {
        IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_StopHardware (not registered)\n"));
        fRetVal = FALSE;
        goto exit;
    }

    fRetVal = (ERROR_SUCCESS == g_Data.pfnHCICallback(DEVICE_DOWN, NULL));
     
exit:
    return fRetVal;    
}


/*

This function is called from HCI to set the callback for indicating transport events.

*/
int HCI_SetCallback(HCI_TransportCallback pfCallback)
{
    IFDBG(DebugOut (DEBUG_HCI_INIT, L"[SDIO] HCI_SetCallback\n"));

    g_Data.pfnHCICallback = pfCallback;

    return ERROR_SUCCESS;   
}


/*

This function is called from HCI to open the transport connection.  Once this function returns
the transport is ready to read/write data.

*/
int HCI_OpenConnection(void)
{
    HKEY hk = NULL;
    int fRetVal = TRUE;

    IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_OpenConnection\n"));

    if (! g_pSdioDevice->OpenConnection()) {
        IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_OpenConnection - Error opening connection.\n"));
        fRetVal = FALSE;
        goto exit;        
    }

#if defined (BT_USE_CELOG)
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_BASE, L"software\\microsoft\\bluetooth\\debug", 0, KEY_READ, &hk)) {
        DWORD dwType;
        DWORD dw;
        DWORD dwSize = sizeof(dw);

        if ((ERROR_SUCCESS == RegQueryValueEx(hk, L"celog", NULL, &dwType, (LPBYTE)&dw, &dwSize)) &&
            (dwType == REG_DWORD) && (dwSize == sizeof(dw)) && dw)
            g_Data.fCeLog = IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL);

        RegCloseKey(hk);
    }

    if (g_Data.fCeLog) {
#if defined (SDK_BUILD)
        CELOGSDK_START ();
#endif
        BTH_CELOG_START_DATA sd;

        sd.eTransport = SDIO;            
        GetLocalTime(&sd.st);
        wsprintf(sd.szDriverString, L"SDIO Driver v. 0x%08x", HCI_INTERFACE_VERSION_1_1);

        CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &sd, sizeof(sd), 0, CELZONE_ALWAYSON, CELOG_FLAG_START);
    }
#endif
    
exit:
    return fRetVal;    
}


/*

This function is called from HCI to close the transport connection.

*/
void HCI_CloseConnection(void)
{
    IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_CloseConnection\n"));

    g_pSdioDevice->CloseConnection();

#if defined (BT_USE_CELOG)
    if (g_Data.fCeLog) {
        BTH_CELOG_STOP_DATA sd;
        GetLocalTime(&sd.st);

        CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &sd, sizeof(sd), 0, CELZONE_ALWAYSON, CELOG_FLAG_STOP);

        g_Data.fCeLog = FALSE;
    }
#endif
}


/*

This function is called from HCI to read data from the BT card.  This function will block
until data is read.

*/
int HCI_ReadPacket(HCI_TYPE *peType, BD_BUFFER *pBuff)
{
    BOOL fRetVal = TRUE;
    unsigned int iRead = 0;
    BYTE bType = 0;

    IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_ReadPacket\n"));

    ASSERT(pBuff->cSize == (PACKET_SIZE_R + SDIO_HEADER_SIZE));

    if (! g_pSdioDevice->ReadPacket(&pBuff->pBuffer[pBuff->cStart], &iRead, &bType)) {
        IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_ReadPacket - Error reading packet from SDIO device.\n"));
        fRetVal = FALSE;
        goto exit;
    }

    ASSERT(iRead <= PACKET_SIZE_R);

    pBuff->cEnd = pBuff->cStart + iRead;

    *peType = (HCI_TYPE) bType; // SDIO type maps to HCI_TYPE
    
    if ((*peType != DATA_PACKET_ACL) &&
        (*peType != DATA_PACKET_SCO) &&
        (*peType != EVENT_PACKET)) {
        IFDBG(DebugOut (DEBUG_HCI_DUMP, L"[SDIO] HCI_ReadPacket - Received an unknown packet type.\n"));    
        fRetVal = FALSE;
        ASSERT(FALSE);
        goto exit;
    }

    IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[SDIO] Packet received:\n"));
    IFDBG(DumpBuff (DEBUG_HCI_TRANSPORT, pBuff->pBuffer, pBuff->cEnd));

exit:    
    return fRetVal;    
}


/*

This function is called from HCI to write data down to the BT card.

*/
int HCI_WritePacket(HCI_TYPE eType, BD_BUFFER *pBuff)
{
    int fRetVal = TRUE;
    unsigned long ulWrite = BufferTotal(pBuff);
    SD_TRANSPORT_HEADER header;

    IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[SDIO] HCI_WritePacket type 0x%02x len %d\n", eType, ulWrite));
    IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, ulWrite));
    
    ASSERT(ulWrite <= PACKET_SIZE_W);
    ASSERT((eType > 0) && (eType < 4));
    ASSERT(sizeof(header) == SDIO_HEADER_SIZE);

    // Size and Type are stored in four bytes before cStart
    // SDIO service ID maps directly to HCI_TYPE
    header.u.AsULONG = ulWrite + SDIO_HEADER_SIZE;
    header.u.AsUCHAR.ServiceID = eType;
    memcpy(pBuff->pBuffer, &header, sizeof(header));

    return g_pSdioDevice->WritePacket(pBuff->pBuffer, (ulWrite + SDIO_HEADER_SIZE));
}


⌨️ 快捷键说明

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