Discussing the nuts and bolts of software development

Tuesday, April 24, 2007

 

Bluetooth Handsfree Profile Support for Windows Mobile 5 - The Series (Part 1)

Bluetooth Handsfree Profile Support for Windows Mobile 5 - Part 1

Have you ever run into the question of what mechanisms are there for supporting Bluetooth on your WM5 device? What has Microsoft provided to extend the Handsfree profile functionality? How can I use the Audio Gateway?

Very good questions. In this series of articles about Bluetooth support, I'm going to try to fill in the holes. This series is geared towards developers who have experimented with the Audio Gateway and are scratching their heads as to how to get into this "black box".

Microsoft supports Bluetooth with an architecture known as the "Audio Gateway." It consists of the core itself, the Services interface, AT Command Extension Module, Phone Extension Module, and Network Component. All of these components interact with the Core that signals the Bluetooth stack of commands and state changes. To read up on the Audio Gateway architecture, trickle into the MSDN website and search for "Bluetooth Audio Gateway."

Now, as a developer, you're wondering, "How do I get into this darn thing and make it do what I want it to do?"

There are a few ways to interact with the Audio Gateway (which I'll refer to as the "AG").

Firstly, from a services standpoint, Services.exe and the underlying layer of IOCTL calls the core support call enumerations to control the AG. I've listed the constants below. They are also in the .h file. The constants are pretty self-explanatory, so I won't go into much detail about them. Basically, there is the AG service, which we can start, stop and refresh. If the service has started and a Bluetooth device has been paired with the WM5 device, a service level connection must be established with the device as to signal different commands via AT Commands (to be discussed later), which we can start and stop as well. On top of that, the AG can route audio to the Bluetooth headset.

// You can find these within service.h
// IOCTL_SERVICE_START
// IOCTL_SERVICE_REFRESH
// IOCTL_SERVICE_STOP
// IOCTL_SERVICE_STATUS

#define IOCTL_AG_OPEN_AUDIO 0x01
#define IOCTL_AG_CLOSE_AUDIO 0x02
#define IOCTL_AG_CLOSE_CONTROL 0x03
#define IOCTL_AG_SET_SPEAKER_VOL 0x04
#define IOCTL_AG_SET_MIC_VOL 0x05
#define IOCTL_AG_GET_SPEAKER_VOL 0x06
#define IOCTL_AG_GET_MIC_VOL 0x07
#define IOCTL_AG_GET_POWER_MODE 0x08
#define IOCTL_AG_SET_POWER_MODE 0x09
#define IOCTL_AG_OPEN_CONTROL 0x0A


So, by simply calling these defines within a IOCTL call, you'll be able to achieve basic services support. Note that some defines require you to pass in values. I don't want to go into too much detail about this, since we're just scratching the surface, and I'm hoping as the reader you're asking yourself, "When does the fun really start?"

HANDLE msAGHandle = ::CreateFile( L"BAG0:", 0, 0, 0, OPEN_EXISTING, 0, 0 );
if ( INVALID_HANDLE_VALUE == msAGHandle )
{
// log something with GetLastError();
return;
}

BOOL result = ::DeviceIoControl( msAGHandle, IOCTL_SERVICE_STOP, 0, 0, 0, 0, 0, 0 );
if ( FALSE == result )
{
// log something
}

::CloseHandle( msAGHandle );


Aside from the services layer, it has been hypothesized (however not actually confirmed by me) that we can replace the AT Command Extension Module to override the AG core of AT command reception and AT command processing. What happens in the AG core, once paired and a service level connection has been established, is if an AT command is received, the core will first "ask" the AT Command Extension Module if it would like to handle this command. If the AT Command Extension Module wishes to handle the command, it returns, from the interface call, "true", otherwise "false" to signal that the core does its own processing.

So how do you replace the AT Command Extension Module?

Easy. There are two ways to replace this module. In the Windows directory of your WM5 device, a file called "btagext.dll" exposes an interface (interface description to come) which the core dynamically links to. You can replace this file with your own file to override the AT command processing. Replacing the file can get a little messy if one doesn't have the proper access rights to overwrite Windows dlls.

Another way is to edit the registry so that the AT Command Extension Module path points to your dll. First, copy your AT Command Extension DLL onto the device, edit the registry path "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway\\BTAGExtModule" with your DLL path, restart the device or restart the AG service and... Voila!

So what does your custom AT Command Extension Module have to override?

The "btagext.dll" exposes these commands:
typedef DWORD (*PFN_SendATCommand) (LPSTR szCommand, DWORD cbCommand);
BOOL BthAGATHandler(LPSTR szCommand, DWORD cbCommand);
void BthAGATSetCallback(PFN_SendATCommand pfn);
DWORD BthAGOnVoiceTag(BOOL fOn);


I leave it up to you to explore how you can replace the AT Command Extension Module. Take a look at the MSDN Website for further details about these methods. Since we are supporting the Handsfree profile, search the Bluetooth website for the .pdf file for a list of AT commands to support... Or stay tuned for a description of these AT commands.

OK, now for the really fun stuff.

I know some of you are in the same boat as I was, saying to yourself, "I've paired and authenticated with the device, so how do I use the AG to route audio? I can route audio via the IOCTL calls but I can't do any other in-call processing. Some libraries offered in WinCE are not exposed to me, e.g. the Network component (for network signalling), so I can't signal different in-call states."

Personally, I've never gotten around to using the AG service, since specific libraries in the WM5 PPC and Smartphone SDK weren't included in my version and, simply put, I had no mechanism to control the AG service besides the service component via IOCTL calls.

What to do, what to do?! Hey lets build our own Audio Gateway! Yeah! That'll be fun!

To be continued....

Comments:
Hello Quan Nguyen,

I want to post one TAPI 2.0 related query to you, but as I am not getting any other way to reach I am posting it here.

I am trying to implement 3 way cell conference, I almost did it but problem is to check whether it is supported (enabled) by TSP or not.
I did check it same with lineGetCallStatus() and lineGetAddressCaps() but it doesn't give proper values into appropriate fields. Is there any way to check service availability of cell conference before adding the call to cellconference.


any help would be helpful to me, as I stuck here and it creates problem with behavior where cell conference is not enabled by TSP.
 
Hi Paresh,
There should be a way to query the line capabilities...
Try using TSPI_lineGetDevCaps or methods related to tapi to get the line device capabilities...

Hope that helps
Cheers,
Q.
 

- Xoẹt xoẹt.

Đòn công kích của Thượng Quan Uyển Nhi và Dịch Thiến rất mạnh thân thể của hai nàng sau đó lui về phía sau hơn nghìn thước, một ngụm máu tươi sau đó được phun ra, cả hai kinh ngạc nhìn hắc bào nam tử phía trước:


- Xoẹt xoẹt xoẹt.

Một thanh âm xé giódongtam
mu private
tim phong tro
http://nhatroso.com/
nhac san cuc manh
tổng đài tư vấn luật
http://dichvu.tuvanphapluattructuyen.com/
văn phòng luật
tổng đài tư vấn luật
dịch vụ thành lập công ty
http://we-cooking.com/
chém gió
trung tâm ngoại ngữ truyền tới, ngay sau đó Yêu Huyên, Bàn Thiên Lão Ma, Kim Long, Hỏa Lão đã tới bên cạnh Nhạc Thành.


- Nhạc tộc trưởng, cả hai vừa tới đúng lúc.

Hoàng Vũ sau khi nhìn thấy thì khuôn mặt nở ra một nụ cười, có Nhạc Thành tới, nàng biết mình tuyệt đối được an toàn.

- Bàn Thiên Lão Ma, Kim Long, Nam Tương Tư, đem mọi người vây lại cho ta.

Nhạc Thành khẽ nói với đám người Bàn Thiên Lão Ma.

 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?