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
|