Hi Simon,

On Thu, Mar 8, 2018 at 9:18 AM, Simon Ratner <si...@proxy.co> wrote:
> Old thread, but I just bumped into this myself so want to resurrect it.
>
> Current api makes it very difficult to implement a long characteristic that
> changes frequently (e.g. time- or sensor-based reading, or including a
> random component). In the case where mtu exchange fails or does not
> complete in time, the client may receive a mashup of two or more different
> values, if access_cb returns a current value each time. For example, a
> 32-byte value might end up as 22 bytes from sample 0 plus 10 bytes from
> sample 1 -- a combination that does not decode to a valid reading. One way
> around this is to lock in a stable sample for each connection, but that
> becomes harder to keep track of with many concurrent connections.

Reading long attributes is not atomic and there's not much stack can
do about it - it's just what spec says. Trying to make it look like
atomic operation in NimBLE would not be a good idea since there is
probably no good way to do this properly so instead we will end up
with complex code that breaks things.

I suggest to change approach here and instead of trying to read long
value just notify complete value in fragments. For example, add
<value_id> and <fragment_index> to each chunk and client should be
able to reassemble complete value easily without need to read
anything.

> I don't really have a solution yet, just complaining ;) Perhaps nimble
> holding on to the value for subsequent offset reads makes sense after all.
> I guess the difficulty there is knowing when to free it?

This is certainly one of biggest difficulties here. Also note that
attribute values are unique per-connection so this means we need to
store separate copy of value for each connection. This can easily
consume lots of memory and we don't really know if/when it can be
freed to make things work as expected.

I'd say if someone has good idea how such caching could be
implemented, it can be done as separate utility package so one can
reuse it in application easily. I'd certainly not want such thing to
be added to NimBLE directly since it's just not how ATT/GATT should
work according to spec.

> Cheers,
> simon

Best regards,
Andrzej


> On Tue, Jul 25, 2017 at 12:19 PM, Andrzej Kaczmarek <
> andrzej.kaczma...@codecoup.pl> wrote:
>
>> Hi,
>>
>>
>> On Tue, Jul 25, 2017 at 8:14 PM, Christopher Collins <ch...@runtime.io>
>> wrote:
>>
>> > On Tue, Jul 25, 2017 at 10:46:32AM -0700, Pritish Gandhi wrote:
>> > [...]
>> >
>> [...]
>>
>>
>> > > Is this true for notifications too? If I need to send notifications for
>> > > that long characteristic value, will my access callback be called
>> several
>> > > times based on the MTU of the connection?
>> >
>> > Unfortunately, Bluetooth restricts notifications to a single packet.  If
>> > the characteristic value is longer than the MTU allows, the notification
>> > gets truncated.  To get around this, the application needs to chunk the
>> > value into several notifications, and possibly use some protocol which
>> > indicates the total length, parts remaining, etc.
>> >
>>
>> Also client can just do long read in order to read remaining portion of
>> characteristic value
>>
>> - this is what ATT spec suggests.
>> It depends on actual use case, but this way client may be able to decide
>> whether it should read remaining portion of value or skip it, e.g. some
>> flags can be placed at the beginning of the characteristic value and they
>> will be always sent in notification.
>>
>> Best regards,
>> Andrzej
>>

Reply via email to