< Bluetooth Device Query Example | Winsock2 Supported Protocols Main | Querying Bluetooth Device Example >


 

 

Winsock 2: Other Supported Protocols 4 Part 13

 

 

What do we have in this chapter 4 part 13?

  1. Querying Service Capability on Remote Bluetooth Devices

  2. Bluetooth Querying Remote Device Program Example

 

Querying Service Capability on Remote Bluetooth Devices

 

An application can query for services on a remote Bluetooth device by using the following standard Winsock programming elements:

 

1.      WSAQUERYSET structure.

2.      WSALookupServiceBegin() function.

3.      WSALookupServiceNext() function.

4.      WSALookupServiceEnd() function.

 

Before you query service capability on remote Bluetooth devices, you must have the address of the remote Bluetooth device information to query, as a BT_ADDR type, which is defined in Ws2bth.h as:

 

typedef ULONGLONG bt_addr, *pbt_addr, BT_ADDR, *PBT_ADDR;

 

To perform a service query on a remote Bluetooth device:

 

1.      To prepare the caller application by providing Winsock-related data such as version and implementation details. This data can be retrieved by calling the WSAStartup function as the following example shows.

 

WSADATA wsd;

WSAStartup (MAKEWORD(2,2), &wsd);

 

2.      Specify the search parameters by configuring the WSAQUERYSET structure. The following code example shows the values in this structure.

 

WSAQUERYSET wsaq;

memset (&wsaq, 0, sizeof(wsaq));

wsaq.dwSize      = sizeof(wsaq);

wsaq.dwNameSpace = NS_BTH;

wsaq.lpBlob      = &blob;

wsaq.lpcsaBuffer = &csai;

 

Restrict the search to Bluetooth queries by setting the dwNameSpace member to NS_BTH.

 

3.      To initiate the search process, call the WSALookupServiceBegin() function. Specify the search criteria by passing the WSAQUERYSET variable, created in step 1, in the pQuerySet parameter. The following code example show how to call WSALookupServiceBegin().

 

int iRet = WSALookupServiceBegin (&wsaq, 0, &hLookup);

 

Pass zero (0) in the dwFlags parameter to perform a service query on the remote device. WSALookupServiceBegin() returns a handle in the hLookup parameter. Passing LUP_CONTAINERS in the dwFlags parameter, sets up WSALookupServiceBegin() to perform a device inquiry.

 

4.      To retrieve data about the services found on the remote device, call the WSALookupServiceNext() function by using the handle returned by WSALookupServiceBegin() as shown in the following code example.

 

CHAR buf[5000];

LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;

DWORD dwSize  = sizeof(buf);

memset(pwsaResults,0,sizeof(WSAQUERYSET));

pwsaResults->dwSize      = sizeof(WSAQUERYSET);

pwsaResults->dwNameSpace = NS_BTH;

pwsaResults->lpBlob      = NULL;

iRet = WSALookupServiceNext (hLookup, 0, &dwSize, pwsaResults);

 

WSALookupServiceNext() returns a pointer to WSAQUERYSET that references the service data in the lpBlob member. This member points to a BLOB (Windows Sockets) structure, which contains the binary data that is returned by WSALookupServiceNext() all at once. Windows Embedded CE provides COM interfaces that you can use to parse service data.

 

5.      To terminate the service discovery process, call the WSALookupServiceEnd() function. This function releases the lookup handle created by WSALookupServiceBegin(). The following code example shows how to call WSALookupServiceEnd().

 

WSALookupServiceEnd(hLookup);

 

6.      To terminate the use of Winsock services, call the WSACleanup() function. There must be a call to WSACleanup() for every successful call to WSAStartup() made by an application.

 

 

 

 

Bluetooth Querying Remote Device Program Example

 

The following code example shows queries a remote Bluetooth device for the supported services. The remote device is specified by passing a pointer to the address of the device stored in the in a BT_ADDR type, as defined in Ws2bth.h:

 

Bluetooth Querying Remote Device Program Example: Creating a new empty Win32 console mode application and adding the project/solution name.

 

Add the following source code.

 

// Link to ws2_32.lib

#include <winsock2.h>

#include <Ws2bth.h>

// Link to Bthprops.lib

#include <BluetoothAPIs.h>

#include <stdio.h>

 

// callback for BluetoothSdpEnumAttributes()

BOOL __stdcall callback(ULONG uAttribId, LPBYTE pValueStream, ULONG cbStreamSize, LPVOID pvParam)

{

            SDP_ELEMENT_DATA element;

            // Just a verification, uncomment to see the output!!!

            //printf("Callback() uAttribId: %ul\n", uAttribId);

            //printf("Callback() pValueStream: %d\n ", pValueStream);

            //printf("Callback() cbStreamSize: %ul\n ", cbStreamSize);

 

            if (BluetoothSdpGetElementData(pValueStream,  cbStreamSize, &element) != ERROR_SUCCESS)

            {

                        // Just a verification

                        // printf("BluetoothSdpGetElementData() failed with error code %ld\n", WSAGetLastError());

                        return FALSE;

            }

            else

            {

                        // Just a verification

                        // printf("BluetoothSdpGetElementData() is OK!\n");

                        return TRUE;

            }

}

 

int main(int argc, char** argv)

{

            WSADATA m_data;

            SOCKET s;

            WSAPROTOCOL_INFO protocolInfo;

            int protocolInfoSize;

            WSAQUERYSET querySet, *pResults, querySet2;

            HANDLE hLookup, hLookup2;

            int result;

            static int i;

            BYTE buffer[1000];

            BYTE buffer1[2000];

            DWORD bufferLength, flags, addressSize, bufferLength1;

            CSADDR_INFO *pCSAddr;

            BTH_DEVICE_INFO *pDeviceInfo;

            char addressAsString[2000];

            BLOB *pBlob;

            GUID protocol;

 

            // Load the winsock2 library

            if (WSAStartup(MAKEWORD(2,2), &m_data) == 0)

            {

               printf("WSAStartup() should be fine!\n");

 

               // Create a blutooth socket

               s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);

               if (s == INVALID_SOCKET)

               {

                           printf("Failed to get bluetooth socket with error code %ld\n", WSAGetLastError());

                           return 1;

               }

               else

                           printf("socket() is OK!\n");

 

               protocolInfoSize = sizeof(protocolInfo);

 

               // Get the bluetooth device info using getsockopt()

               if (getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &protocolInfoSize) != 0)

               {

                           printf("getsockopt(SO_PROTOCOL_INFO) failed with error code %ld\n", WSAGetLastError());

                           return 1;

               }

               else

                           printf("getsockopt(SO_PROTOCOL_INFO) is OK!\n");

 

               // Query set criteria

               memset(&querySet, 0, sizeof(querySet));

               querySet.dwSize = sizeof(querySet);

               querySet.dwNameSpace = NS_BTH;

 

               // Set the flags for query

               flags = LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_FLUSHCACHE |

                          LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE;

 

 

 

 

               // Start a device in range query...

               result = WSALookupServiceBegin(&querySet, flags, &hLookup);

 

               // If OK

               if (result == 0)

               {

                           printf("          WSALookupServiceBegin() is OK!\n");

                           i = 0;

 

                           while (result == 0)

                           {

                                       bufferLength = sizeof(buffer);

                                       pResults = (WSAQUERYSET *)&buffer;

 

                                       // Next query...

                                       result = WSALookupServiceNext(hLookup, flags, &bufferLength, pResults);

                                       if (result != 0)

                                       {

                                                   printf("          WSALookupServiceNext() failed with error code %ld\n", WSAGetLastError());

                                       }

                                       else

                                       {

                                                   // Get the device info, name, address etc

                                                   printf("          WSALookupServiceNext() is OK!\n");

                                                   printf("          The service instance name is %S\n", pResults->lpszServiceInstanceName);

                                                   pCSAddr = (CSADDR_INFO *)pResults->lpcsaBuffer;

                                                   pDeviceInfo = (BTH_DEVICE_INFO *)pResults->lpBlob;

                                                   memset(&querySet2, 0, sizeof(querySet2));

                                                   querySet2.dwSize = sizeof(querySet2);

                                                   protocol = L2CAP_PROTOCOL_UUID;

                                                   querySet2.lpServiceClassId = &protocol;

                                                   querySet2.dwNameSpace = NS_BTH;

 

                                                   addressSize = sizeof(addressAsString);

 

                                                   // Print the local bluetooth device address...

                                                   if (WSAAddressToString(pCSAddr->LocalAddr.lpSockaddr, pCSAddr->LocalAddr.iSockaddrLength,

                                                                     &protocolInfo, (LPWSTR)addressAsString, &addressSize) == 0)

                                                   {

                                                               printf("          WSAAddressToString() for local address is fine!\n");

                                                               printf("          The local address: %S\n", addressAsString);

                                                   }

                                                   else

                                                               printf("          WSAAddressToString() for local address failed with error code %ld\n", WSAGetLastError());

 

                                                   addressSize = sizeof(addressAsString);

 

                                                   // Print the remote bluetooth device address...

                                                   if (WSAAddressToString(pCSAddr->RemoteAddr.lpSockaddr, pCSAddr->RemoteAddr.iSockaddrLength,

                                                                &protocolInfo, (LPWSTR)addressAsString, &addressSize) == 0)

                                                   {

                                                               printf("          WSAAddressToString() for remote address is fine!\n");

                                                               printf("          The remote device address: %S\n", addressAsString);

                                                   }

                                                   else

                                                               printf("          WSAAddressToString() for remote address failed with error code %ld\n", WSAGetLastError());

 

                                                   // Prepare for service query set

                                                   querySet2.lpszContext = (LPWSTR)addressAsString;

 

                                                   flags = LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_TYPE |

                                                                                             LUP_RETURN_ADDR | LUP_RETURN_BLOB | LUP_RETURN_COMMENT;

 

                                                   // Start service query

                                                   result = WSALookupServiceBegin(&querySet2, flags, &hLookup2);

                                                   if (result == 0)

                                                   {

                                                               printf("          WSALookupServiceBegin() is OK!\n");

                                                               while (result == 0)

                                                               {

                                                                           bufferLength1 = sizeof(buffer1);

                                                                           pResults = (WSAQUERYSET *)&buffer1;

 

                                                                           // Next service query

                                                                           result = WSALookupServiceNext(hLookup2, flags, &bufferLength1, pResults);

 

                                                                           if(result == 0)

                                                                           {

                                                                                       // Populate the service info

                                                                                       printf("          WSALookupServiceNext() is OK!\n");

                                                                                       printf("          WSALookupServiceNext() - service instance name: %S\n",

                                                                                                                            pResults->lpszServiceInstanceName);

                                                                                       printf("          WSALookupServiceNext() - comment (if any): %s\n", pResults->lpszComment);

                                                                                       pCSAddr = (CSADDR_INFO *)pResults->lpcsaBuffer;

 

                                                                                       // Extract the sdp info

                                                                                       if (pResults->lpBlob)

                                                                                       {

                                                                                                   pBlob = (BLOB*)pResults->lpBlob;

                                                                                                   if (!BluetoothSdpEnumAttributes(pBlob->pBlobData, pBlob->cbSize, callback, 0))

                                                                                                   {

                                                                                                               printf("BluetoothSdpEnumAttributes() failed with error code %ld\n", WSAGetLastError());

                                                                                                   }

                                                                                                   else

                                                                                                   {

                                                                                                               printf("BluetoothSdpEnumAttributes() #%d is OK!\n", i++);

                                                                                                   }

                                                                                       }

                                                                           }

                                                                           else

                                                                           {

                                                                                       printf("          WSALookupServiceNext() failed with error code %ld\n", WSAGetLastError());

                                                                                       printf("          Error code = 11011 ~ WSA_E_NO_MORE ~ No more device!\n");

                                                                           }

                                                               }

 

                                                               // Close the handle to service query

                                                               if(WSALookupServiceEnd(hLookup2) == 0)

                                                                           printf("WSALookupServiceEnd(hLookup2) is fine!\n", WSAGetLastError());

                                                               else

                                                                           printf("WSALookupServiceEnd(hLookup2) failed with error code %ld\n");

                                                   }

                                                   else

                                                               printf("WSALookupServiceBegin() failed with error code %ld\n", WSAGetLastError());

                                       }

                           }

 

                           // Close handle to the device query

                           if(WSALookupServiceEnd(hLookup) == 0)

                                       printf("WSALookupServiceEnd(hLookup) is fine!\n", WSAGetLastError());

                           else

                                       printf("WSALookupServiceEnd(hLookup) failed with error code %ld\n");

}

else

{

            printf("WSALookupServiceBegin() failed with error code %ld\n", WSAGetLastError());

}// end WSALookupServiceBegin()

 

// Cleanup the winsock library startup

if(WSACleanup() == 0)

printf("WSACleanup() pretty fine!\n");

else

printf("WSACleanup() failed with error code %ld\n", WSAGetLastError());

} // end WSAStartup()

return 0;

}

 

Build and run the project. The following screenshot shows a sample output.

 

----------------------------------------------------------------------------------

Bluetooth Querying Remote Device Program Example: A sample program output

 

The following sample output is the full version of the previous screenshot.

 

WSAStartup() should be fine!

socket() is OK!

getsockopt(SO_PROTOCOL_INFO) is OK!

        WSALookupServiceBegin() is OK!

        WSALookupServiceNext() is OK!

        The service instance name is nazuri

        WSAAddressToString() for local address is fine!

        The local address: (00:11:67:55:8F:69)

        WSAAddressToString() for remote address is fine!

        The remote device address: (00:1D:D9:EA:24:D8)

        WSALookupServiceBegin() is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Bluetooth Serial Port

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #0 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Network Access

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #1 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Network Access

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #2 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Dial-up Networking

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #3 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: PIM Item Transfer

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #4 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: File Transfer

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #5 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Fax

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #6 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: PIM Synchronization

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #7 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Sync Command Service

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #8 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Headset

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #9 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Stereo Audio

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #10 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name:

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #11 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Audio Source

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #12 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Bluetooth Imaging

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #13 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Audio Gateway

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #14 is OK!

        WSALookupServiceNext() is OK!

        WSALookupServiceNext() - service instance name: Audio Gateway

        WSALookupServiceNext() - comment (if any):

BluetoothSdpEnumAttributes() #15 is OK!

        WSALookupServiceNext() failed with error code 10110

        Error code = 11011 ~ WSA_E_NO_MORE ~ No more device!

WSALookupServiceEnd(hLookup2) is fine!

WSALookupServiceEnd(hLookup) is fine!

WSACleanup() pretty fine!

Press any key to continue . . .

 

 

 


< Bluetooth Device Query Example | Winsock2 Supported Protocols Main | Querying Bluetooth Device Example >