我一直在使用Winsock API在Windows上尝试蓝牙编程,并在如何确定主机上是否没有蓝牙或扫描集是否为空方面遇到了一个问题。
所以程序非常简单,启动Winsock,调用WSALookupServiceBegin,然后在我们扫描设备时调用ServiceNext和ServiceEnd。开发机器有蓝牙收音机,驱动程序是Microsoft BT Stack,我可以通过Windows找到使用设备向导的设备。
问题是,在调用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;
}
}
发布于 2013-11-27 11:07:01
我使用以下代码来确定是否可以使用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;
}
https://stackoverflow.com/questions/19762847
复制相似问题