evothings / cordova-ble

Bluetooth Low Energy plugin for Cordova
http://www.evothings.com/
Apache License 2.0
242 stars 103 forks source link

Notification/Indication values not received on iOS when properly subscribed #83

Closed robertoandrade closed 8 years ago

robertoandrade commented 8 years ago

According to Apple's CBPeripheral's documentation when enabling notifications for a specific characteristic, such value updates are to be received via the peripheral:didUpdateNotificationStateForCharacteristic:error: callback and not via peripheral:didUpdateValueForCharacteristic:error: as commented/expected in the current code.

Seems like there was an assumption there that the value was to be received through the same route as the "read" operation, which is not true.

fredrikeldh commented 8 years ago

Apple's documentation does not agree with our code, yes, but all our tests indicate that we DO get values via didUpdateValueForCharacteristic. Perhaps there's a mistake in Apple's documentation, or a bug in the API.

Anyway, as long as this plugin works as advertised, I think we can close this issue.

robertoandrade commented 8 years ago

Well, I actually bumped into this issue because it wasn't working me on an iOS 9.2 device. When I add the other message to the implementation and forward the parameters to the other method it works.

What kind of test environment do you guys have for this?

robertoandrade commented 8 years ago

And to be sure the test case matches my scenario. The characteristic I'm trying to subscribe for notifications has the PROPERY_INDICATE flag to it. So not sure if in your case you're testing with PROPERTY_NOTIFY?

fredrikeldh commented 8 years ago

I'm not sure, but I think most of our BLE devices use NOTIFY rather than INDICATE. We usually test with TI SensorTags. What do you use?

If you have code that fixes this bug, we'd love a pull request.

robertoandrade commented 8 years ago

Yeah, will submit a PR for it. I'm using a Homedics Blood Pressure Monitior and the particular characteristic I'm interested in, the blood pressure itself, has the indicate property (instead of notify) as per the specs.

ghost commented 8 years ago

@robertoandrade Many thanks for the pull request! Merged it just now.

ghost commented 8 years ago

@robertoandrade Hi again, done some further testing and I get an application crash caused by characteristic.value being nil on this line: https://github.com/evothings/cordova-ble/blob/7f130823809563033adffb3f13454415d96d096c/src/ios/EVOBLE.m#L652

Actual crash (SIGABRT) occurs inside Cordova in file CDVPluginResult.m line 38 in my code.

I am investigating this further now.

A question, is characteristic.value supposed to hold a value when receiving didUpdateNotificationStateForCharacteristic?

Tested with TI SensorTag CC2541 and CC2650 and get the same result.

ghost commented 8 years ago

Related post: http://stackoverflow.com/questions/29650844/unable-to-get-cbcharacteristics-value-in-didupdatenotificationstateforcharacteri

ghost commented 8 years ago

@robertoandrade I pushed a commit that checks that characteristic.value is non-nil in peripheral:didUpdateNotificationStateForCharacteristic:error: https://github.com/evothings/cordova-ble/commit/55456d4db2a54a57fed64e231f2f993699ca4e1c

The documentation says that didUpdateNotificationStateForCharacteristic is called as a result of setNotifyValue:forCharacteristic:, as a confirmation that the call worked I would assume: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/#//apple_ref/occ/intfm/CBPeripheralDelegate/peripheral:didUpdateNotificationStateForCharacteristic:error:

Do you get values in characteristic.value in peripheral:didUpdateNotificationStateForCharacteristic:error: from your Blood Pressure Monitor?

robertoandrade commented 8 years ago

I get the value just fine in one project but am getting nulls on another... trying to figure out the difference here.

robertoandrade commented 8 years ago

so @mikaelkindborg does that device provide characteristics that have the indicate property or they are notify ones?

robertoandrade commented 8 years ago

Ok, retesting this again, it looks like the correct behavior is that the peripheral:didUpdateNotificationStateForCharacteristic:error: callback gets invoked, just to let you know that the notifying BOOL inside the CBCharacteristic is changing and then it calls didUpdateValueForCharacteristic regardless with the value. when didUpdateNotificationStateForCharacteristic is called, the value is not available yet.

I can't seem to reproduce the original case where I was subscribing for notifications of the indicate tagged characteristic and was not receiving the call to didUpdateValueForCharacteristic. So guessing there is really no issue. If I get it to be reproducible I'll reopen this for discussion or open an new issue.

ghost commented 8 years ago

@robertoandrade Ok thanks a lot for the clarification!

ghost commented 8 years ago

@robertoandrade Forgot to answer your question, no I have not seen the INDICATE property previously. Not really sure I understand it. All BLE devices I have used have as far as I know used "standard" notifications.