Allan,
I don't get your "configuration swap" description. As I understand, you have two
iPhones. If iPhone A is peripheral and iPhone B is central, it doesn't work. If
iPhone A is central and iPhone B is peripheral, it works. Are these assumptions
correct?
If yes, try building a minimal example and building two apps, one
peripheral only and one central only, so that you can rule out bugs in your
real application.
Another issue may be that you use an encrypted link between your iPhones. As
soon as you have a bond, characteristic and service information may be cached.
Try to read the characteristic properties on your central side to make sure that
notifications are not anymore available, but only indications are set.
If you want to completely reset iOS Bluetooth state, a "Reset All Settings" is required.
This also clears the UUID cache and UUIDs of all devices will appear again as
"nil" before the first connection.
Also, do you wait until you receive the acknowledgment for the indication on the peripheral side
before you send another one? Bluetooth Low Energy supports only one indication at a time.
Packet sniffer:
Yes, it's that packet sniffer that you linked with the physical device that you linked.
The software can be downloaded on the first page. Unfortunately, it's Windows only
and is not the most stable piece of software. Have not tried it under VMware or
Parallels. However, the software is free and you can try to run it in a virtual Windows
environment.
On iOS, as far as I know, you cannot specify which of the advertising channels to use
as a peripheral. Therefore, you will only succeed with this sniffer with a 33% probability,
as you have to listen on the same frequency as the connection occurs. As there are three
advertising channel and the iPhone most probably is using all of them, the 33% chance
is deduced. In my opinion, it's still a better option for your use case than the other sniffers
that have price tags that are up to three magnitudes higher.
Etan
wrote:
Hi Etan,
Thanks for your helpful reply.
Just now I tried switching this over to use an indication instead of a notification, and I still encountered the issue.
Interestingly, in my test app running on two devices, if I switch them in terms of which one is running as a central vs peripheral, then the indication/notification works in this swapped configuration. I wonder why one of the configurations
doesn't work.
Semi-related: in post to this mailing list in mid-2012, a contributor wrote that the onSubscribedCentrals array in the updateValue call should be an array of UUID's, rather than CBCentral*'s, despite the documentation on this. Which
way is correct?
Thanks and regards,
Allan
From: Etan Kissling < email@hidden>
Date: Fri, 11 Jan 2013 09:46:10 -0800
To: Allan Morgan Young < email@hidden>
Cc: " email@hidden" < email@hidden>
Subject: Re: Core Bluetooth > Subscribed characteristic sometime not getting updated in Central
Allan,
Bluetooth Low Energy supports two modes for pushing data form a peripheral
to a central: notifications and indications.
Indications can only be sent once at a time, and you receive a confirmation that
they have been received by the remote device correctly.
Only one indication can be sent at a time, restricting the available bandwidth,
because only one packet can be sent every 2 connection events.
Notifications can be sent at any time, but you won't receive any confirmation that
they have been received. iOS restricts the number of packets that you can send
to ~ 4 per connection event. After exceeding this limit, any additional notifications
will be dropped.
Because you experience packet loss, I assume that you are currently using
notifications.
If you change your peripheral characteristics from Notification to Indication, the
packet should always get through - although at a slower speed. However, you
can adjust the connection parameters to achieve higher throughput.
For changing peripheral characteristics from notification to indication, just change
the CBCharacteristicProperties in your initialization routine. Note, that for both
notifications and indications, the central will report isNotifying = true, even if you
are using indications.
On iOS, when using the fastest connection parameters that fall under the Apple
Guidelines for Bluetooth Accessories, around 2 kbit/s can be achieved using indications,
and around 16 kbit/s for notifications, if both devices are reasonable near to each other.
/*!
* @method initWithType:properties:value:permissions
*
* @param UUIDThe Bluetooth UUID of the characteristic.
* @param propertiesThe properties of the characteristic.
* @param valueThe characteristic value to be cached. If <i>nil</i>, the value will be dynamic and requested on-demand.
*
@param permissionsThe permissions of the characteristic value.
*
* @discussionReturns an initialized characteristic.
*
*/
- (id)initWithType:(CBUUID *)UUID properties:(CBCharacteristicProperties)properties value:(NSData *)value permissions:(CBAttributePermissions)permissions;
CBCharacteristicPropertyNotify= 0x10,
CBCharacteristicPropertyIndicate= 0x20,
If you are already using Indications, make sure to only send a new
indication after you received the confirmation that the last one went through.
You can use this method in order to achieve this:
/*!
* @method peripheralManagerIsReadyToUpdateSubscribers:
*
* @param peripheral The peripheral manager providing this update.
*
* @discussion This method is invoked after a failed call to @link updateValue:forCharacteristic:onSubscribedCentrals: @/link, when <i>peripheral</i> is again
* ready to send characteristic value updates.
*
*/
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral;
If this still does not solve your problem, consider purchasing a packet sniffer (available
by TI for around 50 $) to get an air trace. With the sniffer, you can see exactly what packets
are sent over the air and should be able to determine if your issues may be related to iOS
behavior or if the fault is in your application code.
Etan
Hello,
Running a Core Bluetooth test app on two iOS 6 devices, I notice that
*sometimes* I will not get a didUpdateValueForCharacteristic for a
characteristic that my central has subscribed to.
My peripheral sets up the service with this characteristic having notify
properties. (My service also has a writeable propertyŠsee below.)
The central, after connecting the peripheral and receiving
didDiscoverCharacteristicsForService, subscribes to the notify
characteristic. didUpdateNotificationStateForCharacteristic gets called,
with the characteristic's isNotifying flag reporting YES.
My central writes to the peripheral via the writeable characteristic
mentioned above.
In the peripheral's didReceiveWriteRequests, I read what the central wrote
to us, and in this same method I call
updateValue:forCharacteristic:onSubscribedCentrals: to write some data to
the notify characteristic that the central has subscribed to. The
updateValue:forCharacteristic:onSubscribedCentrals: call returns YES.
At this point, often in the central, didUpdateValueForCharacteristic does
not get called in this workflow.
Any ideas on this?
Thanks.
Allan
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Bluetooth-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
|