我一直在尝试使用Winsock API在Windows上进行蓝牙编程,并且遇到了如何确定主机上是否没有蓝牙或扫描设置是否为空的问题。
所以程序非常简单,启动Winsock,调用WSALookupServiceBegin,然后在扫描设备时调用ServiceNext和ServiceEnd。开发机器有一个蓝牙无线电,驱动程序是Microsoft BT Stack,我可以通过Windows使用Devices向导找到设备。
问题是在调用WSALookupServiceBegin时,在两种情况下返回WSASERVICE_NOT_FOUND:
所以我的问题是:
提前致谢!
附加代码:
int main(int argc, char **argv)
{
WSADATA wsd;
BOOL retVal;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
printf("WSAStartup() failed with error code %ld\n", WSAGetLastError());
else
printf("WSAStartup() is OK!\n");
scan();
if (WSACleanup() == 0)
printf("WSACleanup() is OK!\n");
else
printf("WSACleanup() failed with error code %ld\n", WSAGetLastError());
return 0;
}
并扫描();
void scan()
{
WSAQUERYSET queryset;
memset(&queryset, 0, sizeof(WSAQUERYSET));
queryset.dwSize = sizeof(WSAQUERYSET);
queryset.dwNameSpace = NS_BTH;
// begin query
HANDLE hDeviceLookup;
if (WSALookupServiceBegin(&queryset, LUP_FLUSHCACHE | LUP_CONTAINERS, &hDeviceLookup)) {
int last_error = WSAGetLastError();
wcout << getWinErrorMessage(last_error) << endl;
return;
}
int bufSize = 0x2000;
void* buf = malloc(bufSize);
int result = -1;
while (result == -1) {
memset(buf, 0, bufSize);
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)buf;
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
DWORD size = bufSize;
if (hDeviceLookup == NULL) {
break;
}
if (WSALookupServiceNext(hDeviceLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RETURN_BLOB, &size, pwsaResults)) {
int last_error = WSAGetLastError();
switch (last_error) {
case WSAENOMORE:
case WSA_E_NO_MORE:
result = 2;
break;
default:
wcout << getWinErrorMessage(last_error) << endl;
result = 3;
}
WSALookupServiceEnd(hDeviceLookup);
hDeviceLookup = NULL;
break;
}
BTH_DEVICE_INFO *p_inqRes = (BTH_DEVICE_INFO *)pwsaResults->lpBlob->pBlobData;
// get device name
WCHAR name[256];
BOOL bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
wcout << pwsaResults->lpszServiceInstanceName << endl;
int deviceClass = p_inqRes->classOfDevice;
BTH_ADDR deviceAddr;
deviceAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
}
if (buf != NULL) {
free(buf);
}
if (hDeviceLookup != NULL) {
WSALookupServiceEnd(hDeviceLookup);
hDeviceLookup = NULL;
}
}
答案 0 :(得分:1)
我使用以下代码确定是否可以使用Windows蓝牙堆栈以及是否存在所需的硬件。
CanUseBluetooth()只是检查是否有一个了解蓝牙协议的winsock提供商。如果是这种情况,则安装堆栈。
static bool CanUseBluetooth(
bool throwOnFailure)
{
static const CAddressTypeBluetooth addressType;
SOCKET s = ::socket(addressType.Family(), SOCK_STREAM, addressType.Protocol());
const bool canUseBluetooth = (s != INVALID_SOCKET);
const DWORD lastError = ::GetLastError();
::closesocket(s);
if (!canUseBluetooth && throwOnFailure)
{
throw CWin32Exception(_T("CUsesXPBluetooth::CanUseBluetooth()"), lastError);
}
return canUseBluetooth;
}
HarwareActive()检查我们是否可以绑定到通配符地址,如果我们可以这样做,那么我们有一些使用Windows堆栈的活动蓝牙硬件。
static bool HardwareActive(
bool throwOnFailure)
{
static const CAddressTypeBluetooth addressType;
SOCKET s = ::socket(addressType.Family(), SOCK_STREAM, addressType.Protocol());
if (s == INVALID_SOCKET)
{
const DWORD lastError = ::GetLastError();
::closesocket(s);
throw CWin32Exception(_T("CUsesXPBluetooth::HardwareActive() - CanUseBluetooth"), lastError);
}
bool hardwareActive = true;
static const IAddress &address = addressType.WildcardAddress();
if (SOCKET_ERROR == ::bind(s, &address.AsSockAddr(), address.Size()))
{
hardwareActive = false;
}
const DWORD lastError = ::GetLastError();
::closesocket(s);
if (!hardwareActive && throwOnFailure)
{
throw CWin32Exception(_T("CUsesXPBluetooth::HardwareActive()"), lastError);
}
return hardwareActive;
}