问题
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.
回答1:
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.
回答2:
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
回答3:
As a starting point the so-called ATT_MTU size determines the number of bytes that can be written. This value is exchanged/negotiating between the two devices. Unfortunately, this value doesn't seem to be exposed in Apple's CoreBluetooth interface :(
But I have just used a BLE sniffer and in my case it was 158 bytes. But then again this value can change over time...
If you write more data than ATT_MTU then the BlueTooth stack may use a so-called Prepare-Write procedure, but not all stacks supports that. Have not tested if Apple supports this...
:)
回答4:
On iOS 9+ you can use this method on each subscribed CBCentral to determine how much data to send per chunk:
[central maximumUpdateValueLength];
回答5:
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.
来源:https://stackoverflow.com/questions/24349945/maximum-data-size-when-sending-data-via-btle-on-ios