I'm building a portion of an app that will require the user to download files of varying size. Currently, I'm using Apple's Reachability code to let me know if I have a connection.
(http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html)
While the reachability code can keep track of 'having a connection', it doesn't have an ability to let me know of a worsening connection. It would seem that I need to expand on the functionality of the Apple code to meet my requirement. Is it possible for me to measure the number or percentage of dropped packets during the data transfer? This would be helpful so I could message the user and be able to pause or stop the download.
There is no iOS API available that hooks deep into the networking stack that tells you when and why packets are dropped. It could be dropped at a router or it could be dropped locally because of a checksum error.
What kind of data is it? I assume TCP.
You might be able to infer the quality of the connection by examining the throughput rate. You can count how many bytes you receive per second.
TCP has something called congestion control and the end hosts (iOS devices) will throttle back their throughput as packets are dropped and go unacknowledged. So throughput may correlate with network quality. However, your throughput rate may vary for many reasons such as network congestion, packet shaping, QoS, etc.
iOS does not have a public API to monitor the wifi signal strength. There is a private API but your app would not be approved in the app store if you use the private API.
Related
When the device is in confirmed mode, it waits for a downlink confirmation (ACK) from the network after each uplink. If the confirmation is not received by the device, it will repeat (up to a maximum of 8 times and increasing the SF of the UL if it was lowered before) the uplink until it receives a confirmation. It may take about 30 seconds to send the 8 repetitions.
If the device does not see a confirmation and needs to send another uplink (e.g. alarm or new periodic measurement), it will send the new uplink and forget the previous one. To operate in confirmed mode, the device must be declared in confirmed mode (or ACK) on the network platform. You can activate it via the IoT configurator in the network parameters
Be aware that this operation consumes much more battery power than a traditional operation, even more, if the network quality is poor.
If the transmitter loses a lot of frames, it would be better to reposition the transmitter (if possible) or the GW (if possible) to improve the transmission rather than activating the ACK which will drain the battery faster than "expected" depending on the network condition.
Is this answer correct or not?
Description - How I can get the number of BLE connection in iOS.
I want to restrict a user to add more BLE sensor after a particular number of BLE connection. I want to get the number of a BLE connection a device can handle.
A connection represents state, not traffic. The count of connections will be bound by either memory or the data structures used by the Bluetooth stack to manage them, both unknown. My answer is, "As many as it can and no more."
Packets represent traffic and each is handled one at a time. From this perspective, my answer is, "One."
However, if a packet cannot be processed out of the critical paths in the chip and protocol stack fast enough to begin processing the next packet, packets can be dropped. Experience has shown these critical paths in iOS are dependent on the traffic's packet size and rate. Additionally, other devices in the area not connected to your BLE stack may be flooding the radio spectrum and causing packet collisions outside the stack. I have seen BLE traffic go to hell with an excess of 20 connections and as few as one. From this perspective my answer is, "It depends."
Apologise for the probably use of the wrong word in my question but for the life of me I can't think of the right one.
Anyway, I've been playing about with the Bluetooth Low Energy and I'm trying to create something that is going to use the RSSI signal strength the BLE device emits. For this, I need it to emit its pulse multiple times per second.
Is there a way I can up the amount of times my devices either scan for a signal, or broadcast their signal through code on iOS devices?
No, there is no API for you to change the advertisement speed or radio power.
This aspect is fully controlled by the system. You can only start and stop the advertisement and add some metadata to the packets: device local name, advertised services, etc. Moreover, the contents of the advertisement packets will differ depending on whether your app is in the background or foreground and, additionally, in background it will be slowed down. These effects have been documented in various SO questions and in the header files.
If your clients are iOS applications, then they should use either the RSSI in the advertisement packets (centralManager:didDiscoverPeripheral:advertisementData:RSSI: method) or when connected, the readRSSI method on the peripheral object (just make sure you don't call it too often).
I am trying to understand BLE and GATT in more depth. My interest is in the max achievable number of reads you would able to make per second over the GATT profile.
I am aware of some of the post made on this topic before, for instance:
Bluetooth Low Energy - updating a characteristic value repeatedly
However, I am trying to explain these results looking at the BLE specification.
What is the relationship between connection events and GATT? Does each ATT read/write require a new connection event? If not, is it possible to say anything about how many ATT read/writes can be made per connection event?
Say I want to poll a BLE connected light sensor for a single byte value, what would be the max Hz I could achieve? Would it always be best to set the mininum connection interval as low a possible?
Would I be able to achieve better results using "GATT server notifications? In the BLE spec (Core_v4.0) it says that "The master initiates the beginning of each connection event". Then how are GATT server notifications implemented? I would think that would require the server to initiate a connection event.
Finally, if anybody knows about any specific iOS imposed limitations on the throughput I would be able to achieve when polling a sensor intensively, I would love to hear about it.
I can answer a portion of of those questions...
What is the relationship between connection events and GATT?
They're different levels of the protocol. You handle connections and connection events via HCI. GATT is something you use after you've connected.
Does each ATT read/write require a new connection event?
No. Once you're connected you can do multiple read/write or other GATT commands.
If not, is it possible to say anything about how many ATT read/writes can be made per connection event?
I think the best method is to actually benchmark the speed yourself. However, the whole point of BLE is a reduction in power usage at the expense of speed. If you're concerned about speed that you probably shouldn't be doing it with BLE. The whole point of notifications/indications is so you don't have to poll an attribute but only get a message when a certain event has occurred.
Say I want to poll a BLE connected light sensor for a single byte value, what would be the max Hz I could achieve? Would it always be best to set the mininum connection interval as low a possible?
See above 2 answers.
Then how are GATT server notifications implemented?
Once you've implemented a GATT connection there's 2 way communication going on between the master and slave-device. Either device can send events to the other. In order to use notifications, you set a bit on a particular attribute to say you want notifications on that information. Then, depending on how that notification works, you'll get events sent back to you whenever there's something to report. I have a feeling that a lightbulb wouldn't have any sort of notification unless there's some interface on it besides the BLE connection. I typical application would be something like a thermometer where it would send a notification every time the temperature changed by 1 degree.
Conclusion:
If you're polling attributes you're doing it wrong. But it's possible that you have to do it wrong because the device didn't properly implement notifications in the way you need and you can't modify the device. However, polling will ramp up the battery usage significantly and you'll have loss the benefit of using BLE.
While I realize that AirPlay has inherent lag/latency, I'm wondering if there's a way for a (currently hypothetical) iPhone app to detect what that latency is. If so, how precise can that latency value be? I'm more curious in whether an app can "know" its own AirPlay latency, rather than simply minimize it.
The latency does not come from network jitter, but rather is decided by the source device (your iPhone).
Long story short:
It's always precisely 2s (down to the millisecond) with Apple devices.
There is no way to tweak it with public APIs.
Audio latency needs to be very accurate so that multiple outputs can play in sync.
Some explanations about AirPlay's implementation:
The protocol starts with several RTSP commands. During this handshake, the source transmits rtpTime, the time at which the playback starts, which is also your latency. The typical value is 88200 = 2s x 44100 Hz.
AirPlay devices can sync their clock with the source's with NTP to mitigate the network latency.
During playback, the source periodically sends a SYNC packet to adjust the audio latency and make sure that all devices are still in sync.
It's possible to change the latency if you use a custom implementation, but Apple usually rejects them.
Check this writeup for more information. You can also read the unofficial protocol documentation.
The short answer is: no, Apple does not provide a way to do this. Assuming you need your app to be approved in the App Store, you're sort of out of luck. If you can run your app on a jailbroken device you can search around for undocumented APIs that will let you do more.
If you need your app to be available in Apple's App Store, most things you can do network-wise are outlined in the "Reachability" sample app.
The only way I can think of to get a good guess would be to use Bonjour to identify the host (see sample code here https://developer.apple.com/library/ios/#samplecode/BonjourWeb/Introduction/Intro.html) and then ping the host.
However:
If there is more than 1 Airplay station you will need to guess or ask which the user is connected to, or maybe take an average.
The device may not respond to a ping at all (Apple TV and Airport Express both respond to ping, not sure about 3rd party devices.)
The ping may not reflect the actual latency of the audio
Instead of spending too much time on this, you should follow Apple's guidelines for preparing your audio for AirPlay and enriching your app for AirPlay: http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AirPlayGuide/PreparingYourMediaforAirPlay/PreparingYourMediaforAirPlay.html#//apple_ref/doc/uid/TP40011045-CH4-SW1
Hope this helps! :)
You can query iOS's current hardware audio latency by -[AVAudioSession outputLatency],
According to the document for outputLatency:
Using an AirPlay enabled device for your audio content can result in a 2-second delay. Check for this delay in game content.
And according to my experience, this value changes when switching output device, eg:
Speaker: ~10ms
Bluetooth: ~100+ms
AirPlay: 2s