Post

Replies

Boosts

Views

Activity

IOBluetooth: discovering if my (classic) bluetooth headset is "connected" to macOS
I want my program to behave differently if a specific bluetooth headset is "connected" to the system. By "connected" I mean that it is: paired with the system appears on a list of audio output in Settings (not necessarily selected as default output) appears on "My Devices" list in Bluetooth preference pane with "Connected" status. I want this to determine "availability" of the device, i.e. likehood that establishing an active connection will succeed. Apparently IOBluetooth does not offer API to easily achieve this... I've tried: [IOBluetooth pairedDevices] to iterate though paired device list. This one correctly returns IOBluetoothDevice object representing my device. When I call [IOBluetoothDevice isConnected] it returns false even though device is listed as "connected" on My Devices list in Bluetooth settings. If I leave the headset at original place, go with my mac to a physically different location and call getLastInqiuryUpdate or recentAccessDate, both return current time, even though the headset is not in range for several days now. So I'm looking to determine the headset "connected" state the same way Bluetooth Settings pane does it and without making an active connection attempt.
0
1
784
Feb ’24
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
0
0
109
Jun ’25