1
votes

I have a bespoke bluetooth device that I can pair with and connect to using windows 10 and it creates 2 com ports - one is listed as incoming and one is listed at outgoing.

When I connect using the 32Feet C# bluetooth libraries I am able to discover and pair the device and the enable the SPP profile but, alas, I only get one COM port and it is listed as "outgoing".

I am required to interface to the device using someone else's code and it needs to be supplied a com port number. Unfortunately it wants to connect to the "incoming" port.

Hence my question is what magic do I need to create this incoming com port? I have looked at the 32Feet code and the underlying API call of BluetoothSetServiceState(...) and it doesn't seem to have any parameters to control how the ports are created. Is there another profile for this feature??

3
COM ports (and bluetooth SPP) are bi-directional. You don't need any magic herevasily.sib
Unfortunately magic is required - when Windows pairs the device I get two ports created and the "incoming" one provides the connectivity I need. When I use SPP via 32Feet I only get 1 port and it doesn't work. I know this seems silly,... but alas I don't control the whole stack so I need the magic. From my reading it seems both the "incoming" and "outgoing" ports are bi-directional but one is created by the "client" and one is created by the "server"Paul Coldrey

3 Answers

2
votes
private const UInt16 BLUETOOTH_MAX_SERVICE_NAME_SIZE = 256;
private const UInt16 BLUETOOTH_DEVICE_NAME_SIZE  = 256;

private static Guid SerialPortServiceClass_UUID = new Guid("{00001101-0000-1000-8000-00805F9B34FB}");

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct BLUETOOTH_LOCAL_SERVICE_INFO
{
            public Boolean Enabled;
            public Int64 btAddr;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BLUETOOTH_MAX_SERVICE_NAME_SIZE)]
            public String szName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BLUETOOTH_DEVICE_NAME_SIZE)]
            public String szDeviceString;
};

[DllImport("BluetoothAPIs.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern UInt32 BluetoothSetLocalServiceInfo(IntPtr hRadioIn, ref Guid pClassGuid, UInt32 ulInstance, ref BLUETOOTH_LOCAL_SERVICE_INFO pServiceInfoIn);

private void CreateComPort(Boolean Create)
{
            BLUETOOTH_LOCAL_SERVICE_INFO s = new BLUETOOTH_LOCAL_SERVICE_INFO();
            s.btAddr = 0;
            s.Enabled = Create;
            s.szName = "MyComPort";
            s.szDeviceString = "COM10";

            UInt32 Res = BluetoothSetLocalServiceInfo(IntPtr.Zero,
                ref SerialPortServiceClass_UUID, 1, ref s);
            MessageBox.Show(Res.ToString());
}
2
votes

You have to use undocumented InstallIncomingComPort function from BluetoothAPIs.dll

0
votes

If you are looking to use the InTheHand BT library and get an incoming com port you can add the following code to the bottom of the function

public void SetServiceState(Guid service, bool state, bool throwOnError)

in WindowsBlurtoothDeviceInfo.cs

if (service == BluetoothService.SerialPort)
{
    NativeMethods.BLUETOOTH_LOCAL_SERVICE_INFO s = new NativeMethods.BLUETOOTH_LOCAL_SERVICE_INFO();
    s.btAddr = deviceInfo.Address;
    s.Enabled = state;
    s.szName = "RemScan";
    s.szDeviceString = "COM10";
    UInt32 Res = NativeMethods.BluetoothSetLocalServiceInfo(IntPtr.Zero, ref NativeMethods.SerialPortServiceClass_UUID, 1, ref s);
}