Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maximum data size when sending data via BTLE on iOS

I am currently implementing an iOS application that uses CoreBluetooth to transfer data between 2 devices. For example, to send data from the central to the peripheral, I use this code:

NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
NSLog(@"Writing data of length %d", [data length]);
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

This works absolutely fine, but the thing is that I have read multiple times now that characteristics can transfer a maximum of 20 bytes at once. Also, when I look at Apple's BTLE Example Code they implement a mechanism that splits the data into chunks of 20 bytes. But the above code prints something like Writing data of length 124 - the data arrives fine at the other device, though.

So: Why is this working at all? And even more so, I am afraid that this could break at some point, especially when non-iOS devices come into play.

like image 506
BlackWolf Avatar asked Jun 22 '14 09:06

BlackWolf


4 Answers

When you write data to the characteristic of remote device by 



func writeValue(_ data: Data, for characteristic: CBCharacteristic, type: CBCharacteristicWriteType) https://developer.apple.com/documentation/corebluetooth/cbperipheral/1518747-writevalue 



you should use

func maximumWriteValueLength(for type: CBCharacteristicWriteType) -> Int https://developer.apple.com/documentation/corebluetooth/cbperipheral/1620312-maximumwritevaluelength



to figure out the size of chunks to split your data into.

like image 114
Petro Novosad Avatar answered Sep 19 '22 09:09

Petro Novosad


On iOS 9+ you can use this method on each subscribed CBCentral to determine how much data to send per chunk:

[central maximumUpdateValueLength];
like image 21
dead_can_dance Avatar answered Oct 19 '22 20:10

dead_can_dance


The BLE standard requires 23 bytes as the minimum ATT_MTU (Attribute Protocol Maximum Transmission Unit) which all BLE devices must support. The maximum ATT_MTU is 255 bytes, however, and has been doubled again for BLE 4.2.

BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part A]:

All L2CAP implementations shall support a minimum MTU of […] 23 octets over the LE-U logical link; however, some protocols and profiles explicitly require support for a larger MTU.

When establishing a connection, both devices will exchange their ATT_MTU size, and the smaller of both values is used. When Apple started with BLE, they would only support the minimum, but have since expanded the possible size. That is why your 124 bytes work, but the older documentation and sample code uses a much smaller ATT_MTU.

like image 3
Peter Kämpf Avatar answered Oct 19 '22 20:10

Peter Kämpf


I'm using iOS 7.1.1 and have also found that I can send as much as 132 bytes reliably from an iPhone to an iPad using BLE. I also heard that 20 bytes was the max but it sure doesn't seem like it is

like image 2
Olivia Stork Avatar answered Oct 19 '22 22:10

Olivia Stork