< Bluetooth Query Device & Service | Winsock2 Supported Protocols Main | Bluetooth Service & SDP Record >
What do we have in this chapter 4 part 14?
|
Another Example Querying Bluetooth Devices
Create a new empty Win32 console mode application and add the project/solution name.
Add the following source code. |
// Link to ws2_32.lib
#include <winsock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
#include <stdio.h>
// Minimum Vista
// #define _WIN32_WINNT 0x0600
#define MAX_NAME 248
#define MYBUFFSIZE 16384
union {
CHAR buf[5000];
SOCKADDR_BTH _Unused_; // ensure proper alignment
} butuh;
typedef ULONGLONG bt_addr, *pbt_addr, BT_ADDR, *PBT_ADDR;
//------------------------------------------------------------------------
// Function: PerformServiceSearch
// Purpose: Performs a service search and returns the RFCOMM channel for
// the specified Bluetooth remote device.
// Arguments: BT_ADDR pb
// Returns: int
//------------------------------------------------------------------------
int BtServiceSearch(BT_ADDR pb)
{
int iResult = 0, iRet;
HRESULT CoInitRet;
BLOB blob;
SOCKADDR_BTH sa;
CSADDR_INFO csai;
WSAQUERYSET wsaq1;
HANDLE hLookup1;
CHAR buf1[5000];
DWORD dwSize;
LPWSAQUERYSET pwsaResults1;
BTHNS_RESTRICTIONBLOB RBlob;
// Initializes the COM library for use by the calling thread
CoInitRet = CoInitializeEx(0, COINIT_MULTITHREADED);
if(CoInitRet == S_OK)
printf("CoInitializeEx() is OK...\n");
else
printf("Something wrong with CoInitializeEx()!\n");
// http://msdn.microsoft.com/en-us/library/ms881237.aspx
// This structure contains details about a query restriction
memset (&RBlob, 0, sizeof(RBlob));
RBlob.type = SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST;
RBlob.numRange = 1;
RBlob.pRange[0].minAttribute = SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;
RBlob.pRange[0].maxAttribute = SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;
RBlob.uuids[0].uuidType = SDP_ST_UUID16;
RBlob.uuids[0].u.uuid16 = SerialPortServiceClassID_UUID16;
// BrowseGroupDescriptorServiceClassID_UUID;
//This structure is used for an arbitrary array of bytes
blob.cbSize = sizeof(RBlob);
blob.pBlobData = (BYTE *)&RBlob;
//This structure defines the Bluetooth socket address
memset (&sa, 0, sizeof(sa));
sa.btAddr = pb;
sa.addressFamily = AF_BTH;
// Do some verification
printf("\n sa.btAddr: %012X\n", sa.btAddr);
printf(" GET_NAP(sa.btAddr): %04X\n", GET_NAP(sa.btAddr));
printf(" GET_SAP(sa.btAddr): %08X\n", GET_SAP(sa.btAddr));
printf(" sa.addressFamily: %d\n", sa.addressFamily);
printf(" sa.port: %ul\n", sa.port);
memset (&csai, 0, sizeof(csai));
csai.RemoteAddr.lpSockaddr = (SOCKADDR *)&sa;
csai.RemoteAddr.iSockaddrLength = sizeof(sa);
// Do some verification
printf("\n csai.RemoteAddr: %012X\n", csai.RemoteAddr.lpSockaddr);
printf(" csai.LocalAddr: %X\n", csai.LocalAddr.lpSockaddr);
printf(" csai.iSocketType: %d\n", csai.iSocketType);
printf(" csai.iProtocol: %d\n", csai.iProtocol);
memset (&wsaq1, 0, sizeof(wsaq1));
wsaq1.dwSize = sizeof(wsaq1);
// NS_BTH - The Bluetooth namespace. However this 'bastard' namespace identifier
// is supported on Windows Vista and later. Can also try NS_NLA
// Using NS_BTH failed with 10022 though with #define _WIN32_WINNT 0x0600
wsaq1.dwNameSpace = NS_ALL;
wsaq1.lpBlob = &blob;
wsaq1.lpcsaBuffer = &csai;
// Do some verification
printf("\n wsaq1.lpcsaBuffer->RemoteAddr: %X\n\n", wsaq1.lpcsaBuffer->RemoteAddr);
iRet = WSALookupServiceBegin(&wsaq1, 0, &hLookup1);
if (iRet == 0) //ERROR_SUCCESS
{
printf("BtServiceSearch(): WSALookupServiceBegin() should be OK!\n");
pwsaResults1 = (LPWSAQUERYSET) buf1;
dwSize = sizeof(buf1);
memset(pwsaResults1,0,sizeof(WSAQUERYSET));
pwsaResults1->dwSize = sizeof(WSAQUERYSET);
// But this part using NS_BTH is OK! Retard lor! %@%#&^%(^@^@^$($&$%
pwsaResults1->dwNameSpace = NS_BTH;
pwsaResults1->lpBlob = NULL;
iRet = WSALookupServiceNext(hLookup1, 0, &dwSize, pwsaResults1);
if (iRet == 0) // ERROR_SUCCESS - got the stream
{
printf("BtServiceSearch(): WSALookupServiceNext() is OK!\n");
printf("\n(The SDP result processing routine should be called...)\n\n");
// ...
// Source codes for this routine are for Windows CE!
// ...
}
else
printf("BtServiceSearch(): WSALookupServiceNext() failed with error code %ld\n", WSAGetLastError());
if(WSALookupServiceEnd(hLookup1) == 0)
printf("BtServiceSearch(): WSALookupServiceEnd(hLookup1) is OK!\n");
else
printf("BtServiceSearch(): WSALookupServiceEnd(hLookup1) failed with error code %ld\n",WSAGetLastError());
}
else
printf("BtServiceSearch(): WSALookupServiceBegin() failed with error code %ld\n", WSAGetLastError());
// Closes the COM library on the current thread, unloads all DLLs loaded by the thread,
// frees any other resources that the thread maintains, and forces all RPC connections
// on the thread to close.
CoUninitialize();
return iResult;
}
//------------------------------------------------------------------------
// Function: FindingBtDevices
// Purpose: Performs a device inquiry displays the device name in a console
//------------------------------------------------------------------------
BOOL FindingBtDevices()
{
WSAQUERYSET wsaq;
HANDLE hLookup;
LPWSAQUERYSET pwsaResults;
DWORD dwSize;
BOOL bHaveName;
BT_ADDR btAddr;
DWORD dwNameSpace;
int nPssRet;
pwsaResults = (LPWSAQUERYSET) butuh.buf;
dwSize = sizeof(butuh.buf);
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;
printf("\n");
if (WSALookupServiceBegin(&wsaq, LUP_CONTAINERS, &hLookup) == SOCKET_ERROR)
{
printf("FindingBtDevices(): WSALookupServiceBegin() failed %d\r\n", WSAGetLastError());
return FALSE;
}
else
printf("FindingBtDevices(): WSALookupServiceBegin() pretty damn OK!\n");
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob = NULL;
while (WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults) == 0)
{
// to get the remote address, the btAddr field should be properly cast
btAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
// Verify
wprintf(L"Device Address is 0X%012X\n", btAddr);
// Verify the returned name
bHaveName = (pwsaResults->lpszServiceInstanceName) && *(pwsaResults->lpszServiceInstanceName);
// Some more info
dwNameSpace = pwsaResults->dwNameSpace;
// http://msdn.microsoft.com/en-us/library/cc510863.aspx
// http://msdn.microsoft.com/en-us/library/ms892245.aspx
// SAP = 32 bits (8-hex-string)+ NAP = 16 bits 94-hex-string)= 48 bits = bluetooth address
wprintf (L"Name\tNAP Address\tSAP Address\tName Space\n");
wprintf (L"%s\t0X%04X\t\t0X%08X\t0X%0X\n", pwsaResults->lpszServiceInstanceName, GET_NAP(btAddr), GET_SAP(btAddr),
dwNameSpace);
nPssRet = BtServiceSearch(btAddr);
printf("Service search return value: %d\n", nPssRet);
}
if(WSALookupServiceEnd(hLookup) == 0)
printf("FindingBtDevices(): WSALookupServiceEnd(hLookup) is OK!\n");
else
printf("FindingBtDevices(): WSALookupServiceEnd(hLookup) failed with error code %ld\n",WSAGetLastError());
return TRUE;
}
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");
retVal = FindingBtDevices();
if(FindingBtDevices() == FALSE)
printf("\nNo bulutooth device in range found!\n");
else
printf("\nWell, found some bluetooth devices around!\n");
if(WSACleanup() == 0)
printf("WSACleanup() is OK!\n");
else
printf("WSACleanup() failed with error code %ld\n", WSAGetLastError());
return 0;
}
Build and run the project and the following screenshot shows a sample output.
--------------------------------------------------------------
< Bluetooth Query Device & Service | Winsock2 Supported Protocols Main | Bluetooth Service & SDP Record >