Windows蓝牙WSALookupServiceBegin如果范围内没有设备,则返回WSASERVICE_NOT_FOUND(10108)?

时间:2013-11-04 06:44:20

标签: winapi bluetooth winsock winsock2

我一直在尝试使用Winsock API在Windows上进行蓝牙编程,并且遇到了如何确定主机上是否没有蓝牙或扫描设置是否为空的问题。

所以程序非常简单,启动Winsock,调用WSALookupServiceBegin,然后在扫描设备时调用ServiceNext和ServiceEnd。开发机器有一个蓝牙无线电,驱动程序是Microsoft BT Stack,我可以通过Windows使用Devices向导找到设备。

问题是在调用WSALookupServiceBegin时,在两种情况下返回WSASERVICE_NOT_FOUND:

  1. 主机上没有适配器
  2. 扫描范围内没有蓝牙设备(即空扫描设置)
  3. 所以我的问题是:

    1. 这是预期的吗?
    2. 如何进一步确定发生了哪一个?
    3. 提前致谢!

      附加代码:

      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;
          }
      }
      

1 个答案:

答案 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;
}