I would like to create a Garmin wearable app (Data Field), which would communicate with my iOS app using Bluetooth LE (BluetoothLowEnergy API on Garmin and CoreBluetooth on iOS). There's a limitation of Garmin's API - it can work only as a central device, so I configured my iPhone to act as a "virtual" peripheral (I tested it both with my own debug app and LightBlue).
I managed to establish a connection between my Garmin Vivoactive 3 Music and my iPhone, but I still have some issues to make it work.
From Garmin wearable I managed to search, find and pair a device (my iPhone virtual peripheral), so that both: self.pairedDevice = BluetoothLowEnergy.pairDevice(scanResult) and BluetoothLowEnergy.getPairedDevices().next() don't return nulls.
The problem I have is that this callback is never called on a Garmin device:
function onConnectedStateChanged(device, connectionState) {
if (connectionState==BluetoothLowEnergy.CONNECTION_STATE_CONNECTED) {
displayString = "Connected";
}
if (connectionState==BluetoothLowEnergy.CONNECTION_STATE_DISCONNECTED) {
displayString = "Disconnected";
}
}
Moreover, when discovering my virtual peripheral, I can see available services in advertisement data, but once the devices are paired, calling device.getServices() returns an empty iterator.
I already checked that BluetoothLowEnergy.getAvailableConnectionCount() is 3, so there should be no problem with regard to connections number limit. Is there any way to force the connection?
On iOS I do something like this:
let service = CBMutableService(type: serviceCbuuid, primary: true)
let writeableCharacteristic = CBMutableCharacteristic(type: characteristicCbuuid,
properties: [.write],
value: nil,
permissions: [.writeable])
service.characteristics = [writeableCharacteristic]
currentService = service
peripheralManager = CBPeripheralManager(delegate: self,
queue: DispatchQueue.global(qos: .userInteractive))
then I add currentService using peripheralManager?.add(currentService) and in didAdd service callback I start advertising by calling peripheral.startAdvertising(options).
Maybe I miss some setting on the iOS end to make this work?