Few weeks ago I was working on the case, where customer asked for redirection of audio output in Windows Mobile into it’s Bluetooth headset. Yes yes, I know there are stereo Bluetooth headsets, so what’s the point? The problem was how to redirect any audio stream (gps navigation instructions) into Bluetooth even if the headset is standard hands-free (no stereo headset profile).

Bluetooth audio gateway

Windows Mobile (Windows CE) offers way how to redirect audio output to Bluetooth stream. It’s obvious functionality that helps things like Bluetooth hands-free to work. The only thing we need is to make this feature work for us. More information about the Audio Gateway can be found on MSDN.

Long story short, following code listing shows necessary API functions.

public class SystemCalls
    public const int IOCTL_AG_CLOSE_AUDIO = 2;
    public const int IOCTL_AG_OPEN_AUDIO = 1;

    public static extern bool DeviceIoControl(  IntPtr hDevice,
                                                int dwIoControlCode, 
                                                IntPtr lpInBuffer,
                                                int nInBufferSize, 
                                                IntPtr lpOutBuffer,
                                                int nOutBufferSize,
                                                ref int lpBytesReturned,
                                                IntPtr lpOverlapped);

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern IntPtr CreateFile( string lpFileName, 
                                            uint dwDesiredAccess, 
                                            uint dwShareMode, 
                                            IntPtr lpSecurityAttributes, 
                                            uint dwCreationDisposition, 
                                            uint dwFlagsAndAttributes, 
                                            IntPtr hTemplateFile);

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr hObject);

Audio Manager class

Whole functionality is based on creating the handle of the Bluetooth Audio Gateway and then set appropriate parameter using DeviceIoControl. Excuse me the empty catch block, but there is not much place for deeper diagnostics what went wrong :) The only glitch with redirecting audio gateway is, that Windows Mobile sets everything back once you hang-up your call. So, it’s important to re-redirect audio after every phone call. Maybe there are other event that resets the audio gateway - you have to test it. Another issue is, that this might not work 100% on every device. My goal was to make it work on HTC TyTN II.

public class AudioManager
    public static bool EnableAudio()
        return ProcessStatus(SystemCalls.IOCTL_AG_OPEN_AUDIO);

    public static bool DisableAudio()
        return ProcessStatus(SystemCalls.IOCTL_AG_CLOSE_AUDIO);

    private static bool ProcessStatus(int status)
        bool result = false;
            IntPtr hDevice = SystemCalls.CreateFile("BAG0:", 0, 0, IntPtr.Zero, 3, 0, IntPtr.Zero);
            if (IntPtr.Zero == hDevice)                
                return result;
            int lpBytesReturned = 0;
            if (!SystemCalls.DeviceIoControl(hDevice, 
                                             status, IntPtr.Zero, 
                                             ref lpBytesReturned, 
                result = false;
                result = true;

        return result;

Sample application

Sample C# application for Compact Framework are available to download. All sources and installation .CAB file is bundled: BTAudioGateway.zip [61.4 Kb]