Miniware logo
Articles / Finding Bluetooth devices and services using C++ in Windows XP

Finding Bluetooth devices and services using C++ in Windows XP

Preparing Visual Studio 2005
Providing that you have already installed Microsoft Windows Platform SDK, we have to set the necessary paths. We can do it by pressing Tools -> Options and then choosing Project and Solutions -> VC++ Directories. There you have to add in the Executable files the bin directory of the Microsoft Windows Platform SDK , in the Include files, the include directory and in the Reference and library files, the lib directory.

Including the necessary header files
Our program should start with the following statements:
#include <winsock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "irprops.lib")
using namespace std;


Initializing the Winsock
Before doing everything we have to initialize the Winsock as the Bluetooth api is using it. This is done with the following code:
WSADATA data;
int result;
result = WSAStartup(MAKEWORD(2, 2), &data);//initializing winsock
if (result!=0){
    cout << "An error occured while initialising winsock, closing....";
exit(result);
}


Querying for devices
In order to discover devices we use two methods, the WSALookupServiceBegin which create a handle that we are using in the seconde method named WSALookupServiceNext. WSALookupServiceBegin needs WSAQUERYSET structure in its input. The way this structure is constructed is specified in the msdn web site which you can find in the links section of this website. WSALookupServiceNext returns also a WSAQUERYSET which represent the remote device. Note that we have to run WSALookupServiceNext as many times as the remote devices. The code below demonstrates the above in use:
//Initialising query for device
WSAQUERYSET queryset;
memset(&queryset, 0, sizeof(WSAQUERYSET));
queryset.dwSize = sizeof(WSAQUERYSET);
queryset.dwNameSpace = NS_BTH;

HANDLE hLookup;
result = WSALookupServiceBegin(&queryset, LUP_CONTAINERS, &hLookup);
if (result!=0){
    cout << "An error occured while initialising look for devices, closing....";
exit(result);
}

//Initialisation succeed, start looking for devices
BYTE buffer[4096];
memset(buffer, 0, sizeof(buffer));
DWORD bufferLength = sizeof(buffer);
WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
while (result==0){
    result = WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_FLUSHCACHE |                 LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE,&bufferLength, pResults);
    if(result==0){// A device found
        //print the name of the device
        LPTSTR s = pResults->lpszServiceInstanceName;
        wcout << s << "found. \n";

    }
}


Querying for services
In order to find the services a device is offering we are suing the same two methods. But the values set in the WSAQUERYSET structure are different. You can find more details about the values needed to be set in the msdn web site, that can be found in the links section of the website. The below example show how to find the services a device is offering. Note that the pResults variable is the result of the code above.

//Initialise quering the device services
WSAQUERYSET queryset2;
memset(&queryset2, 0, sizeof(queryset2));
queryset2.dwSize = sizeof(queryset2);
queryset2.dwNameSpace = NS_BTH;
queryset2.dwNumberOfCsAddrs = 0;
CSADDR_INFO * addr = (CSADDR_INFO *)pResults->lpcsaBuffer;
WCHAR addressAsString[1000];
DWORD addressSize = sizeof(addressAsString);
WSAAddressToString(addr->RemoteAddr.lpSockaddr,addr->RemoteAddr.iSockaddrLength,NULL,addressAsString, &addressSize);
queryset2.lpszContext = addressAsString;
GUID protocol = L2CAP_PROTOCOL_UUID;
queryset2.lpServiceClassId = &protocol;
HANDLE hLookup2;
int result2 = WSALookupServiceBegin(&queryset2, LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_TYPE | LUP_RETURN_ADDR | LUP_RETURN_BLOB | LUP_RETURN_COMMENT, &hLookup2);
if (result2 !=0){
    cout << "An error occured while initializing query for services";
exit(result);
}

//Start quering for device services
while(result2 ==0){
    BYTE buffer2[4096];
    memset(buffer2, 0, sizeof(buffer2));
    DWORD bufferLength2 = sizeof(buffer2);
    WSAQUERYSET *pResults2 = (WSAQUERYSET*)&buffer2;
    result2 = WSALookupServiceNext(hLookup2,LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_TYPE | LUP_RETURN_ADDR |             LUP_RETURN_BLOB | LUP_RETURN_COMMENT,&bufferLength2,pResults2);
    if(result2 == 0)
        wcout << "Service found: " << pResults2->lpszServiceInstanceName <<"\n";


The code below is a full program that it search for Bluetooth device and for each device it can found its services

#include <winsock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "irprops.lib")
using namespace std;

int main(){
//Initialising winsock
WSADATA data;
int result;
result = WSAStartup(MAKEWORD(2, 2), &data);//initializing winsock
if (result!=0){
    cout << "An error occured while initialising winsock, closing....";
exit(result);
}

//Initialising query for device
WSAQUERYSET queryset;
memset(&queryset, 0, sizeof(WSAQUERYSET));
queryset.dwSize = sizeof(WSAQUERYSET);
queryset.dwNameSpace = NS_BTH;

HANDLE hLookup;
result = WSALookupServiceBegin(&queryset, LUP_CONTAINERS, &hLookup);
if (result!=0){
    cout << "An error occured while initialising look for devices, closing....";
exit(result);
}

//Initialisation succedd, start looking for devices
BYTE buffer[4096];
memset(buffer, 0, sizeof(buffer));
DWORD bufferLength = sizeof(buffer);
WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
while (result==0){
    result = WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_FLUSHCACHE |                 LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE,&bufferLength, pResults);
    if(result==0){// A device found
        //print the name of the device
        LPTSTR s = pResults->lpszServiceInstanceName;
        wcout << s << "found. quering for services\n";
        //Initialise quering the device services
        WSAQUERYSET queryset2;
        memset(&queryset2, 0, sizeof(queryset2));
        queryset2.dwSize = sizeof(queryset2);
        queryset2.dwNameSpace = NS_BTH;
        queryset2.dwNumberOfCsAddrs = 0;
        CSADDR_INFO * addr = (CSADDR_INFO *)pResults->lpcsaBuffer;
        WCHAR addressAsString[1000];
        DWORD addressSize = sizeof(addressAsString);
        WSAAddressToString(addr->RemoteAddr.lpSockaddr,addr->RemoteAddr.iSockaddrLength,NULL,addressAsString, &addressSize);
        queryset2.lpszContext = addressAsString;
        GUID protocol = L2CAP_PROTOCOL_UUID;
        queryset2.lpServiceClassId = &protocol;
        HANDLE hLookup2;
        int result2 = WSALookupServiceBegin(&queryset2, LUP_FLUSHCACHE |LUP_RETURN_NAME | |LUP_RETURN_TYPE| LUP_RETURN_BLOB | LUP_RETURN_COMMENT, &hLookup2);
        if (result2 !=0){
            cout << "An error occured while initializing query for services";
        exit(result);
        }

        //Start quering for device services
        while(result2 ==0){
        BYTE buffer2[4096];
        memset(buffer2, 0, sizeof(buffer2));
        DWORD bufferLength2 = sizeof(buffer2);
        WSAQUERYSET *pResults2 = (WSAQUERYSET*)&buffer2;
        result2 = WSALookupServiceNext(hLookup2,LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_TYPE | LUP_RETURN_ADDR | LUP_RETURN_BLOB | LUP_RETURN_COMMENT,&bufferLength2,pResults2);
        if(result2 == 0)
                wcout << "Service found: " << pResults2->lpszServiceInstanceName <<"\n";

        }
    }
}
return 0;
}

The complete code can be downloaded here



The content of this page can be reproduced as long as the author and the source are mentioned. For questions please use the forum. Nikos Fotiou
Comments
(Post new comment)

2008-09-09 13:43:08 Carl Kenner wrote:
If you get -1 when you call WSALookupServiceBegin, it is because you didn't call WSAStartup(2,data); at the start of your program.


2008-09-03 11:48:43 Anil Kumar Gautam wrote:
I want to disable bluetooth service in my windows pc like dial up networking or PAN network and file transfer service how can I do ,can you give me some source code or example
2008-07-13 04:03:37 eirc wrote:
I want to disable bluetooth service like dial up networking or PAN network and file transfer service how can I do ,can you give me some source code or example
2007-08-24 09:37:03 honzo wrote:
Is highly probable that problem is in drivers, i have widcomm driver instead of MS drivers. : [ thx
2007-08-24 09:29:19 honzo wrote:
Hi, i have problem, when i debug this line " result = WSALookupServiceBegin(&queryset, LUP_RETURN_NAME, &hLookup);" result is still "-1", error code is "WSASERVICE_NOT_FOUND 10108 - No such service is known. The service cannot be found in the specified name space. ". Do you have any idea where is a problem? I have VS 2005, WinXP SP2. Result of WSAStartup is 0. :[ could you help me, thx Honzo