Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

IOBluetoothHandsFreeDevice API confusion

I wonder how one would use IOBluetoothHandsFree APIs to interact from macOS app with a bluetooth device that implements bluetooth hands free profile. My current observation is as follows:

  • IOBluetoothDevice object representing the device correctly identifies it as a hands free device, i.e.:
    • there is a proper record in services array, that matches the kBluetoothSDPUUID16ServiceClassHandsFree uuid,
    • the IOBluetoothDevice handsFreeDevice property returns 1
  • Attempt to create IOBluetoothHandsFreeDevice using IOBluetoothDevice as described above (i.e. [[IOBluetoothHandsFreeDevice alloc] initWithDevice: myIOBluetoothDeviceThatHasHandsFreeDevicePropertySetTo1 delegate: self]) results in the following output in debugger console: SRS-XB20 is not a hands free device but trying anyways.
  • Subsequent call to connect on an object constructed as above results in the following stream of messages:

API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > AddInstanceForFactory: No factory registered for id <CFUUID 0x600000b5e3e0> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID

Note that this device's handsFreeServiceRecord looks as follows: ServiceName: Hands-free unit RFCOMM ChannelID: 1 Attributes: { 0 = "uint32(65539)"; 256 = "string(Hands-free unit)"; 9 = "{ { uuid32(00 00 11 1e), uint32(262) } }"; 785 = "uint32(63)"; 1 = "uuid32(00 00 11 1e)"; 6 = "{ uint32(25966), uint32(106), uint32(256) }"; 4 = "{ { uuid32(00 00 01 00) }, { uuid32(00 00 00 03), uint32(1) } }"; }

and explicit attempt to open RFCOMM channel no 1 ends like this:

WARNING: Unknown error: 911 Failed to open RFCOMM channel -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x6000002036c0 SRS-XB20, b8-d5-0b-03-62-70, CID: 1, UUID: 111E > AddInstanceForFactory: No factory registered for id <CFUUID 0x600003719260> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel waitforChanneOpen] CID:1 - timed out waiting to open -[IOBluetoothDevice openRFCOMMChannelSync:withChannelID:delegate:] CID:1 error -536870212 call returned: -536870212

IOBluetoothHandsFreeDevice API confusion
 
 
Q