Bluetooth Stacks on Windows Mobile

Submit New Article

January 16, 2010 8:00 PM PST


When you need to access the Bluetooth hardware on Windows Mobile, You should take into account your device’s implementation so you can read the information properly. There are at least two Bluetooth stack (implementations) types on Windows Mobiel from Microsoft and BroadComm.

Both implementations are the same for the end user, but at low level they use different application interfaces. The Microsoft’s Bluetooth stack has a Win32 API whose main function is BthGetHardwareStatus. As I always comment on demos or presentations, the Windows Mobile documentation depends on the underlying Windows CE version, in this case that method belongs to Windows CE .NET 4.2.

To statically use the Microsoft’s Bluetooth implementation you must to include the header Bt_api.h and its dependencies: Btdrt.lib y btdrtstubs.lib, as shown in Figure 1.

Figura2.JPG
Figure 1. Additional Dependencies.

On the other hand, the Broadcomm’s Bluetooth stack SDK can be downloaded from here. You need to include the header BtSdkCE.h from that SDK and add a reference to its dependency: BtSdkCE30.lib. The method to start using this implementation is IsDeviceReady().

Now, let’s jump into the code. First, activate the Bluetooth functionality in your device (Smartphone or Pocket PC) to be able to access the Microsoft or Broadcomm hardware. This sample activation is shown in Figure 2. If you don’t activate the hardware, the code provided won’t read the hardware information.

Figura1.JPG
Figure 2. Bluetooth Activation.

After activating Bluetooth, start a new Smart Device C++ project and copy /paste the following code:
/*
Author: Javier Andrés Cáceres Alvis
2009
This code is for academic purposes only.
.
*/

#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <Bt_api.h>

#define MIN_HW_VALUE 32

void ParseManufacturer(unsigned short usManufacturer, TCHAR *pszValue)
{

switch(usManufacturer)
{
/*
... Many others
*/
case 13:
wcscpy(pszValue,TEXT("TexasInstruments"));
break;
default:
wcscpy(pszValue,TEXT("Unknown"));
}
}

int _tmain(int argc, _TCHAR* argv[])
{

int errorCode=0;
int btStatus=0;

errorCode=BthGetHardwareStatus(&btStatus);

if(errorCode==ERROR_SUCCESS)
{
if(btStatus!=HCI_HARDWARE_NOT_PRESENT && btStatus!=HCI_HARDWARE_UNKNOWN)
{
HRESULT retValue=E_FAIL;
unsigned char phci_version;
unsigned short phci_revision;
unsigned char plmp_version;
unsigned short plmp_subversion;
unsigned short pmanufacturer;
unsigned char plmp_features;

if(BthReadLocalVersion(&phci_version,&phci_revision,&plmp_version,
&plmp_subversion,&pmanufacturer,&plmp_features)==ERROR_SUCCESS)
{
TCHAR pszManufacturer[MIN_HW_VALUE];
ParseManufacturer(pmanufacturer,pszManufacturer);
wsprintf(TEXT("The manufacturer is: %s"),pszManufacturer);
}
}

}

return 0;
}


The above code is simple, it uses the Microsoft stack and only access the Texas Instruments hardware. But what about this code running on BroadComm devices? Well, it won’t break, but it won’t be able to read device information using the method BthReadLocalVersion. In this exercise I used two HP devices with different stacks: a HP iPAQ h4150 and a HP iPAQ Voice Messenger (Figure 3), with Broadcomm and Microsoft implementations respectively.

foto.JPG
Figure 3. Broadcomm and Microsoft Stacks on different HP devices.

Finally, the next code works for Broadcomm’s stack implementations:

if(!bRetValue)
{
CBtIf broadInfo;

if(broadInfo.IsDeviceReady())
{
DEV_VER_INFO dvInfo=(DEV_VER_INFO) sizeof(DEV_VER_INFO);
GetLocalDeviceVersionInfo(&dvInfo);
if(broadInfo.IsDeviceConnectable())
{
if(broadInfo.IsDeviceDiscoverable())
{

}
}
}
}

Well, this is the end for now, I hope it saves you time.

Javier Andrés Cáceres Alvis
http://speechflow.spaces.live.com/
http://software.intel.com/en-us/blogs/author/javierandrescaceres/