Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

An application can create a query for discovering remote Bluetooth devices within range, by using the following standard Winsock programming elements:

Note:
For clarity, information about error handling has been omitted from this.

The sample that ships with Windows Mobile contains source code for discovering Bluetooth devices by using Winsock.

Procedures

To perform device discovery and retrieve the address of a remote Bluetooth device
  1. Prepare the caller application by providing Winsock-related data such as version and implementation details. This data can be retrieved by calling the WSAStartupfunction as the following example shows.

    Copy Code
    WSADATA wsd;
    WSAStartup (MAKEWORD(1,0), &wsd);
    
  2. Create and initialize a WSAQUERYSETvariable to specify search parameters. Set the dwNameSpacemember to NS_BTH to restrict the query to Bluetooth devices.

    The following code example shows the values to set in WSAQUERYSET.

    Copy Code
    WSAQUERYSET wsaq;
    ZeroMemory(&wsaq, sizeof(wsaq));
    wsaq.dwSize = sizeof(wsaq);
    wsaq.dwNameSpace = NS_BTH;
    wsaq.lpcsaBuffer = NULL;
    
  3. To start an inquiry, call the WSALookupServiceBeginfunction.

    The following code example shows how to call WSALookupServiceBeginto perform a device inquiry by passing the WSAQUERYSETvariable, created in step 1.

    Copy Code
    int iRet = WSALookupServiceBegin (&wsaq, LUP_CONTAINERS,
    &hLookup);
    

    In the preceding example, LUP_CONTAINERS is passed in the dwFlagsparameter. This enables Service Discovery Protocol (SDP) to search for other Bluetooth devices within range.

    Note:
    Passing zero(0) in the dwFlagsparameter performs a service search. For more information about SDP search, see Querying Service Capability on Remote Bluetooth Devices.

    The WSALookupServiceBeginfunction returns a handle in the hLookupparameter.

  4. To enumerate devices that were scanned in the previous call to WSALookupServiceBegin, call the WSALookupServiceNextfunction. This function returns a pointer to a buffer that stores the result set in a WSAQUERYSETstructure.

    1. Configure a WSAQUERYSETstructure to store device data returned by WSALookupServiceNext. The following code shows how to configure this structure.

      Copy Code
      CHAR buf[4096];
      LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
      ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
      pwsaResults->dwSize = sizeof(WSAQUERYSET);
      pwsaResults->dwNameSpace = NS_BTH;
      pwsaResults->lpBlob = NULL;
      
    2. Call WSALookupServiceNextby passing the handle returned by WSALookupServiceBeginin the hLookUpparameter. To improve performance, the call to WSALookupServiceBeginreturns only the addresses of the devices, and these addresses are is stored in memory. To retrieve the name and address of the device, pass LUP_RETURN_NAME | LUP_RETURN_ADDR in the dwFlagsparameter. The following code shows how to call WSALookupServiceNext.

      Copy Code
      DWORD dwSize  = sizeof(buf);
      int iRet = WSALookupServiceNext (hLookup, LUP_RETURN_NAME |
      LUP_RETURN_ADDR, &dwSize, pwsaResults)
      

    To enumerate the devices, the caller application can loop through the list of devices, by calling WSALookupServiceNextrepetitively.

  5. To terminate the device discovery process, call the WSALookupServiceEndfunction. This function releases the lookup handle created by WSALookupServiceBegin.

    The following code shows how to call WSALookupServiceEnd.

    Copy Code
    WSALookupServiceEnd(hLookup);
    
  6. To terminate the use of Winsock services, call the WSACleanupfunction. There must be a call to WSACleanupfor every successful call to WSAStartupmade by an application.

The following code example performs a device inquiry displays the device name in a user interface.

Copy Code
//------------------------------------------------------------------------
// Function: PerformInquiry
// Purpose: Performs a device inquiry displays the device name in a
user interface.
// Note: This function does not include a call to WSAStartup as
described 
//	 in the procedure.
//	 This sample has not been tested and is not intended for
production use.
//------------------------------------------------------------------------
#define MAX_NAME 248
static BOOL PerformInquiry() 
{
  WSAQUERYSET wsaq;
  HANDLE hLookup;
  union {
	CHAR buf[5000];
	double __unused; // ensure proper alignment
  };
  LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
  DWORD dwSize  = sizeof(buf);
  BOOL bHaveName;
  ZeroMemory(&wsaq, sizeof(wsaq));
  wsaq.dwSize = sizeof(wsaq);
  wsaq.dwNameSpace = NS_BTH;
  wsaq.lpcsaBuffer = NULL;
  if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq,
LUP_CONTAINERS, &hLookup))
  {
	wprintf(L"WSALookupServiceBegin failed %d\r\n",
GetLastError());
	return FALSE;
  }
  ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
  pwsaResults->dwSize = sizeof(WSAQUERYSET);
  pwsaResults->dwNameSpace = NS_BTH;
  pwsaResults->lpBlob = NULL;
  while (ERROR_SUCCESS == WSALookupServiceNext (hLookup,
LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
  {
	ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
	BT_ADDR b = ((SOCKADDR_BTH
*)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
	bHaveName = pwsaResults->lpszServiceInstanceName &&
*(pwsaResults->lpszServiceInstanceName);
	wprintf (L"%s%s%04x%08x%s\n", bHaveName ?
pwsaResults->lpszServiceInstanceName : L"", 
	bHaveName ? L"(" : L"", GET_NAP(b), GET_SAP(b), bHaveName ?
L")" : L"");
  }
  WSALookupServiceEnd(hLookup);
  return TRUE;
}

See Also