📄 hcisdio.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 + -