I am trying implement an APP with BLE function.
Tried to get data back from UpdatedCharacterteristicValue().
But I found out that when I am expecting to receive about 200 bytes long data.
On my iPhone 12 Pro(iOS 15). It works fine.
On my iPhone 8(iOS 12). It's not working.
If I am expecting to receive about 60 bytes long data.
Both device works fine.
What would be the difference between these two device that cause this result?
Check the negotiated ATT MTU after the connection is established and use it to determine the maximum characteristic size.
The maximum characteristic size you can use on the link is ATT MTU - 3, as 1 byte is used for op-code, and 2 bytes as attribute handle.
Related
I have a custom BLE peripheral that can send a notification data packet to a central. The device sends packets of 234 bytes at a time, and the central is expected to register for notification of characteristic updates on the device. Peripheral is sending the 234 bytes of data to central but iOS device receiving only 182 bytes of data in the didUpdateValueForCharacteristic function.
In android, The central software just works with no problems and the phone (central) receives 234 bytes in a single notify event. - this works just fine in Android but having an issue with iOS devices.
Is there any configuration required for the iOS device to receive the full length of data from the BLE peripheral? Any help would be appreciated!
iOS devices have a maximum ATT_MTU of 185 bytes, which means you can send a maximum of 182 data bytes per packet (the other 3 bytes are overhead for L2CAP). In the beginning iOS devices only supported 158 bytes and then this was increased to 185.
The way ATT_MTU works is that there's a negotiation upon connection where the central sends its maximum ATT_MTU (i.e. for iPhones it is 185) and the peripheral replies with its own ATT_MTU (i.e. in your case it is 237), and then the connection's ATT_MTU will be the minimum between the two (i.e. 185). So to answer your question, no there isn't a way to configure your iOS device to send the full length of data because this is a low level configuration that Apple don't allow access to.
Have a look at the following links for more information:-
iOS BLE Get Negotiate MTU
Maximizing BLE Throughput Part 2: Use Larger ATT_MTU
A Practical Guide to BLE Throughput
I have a quick question regarding BLE packets with iOS.
Say I have an iPhone app that sends out BLE advertising packets once a second in the background. This same app is also configured to receive advertising packets in the background. Say there are 30 other devices running this same app within Bluetooth range of the original device. Is there a theoretical maximum to the amount of packets any one device can receive within a given time interval? Could the app receive and process all the advertising packets from the thirty phones, or even 100 phones? Thanks for your help!
Depends on peripheral advertising speed/interval. If you have 20 ble device around ios device and start scan.
Then first get nearest device and which devices who advertising interval is fast.
Well the BLE advertisements run at 1 MBit/s so that means one microsecond per bit.
In an advertisement packet the overhead is, on top of the advertisement data, the address of 6 bytes and then 10 bytes extra for BLE header and CRC.
If two packets are transmitted by two devices at the same time, they will interfere and possibly none of these packets can be detected at all.
With this information you should be able to calculate the rest of the Math yourself.
I'm Working on iOS Application(Objective-C) for Bluetooth watch which using BLE(CoreBluetooth), and my watch is having GATT Bluetooth Profile, iOS application minimum support is from iOS7.
I wants to know How can we do data transfer between iOS device and external device using Core Bluetooth framework.
Actually I'm working on the Firmware upgrade section of my Bluetooth watch,
My iOS application will get Firmware code (binary data) from web service whenever any update received and then it will send data to Bluetooth watch.
I have searched and got one Apple Sample code:
BTLE_Transfer: https://developer.apple.com/Library/ios/samplecode/BTLE_Transfer/Introduction/Intro.html
I guess sample code was not useful in my case as its having Central and Peripheral both code and transferring data between two iOS device.
is there any other way apart from this sample code for BLE data transfer? or it's possible with this sample code only?(if yes how?)
UPDATED:
My device have 1 service which have 2 characteristic one for read and one for write.
According to my workflow using write charateristic:
Using WRITECHARACTERISTIC I'm sending data of firmware code in chunks
[MYDEVICEINSTANCE writeValue:NSDATACHUNK
forCharacteristic:WRITECHARACTERISTIC
type:CBCharacteristicWriteWithResponse];
and in delegate method "didWriteValueForCharacteristic" method I'm notifying read characteristic as below
[MYDEVICEINSTANCE setNotifyValue:TRUE
forCharacteristic:READCHARACTERISTIC];
which calls "didUpdateNotificationStateForCharacteristic" delegate method inside that I'm checking if READCHARACTERISTIC isNotifying or not then I call
[MYDEVICEINSTANCE readValueForCharacteristic:READCHARACTERISTIC];
which call delegate method "didUpdateValueForCharacteristic" and I'm reading response using READCHARACTERISTIC.value
My query:
I wants to confirm MTU maximum limit allowed by Apple for External device communication from iOS application, which I'm starting in step-1 by sending NSDATACHUNK to BLE Watch from iOS app using writeValue
I have tested that I can send NSDATACHUNK of MTU=255 size and BLE watch is receiving same successfully.
I have found in "Apple Sample code: BTLE_Transfer" they are using MTU=20 but, I guess that sample code is for iOS device to iOS device communication (Please, correct me if I'm wrong)
So, If I use MTU=250 in my iOS application for BLE communication is there any chance that apple will reject my Application?
Or is there any one that can say what is the maximum limit allowed by Apple for MTU?
Every suggestion are appreciated,
Thanks in advance
You can use whatever MTU size you want (up to 512).
The value that the connection will use is always the minimum between yours and theirs.
So, if for example they want to use MTU equal to, let's say, 50, then if your MTU is lower than 50, that one will be used; otherwise, whichever value you select above 50 is meaningless, as 50 gets picked.
After connect your device yo your app you should have to write a "characteristic" with:
[YOURDEVICEINSTANCE writeValue:NSDATAVALUE forCharacteristic:YOURCHARACTESITIC type:CBCharacteristicWriteWithResponse];
We spent a lot of time working with my custom BLE device and my conclusion was:
The connection is asymmetric. (you will spent 5ms to transmit from your BLE device to your app and 20ms from your app to your BLE device)
On an iOS device, the available mtu is 20. It means that you can send 20 bytes of data every time when you set it up as BLE peripheral. If you want to communicate for more than 20 bytes, you have to handle that yourself, referencing the APPLE Central Peripheral sample code
In your case, the problem is not the mtu of iOS device but your external BLE device, because your BLE device is the peripheral device. Since your BLE device is capable of transmitting a large amount of data - 255 bytes, it will be fine to have that mtu.
The maximum MTU is negotiated between the participating devices on a low level. CoreBluetooth makes this value available via CBPeripheral's maximumWriteValueLength(for: …).
That said, unless you exactly know the behavior of your BLE peripheral, I'm afraid you can't rely on this value. There are devices out there which claim to support the BLE 5.0 specification with QUEUED WRITES – which would lead to pretty high MTUs, such as 512. They do NOT implement it though, thus packages larger than their native MTU will get silently truncated and as of iOS 14, iOS will not detect this!
I'm playing around with CoreBluetooth in iOS 7, and have successfully got two devices sending quite a large amount of data between each other (one is the central, one is the peripheral).
Between an iPhone 5 and 4S I had an MTU of 20 bytes, and between an iPhone 5s and iPhone 5 I had an MTU of 132 bytes. The size is much larger, so I assumed fewer individual messages would be sent and therefore the overall time of the transfer would decrease.
Unfortunately the time remains pretty much the same in both scenarios (around 15 seconds). Was my original assumption incorrect or is there something I may be doing wrong?
L2CAP has MTU of 20 bytes. If you want to send data of more than 20 bytes, it is sent in multiple packets. Most likely the 132 bytes are being sent in 7 packets at the same rate as 7 20-byte packets. So the throughput is the same.
We are developing a BLE sensor Peripheral to work with an iPad, that requires the following throughput of data on the BLE notification characteristic (no acknowledge) using a TI CC2541 BLE module and a custom profile:
One 20 bytes (GATT maximum standard packet) every 10ms, or since we appear to have a limit of 4 packets per connection interval, this equates to one connection interval every 40ms. Throughput required is 2,000 bytes per second, the TI website recommends the CC2541 BLE solution be used for several sensor devices requiring this level of data throughput.
The profile for the BLE module is set with min and max connection intervals of 20ms and 40ms respectively, which should suffice. The "Bluetooth Accessory Design Guidelines for Apple Products" document suggests that the minimum and maximum connection intervals we set, as above are correct. We are using the latest iPad and Apple tools for iOS 6 on a new Mac Mini / Mac Book.
With a simple test program on the iPad, we can get the link to work well sending 20 byte packets to the BLE Peripheral at intervals of 20ms, however once we lower this to 10ms as required we start loosing packets or getting corrupt packets, we have the FIFO empty interrupt turned off so we can handle the sending to the BLE module FIFO quicker, and we are using the maximum Baud rate of 230400 to send the 20 byte packets to the BLE TX FIFO from the micro.
We realise we are at the top end of the BLE transfer limit, and of what is possible. Can anyone advise if there is a solution to achieving 2000 bytes per second throughput using the TI CC2541 BLE chip / module with an up to date iPad?
We use TI 2540 (BLE stack version 1.3.2) succesfully with iPad/iPod/iPhone (iOS 6.x and 7.x). We currently send 75 notifications of 20 bytes per second => 1500 bytes/second. But I have tried to send 125 notifications and that worked as well.
Of course the more you send the greater likelihood of loosing data, e.g., less time to resend a NACK'ed message.
I have experienced that iOS' BLE stack may enter a mode where it begins to NACK messages continuously. If this happens you will loose a lot of messages. I have reported an error to Apple about this. (This problem seems to have been fixed in iOS 7.1.beta3/4.)
I currently have:
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 10
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 20
Yes, it doesn't conform with Apple's guidelines. But I believe they can be relaxed in our case.
UPDATE: I have also tried to use an iDevice as peripheral, i.e., BTLE between two iDevices. Here I have sent 150 messages per second without any problems.
Are you sending "write without response" commands? You can send 4 packets per connection event this way. Using you previous 20ms connection interval, you would be sending 4 packets with 20 bytes every 0.02 seconds. Putting that together: 4*20/0.02 = 4000 bytes per second easy.
I highly doubt you are getting corrupt data. The link layer adds a CRC and a 2 bits of "next expected" to BLE packets to ensure A) all the bits are received correctly and b) packets were not sent out of order. The TI stack and iOS control the link layer so I doubt you've botched that.
Here are few observation on throughput that we found during our RnD on iPhone with BLE. The below data is based on write with response.
iPhone 8 (BLE 5.0) as Central and Linux desktop (Ubuntu 16.04 with BLE dongle 4.0): MTU = 2048 : Throughput - 2.5 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and Android OS with BLE version 4.2 as Peripheral(Xiomi Mi A1): MTU = 180 : Throughput - 2.5 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and iPhone 7 plus (BLE 4.2) as Peripheral : MTU = 512 : Throughput - 7.1 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and Samsung S8 (BLE 5.0) as Peripheral : Samsung S8 failed to work as peripheral
iPhone 8 (BLE 5.0) as Central and iPhone 8 plus (BLE 5.0) as Peripheral : MTU = 512 : Throughput - 15.5 KiloBytes per sec.
As you can see, as the MTU value increases, we get maximum throughput. But we cannot increase to any limit. The above MTU values are the default maximum allowed MTU value as per the given configuration. [MTU - Maximum Transmission Unit. i.e maximum bytes that can be sent in one write request]
Comments are welcome to the above data.
iOS 7 seems to have made some optimizations regarding the throughput levels for BLE transfers. Try it again on an iOS 7 device.
You don't really pose a question, but I can verify that your desired limit of 2000 bytes/sec is possible.
check out the selected answer on this forum post (http://e2e.ti.com/support/wireless_connectivity/f/538/p/353327/1244676.aspx#1244676) to see how we made it work.