Extending the Bluetooth Hands Free Profile

Windows CE supports the Bluetooth Hands Free Profile Audio Gateway (AG).  This profile allows you to use a Bluetooth headset or car kit as a hands free (HF) device.  This feature is supported on Windows CE 5.0 and Windows Mobile 5.0 (and WM2003 SE).  You can find the Hands Free specification at www.bluetooth.org.


On top of routing audio to the HF, this profile allows many other functions like answering/ending/placing a call, redial, memory dial, voice dial, sending DTMF tones, etc.  The Windows CE implementation supports all of the mandatory features along with some optional features.  For a list of supported features (AT commands):




Does this mean that your phone can only take advantage of the features Microsoft has implemented?  Of course not!  The Hands Free Profile has an extensibility mechanism to allow OEMs to handle AT commands coming from the HF:




Some optional features of the Hands Free Profile require that the AG modify its “capability” bit mask in order to claim support for the feature (see HFP spec for details).  You can override the AG capability to include the new optional feature by using the “capability” registry value:




So you can handle new AT commands, but what about controlling the audio connection to the HF?  The AG service (btagsvc.dll) is a module in services.exe.  Applications can send IOControl messages to the service.  The AG supports the following IOControl messages:




Using IOCTL_AG_OPEN_AUDIO and IOCTL_AG_CLOSE_AUDIO you can allow all system audio to use your BT HF instead of the default system speaker/mic.  Keep in mind that BT audio is routed in hardware between the BT baseband module and cellular modem.  Some phones (e.g. HTC Typhoon) will support routing the audio to the OS to enable system sounds and voice dialing over BT, while other phones will only support cellular audio.


Here is a code sample:


    // TODO: Handle failure case where AG is not present

if (FALSE == fStatus) {
    // Failed to open BT audio!
} else {
    // Success!



[Author: Greg Scott]


Comments (39)

  1. Paul Sneddon says:

    Does this sample only work on WM2005? There are no headers in the SDK for the other versions?

  2. rmg says:

    Hi Greg, Please come back to http://forum.xda-developers.com/viewtopic.php?t=23558

    Paul (psneddon) has some new questions for you reagarding enabling the audio gateway on the HTC Magician.


  3. Winfried Klum says:

    Hi Greg,

    is the IOCTL_AG_OPEN_AUDIO/IOCTL_AG_CLOSE_AUDIO stuff also working for Windows CE4.2 ?

  4. cenet says:

    The Hands Free Profile was added in Windows CE 5.0. However, it was also included in Windows Mobile 2003 SE which is based on CE 4.2. To find SDK headers (btagpub.h, etc) you need to install Windows CE Platform Builder 5.0.

    This feature is not present in Windows CE Platform Builder 4.2.

  5. qwu says:

    could you send me the btagpub.h?

  6. qwu says:

    On a smartphone (like Motorola MPX220) with WM2003 SE, is it possible to route audio to BT Headset using your mentioned way?

  7. cenet says:

    qwu, I believe the MPx220 does not have the ability to route OS audio to a BT headset. It can only route cellular audio.

    What info do you need from the header?

    #define IOCTL_AG_OPEN_AUDIO 0x01

    #define IOCTL_AG_CLOSE_AUDIO 0x02

    If you need more info I recommend you download an evaluation version of Windows CE Platform Builder v5.0.


  8. Jerry says:

    When a Handsfree connection exists, can I do Push Object? In another words, does Windows CE Bluetooth stack support concurrent connections for multiple profiles?

  9. cenet says:


    The Windows CE Bluetooth stack does support concurrent connections so this is possible given the following assumptions:

    1) The remote device also supports this.

    2) If you are communicating with two different devices, the BT chip may need to support a feature called "scatternet".


  10. mrm_blue says:

    I want to use WinCE 5.0 for developing a Hands-Free Unit, not Audio Gateway. Does Windows CE support Hands Free Unit?

  11. cenet says:

    Windows CE 5.0 does not support the Hands Free device role of the Hands Free Profile, just Audio Gateway. But it is possible for you to develop this profile by making use of the CE Bluetooth APIs.



  12. mrm_blue says:

    Hi Greg,

    Saying that I want to develop a Hands Free Unit using WinCE 5.0 Bluetooth device, and want to keep two or more hands-free service level connection to two or more phones, so that any calling to those phones will be notified on my Hands Free Unit. Is this possible?



  13. Josh says:

    Thanks for the info! What specifically does IOCTL_AG_OPEN_AUDIO do? Does it just set up the connection? What else has to be done to send or record from the connection? I’ve been playing around on my phone and when I send an open audio command I can hear my headset "turn on", but nothing seems to change with how the Smartphone routes audio (everything keeps going over the normal speaker).

  14. cenet says:

    Hi Josh,

    Some OEMs will only set up audio routing between the cellular radio and Bluetooth due to hardware limitations. In this scenario IOCTL_AG_OPEN_AUDIO will not route OS sounds over BT. I suspect that is the issue you are having.



  15. Josh says:

    Thanks for a response, I figured as much. What little additional information is available online points to the possibility of using the btscosnd sample driver from PB 5.0 to compensate for the lack of hardware audio routing. I have been able to get btscosnd to compile in eVC4 for SP 2003, however it is not loading properly via the DriversBuiltIn registry key and when I try to manually add it via RegisterDevice it fails. I haven’t had time to go through and add my own debugging facilities (replacing what’s there with a simple file writer seems easiest).

    I know next to nothing about PB and if it’s possible to use the debug functions on btscosnd.dll even though I have a production device (MPx220). I guess my question then would be if it’s theoretically possible to get btscosnd.dll to work under SP 2003, or if I’m barking up the wrong tree. Any pointers as to what might be the problem before I dive in would be great.

    If I DO get it to work, I assume it will automatically bind to any connected headset on WAV_OPEN or WAV_INIT? I can probably figure that out from the source.

    Also, do you happen to know if there is there any way of setting the default input/output wav device? Ideally I would be able to map WAV5: (btscosnd) to default, so all the programs use it for input/output. Or is that handled directly by the programs? Sorry for all the questions, I’m quite new to CE programming.

    Thank you!

  16. jing says:

    Hi Greg,

    I used the IOCTL_AG_OPEN_AUDIO to open up the audio connection as you suggested and was able to hear sounds from my handsfree device. But my problem is, after a phone call, the audio connection is always terminated. Seems like the btagsvc is forcing a disconnection?

    Is there any workaround?



  17. Vincent says:

    Hi Greg,

    I am able to use IOCTL_AG_OPEN_AUDIO to route system sounds to BT handsfree. Cellular audio is also routed to BT handsfree when a phone call is established. But when the phone call disconnects, the audio connection to the BT handsfree is also disconnected.

    Is it possible to maintain the BT audio connection even after the phone call disconnects, so that system sounds is still routed to BT handsfree?

    Thank you!

  18. Jeff says:

    Is there a possibility that Microsoft will add this functionality to Voice Command so people won’t have to do all of these hacks?

  19. One smart cookie over at PDAPhoneHome.com has written a utility that redirects all audio on your Windows Mobile device and sends it to your Bluetooth headset, allowing you to use Skype, listen to audio books and music all hands free!Here is the utility

  20. SSR says:

    I tried using this utility on my UTstarcomm 6700 but after 10 seconds bluetooth shuts off and audio goes back to device. Anyone has fix on this?

  21. Paul Grant (PG2006) says:

    Hi Greg,

    I’m trying to programatically make a connection to Bluetooth headset from WM5 device.

    Using the GU interface provided on the device, I can

    a. discover the headset device, and authenicate

    b. Select the headset service, however I’m not certain what is actually done programatically when perform

    this selection in the GUI

    c. Using the code from your web page, I can redirect the audio of the WM5 device to the headset.

    This all works fine !

    I am now trying to do this all programatically, I’ve been looking through a description of the headset

    profile, it seems to indicate that the AG can initiate a connection to the HS, the AG is responsible for the

    creation of :

    1. Connection establishment

    2. SCO link establishment

    In the following code, I think the BthCreateACLConnection & BthAuthenticate are

    performing 1, and  BthCreateSCOConnection is performing 2. your code would then

    perform c.

    if (ERROR_SUCCESS == BthCreateACLConnection (&b, &h)) {

    iRes = BthAuthenticate (&b);

    BthCloseConnection (h);

       int res = BthCreateSCOConnection (&b, &hSCO);


    else {

    iRes = GetLastError ();

    MessageBox (hWnd, L"Connection failed", L"Error", MB_OK | MB_TOPMOST);


    I’m currently attempting to make to SCO connection to the BT_ADDR of the device,

    as opposed to the socket of the headset service. I’m not certain if this is correct or not.

    I get an error code 1229 which means :

    An operation was attempted on a nonexistent network connection.

    Am I doing something wrong !


    Paul Grant

  22. Gregoire says:

    I found a software product that controls the voice routing to the Bluetooth Headset.

    It’s called BlueMusic and you can download it from http://www.teksoftco.com

    It works great. Actually I never thought that listening to music with a Bluetooth headset can be this cool.

    I even managed to create voice notes (with the Notes sound recorder) with perfect quality.

    Im planning to test it with Skype and I’ll let you know of the results!

  23. Gregoire says:

    Sorry for the high frequency of posts, but now it hit me…

    Can any of you experts explain how the voice itself goes from the phone modem to the bluetooth headset?

    Is it possible to save that voice stream or whatever that is to a WAV file locally on the mobile device?

  24. David Mays says:

    I have written a shareware tool that will enable BT audio on a WM5 Smartphone.

    You may download it at http://www.davidmays.com/BTAudio/

    It is a fully featured, unlimited shareware application.

    I do not have the money to deal with Certificates, so it is unsigned.

  25. Kirill says:

    Hi Greg,

    I’ve implemented the procedure you described with IOCTL_AG_OPEN_AUDIO. And I am able to hear my BT headset is switched ON by this piece of code, but it still does not route all system sounds to the HF. And I am sure it is not a hardware limitation – when I push HF button for voice dialing then for some seconds I am able to hear all system sounds in the HF until the voice tag application is still active…

    Please explain how I can get it running proper.

    I am using HTC TyTN + WM5.

    Thank you in advance!

  26. David Mays says:

    My shareware utility has been updated, and some users at http://www.howardforums.com have been using it with great success. http://www.davidmays.com/BTAudio/

    I make use of the aforementioned IOCTL call, using P/Invoke from .NET CF 2.0.

    The free version is time limited to 30 minutes at a time, and will not automatically re-enable audio after a call has been received. The pay version is not time limited, and does automatically re-enable the audio routing after a call.

    Feel free to contact me here with any questions.



  27. Adrial says:


    I’m actually trying to do the reverse of what seems to be discussed in this forum for quite some time now but to no avail.

    I’m trying to create a wince based hands-free unit for an in-car computer application. Basically, I have a WINCE 5.0 mobile device running in an in-car environment and this device is already connected to the car audio system. I would want to write an application which allows this mobile device to connect as a hands-free unit to any bluetooth enabled mobile phone.

    Has anyone had any experience in doing something like that? As there are very little information to create something like that, I have been stuck at this for almost half a year now.

    Any help would be deeply appreciated! Thanks in advance to any kind soul out there who has a clue to how I should proceed.

  28. George says:

    Dear all, I want find on the internet bluetooth profile for handsfree. I have Pocket Pc Asus A632N, that have Handsfree profile for sending audio to handsfree kit, and A2DP profile for sending audio to bluetooth audio device. But I can not find profile for “virtual” handsfree, for simulation of handsfree on my pocket, for example GPS software running in my car, and my phone Sony Ericson is in bag, phone has found my virtual handsfree on the pocket. Pocket have windcom bluetooth without this profile.

  29. Eddie says:

    Hi all,

    I am trying to simulate Windows Mobile 5 device as a hands free unit. I have registerd the SDP record and created the service connection between HF and AG, but have no idea of how to receive audio from AG. Should I use the same way as AG to access the SCO connection? Thanks for any advice.

  30. Hrene says:


    this software product that controls sound routing is amazing!!!!…

    hope it will work on my <a href="http://www.techfocus.co.uk/Bluetooth-Headsets/BT150.htm&quot; title=" Jabra Bluetooth Headset">jabra Bluetooth Headset</a>

  31. Ankzz says:

    When I run the code provided over here I get following exception:

    Exception ‘Prefetch Abort’ (3): Thread-Id=06780016(pth=83ac1b58), Proc-Id=00400002(pprc=82209308) ‘NK.EXE’, VM-active=05970006(pprc=8310bbd8) ‘servicesd.exe’

    PC=00000000(???+0x00000000) RA=c0923378(btscosnd.dll+0x00003378) SP=d9fcf87c, BVA=00000000

    EXCEPTION IN WAV_IOControl!!!!

    Another audio driver is also running with name as “WAV1:” , Is it the one causing problem

  32. Ankzz says:

    I removed the other wave driver, still I am getting the same Exception.

    Its giving exception when it goes for the IOCTL "WODM_GETDEVCAPS "

  33. Gautam Kumar says:

    Hi Greg ,

    I am making an application where i am using pocket pc as bluetooth device and any mobile as gateway

    for HF profile.

    I did followint thing.

    I made a application where in I am searching for device and then paring with any BT  mobile found.

    I made a service level connection using winsck here passing HF uuid .

    then waiting in recv api for recving AT commds from BT  mobile.

    I am sucessfull in establ;ishing a service level connection but after a few second of connection establishment the connection breaks .

    I am also not able to send or recv anything .

    any help on this regard will be kindly welcomed

  34. Shinu says:

    Hi All,  

           I am trying to create a winCE based HS/HF device (Here the WincE will act as the HS/DF device side not AG side). I have done the connection establishment from the HS side to some mobile ,After the connection establishment I can able to recieve the Ring and also able to attend the call. But I am not able to route the audio. Whether the Mobile will route the audio to the headset?. Whether I need to do any operation to enable the audio in the headset. In which layer I ll be recieving the voice data. How I can take this data and direct to the speaker. same for the mic also. Please give some Idea for this as early as possible.



Skip to main content