iPhone 7 - CBPeripheral -discoverServices fails to callback

Hi all,


We're developing an app which involves BTLE communication between Android and iOS.

We have Android5.0+ in Peripheral mode and iOS in Central.

We've been developing this for a few months, I've been testing the iOS side on phones from 4S to 6S from iOS8.1 to the iOS10.0.1 release. All was good.


This week we got our first iPhone 7. It's lovely, but to my horror, we're unable to complete our data transfer to the Android BTLE Peripherals. After scanning and successfully connecting to the peripheral we set the delegate and call -discoverServices as normal but the delegate method never gets called back.

I tested both iOS10.0 14A346 (that it shipped with) and current 10.0.1 14A403.


My didConnectPeripheral implementation looks like:


func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
    DLog("Connected: \(peripheral)")
    self.lastPeripheral = peripheral
    if peripheral.services == nil {
        peripheral.discoverServices([lockServiceUUIDBase])
        assert(peripheral.delegate != nil)
    } else {
        DLog("Services already exist, shortcutting")
        self.peripheral(peripheral, didDiscoverServices: nil)
    }
}


Nothing too fancy. This method gets called, the assert doesn't throw, but -didDiscoverServices never gets called. I have tried removing the specific service UUID's but it made no difference.


Has anyone else run into this?


Thanks in advance.

Alex Kent

Accepted Reply

After updating my iPhone 7 to iOS 10.1, the problems are solved. didDiscoverServices is now called and I can access the peripheral.

Replies

Yes - seeing the same issue. Also talking to an Android 5.1 device in peripheral mode, which works fine from all phones/OS/etc except iPhone 7 running iOS10 10.0.1.


In my case, I never receive `-didDiscoverServices`, but after ~30s I receive `-didDisconnectPeripheral` with an error `CBErrorDomain` and `Code: 0 "Unknown Error"`.


Currently updating to 10.0.2 on one of my phones to see if this was fixed.


(EDIT: Does not work on 10.0.2 either)

I've also confirmed that my issue is not strictly related to `discoverServices`. The connection times out after ~30s with "Unknown error" whether I call `discoverServices` or not

Good to hear I'm not alone.


After further testing I have found that the behaviour depends on the Android phone model playing the peripheral role, amongst the half dozen phones we have here only the Samsung S6 Edge works.


I am considering taking a Technical Support Incident to see if I can get any guidance from Apple… although now I see it's device specific I fear the reply will be "Android is doing it wrong".

I filed a bug report rdar://28479978 and open radar http://openradar.appspot.com/radar?id=5507212436832256


I made a TSI but they suggested it would be best resolved as a bug report.


@alexkent do you know which versions of Android you have tested on? Especially on that S6 which worked - was it running Marshmallow?

In our tests iPhone 7 10.0 - 10.0.2 worked connecting to Samsung S6 Edge Android 6.0.1


Other Android devices that the iPhone 7 fails to discover services for:


Samsung Galaxy S7 Android 6.0.1

Samsung Note 4 Android 6.0.1

Cyanogen OnePlus One Android 6.0.1

LG G5 Android 6.0.1

Sony Xperia Z1 Android 5.0.2

Samsung Galaxy S5 Android 5.0

Nexus 6 Android 6.0.1

We're still having this issue with our android device, but we've seen the iPhone 7 connect sucessfully to a Nexus 9 Tablet, and a Samsung Galaxy S5, both running Android 5.1 & this test app: https://github.com/mzsanford/ble-test-peripheral-android.


Alex - when you're having issues with the Galaxy S5, what model specifically? We have not reproduced the failure with a G900A model - it connects to the iPhone 7 without issue. We'd like to see some other failure cases to understand why our device never provokes discovery from the iPhone so any other details you might have would help


I've included a sequence diagram of what we're seing between the iPhone7 (Master) and our device (*****) with some callouts: In our device's case we never receive an `LL_FEATURE_REQ` PDU from the iPhone7 after the `CONNECT_REQ` is sent, and the `VERSION_IND` pdus are exchanged. Later, the iPhone never initiates the `EXCHANGE_MTU_REQ` sequence, or proceeds with GATT interrogation as it does for other devices. Not sure if you are seeing similar behavior in your connection failure cases...

I now have access to a iPhone 7+ device. I can confirm it behaves the same way.

Unable to connect to any of the Android peripheral devices we have except the Samsung S6 Edge.

Hi Alex,


I'm having a similar issue with iPhone 7 connecting to a peripheral. The peripheral is an embedded device and not a phone, but the behavior is exactly the same. I'm able to connect with 6 or 6S, but not 7.


Did you get a packet dump? I got a packet dump and it looks like iPhone 7 is not querying for services.


Sam

Hey guys,


Just thought I would share my findings. The iPhone 7 doesn't seem to be able to read the advertisment data from the peripherals properly. So, if you haven't previously connected to that peripheral, you won't be able to find it by scanning for specific services. Also if you scan with a parametar nil for services, you cannot filter by names because you can't read the friendly name before you connect to it. As the app I am working on needs to go to the store this week, i had to implement a hack to connect to each found peripheral and then check the name/services. Disconnect if it's not the one I'm searching for. It's a nighmare, and seems to be connected to the hardware, as everything works fine on an iPhone 6s with 10.0.2.

Tried to scan with the LightBlue app, and all the peripherals are named "Unnamed" before connecting to them.

Hi moni_qwerty It seems like this is helpful to me... is there a way i can contact you and talk about this? i have an app stoped because of the bt functionality.

It's definitely not just an Android peripheral problem. I'm seeing the same issue on an iPhone 7 with iOS 10.0.3 (which came out today) when trying to access a BLE enabled light bulb (i-Link). The exact same Swift code works fine on a MacBook in a Mac app using it.


Incidentally, the app accompanying the bulb is also crashing on my phone. Also, the LightBlue BLE scanner app running on the phone sees the peripheral but times out when interrogating it.

Just a small note that this is not only related to iPhone 7. I work on an app that interfaces with an RFID reader as the peripheral, and I see the same on my iPad Air too. Both run iOS 10.0.1. I've worked on the app since May and had no real issues with discoverServices before I upgraded my phone to a 7. I never tried with the iPad until now. The phone I used all summer was an iPhone 5 with iOS 9. No issues whatsoever. Now, I see that discoverServices never returns anything. However, if I select "Forget this device" from the Bluetooth settings it will work fine for a while again. But once it fails, it fails constantly until I forget the device.


Checking with LightBlue from my iPad, it seems to always find the RFID reader, but it's often grayed out and can not be "drilled into". When it's not grayed out I can drill down and see the services and characteristics.

However, I don't see any timeout after 30s.

Did you find the problem?


Everything is perfectly working with iPhone 7- and a nRF52832 but didDiscoverServices is not getting called on an iPhone 7 or iPhone 7 Plus. Did someone find the solution?


Thanks.

After updating my iPhone 7 to iOS 10.1, the problems are solved. didDiscoverServices is now called and I can access the peripheral.