I need to receive data periodically through a BlueTooth External Accessory.
I implemented an event-driven model of EA's streams. However, the initial transmission from bluetooth is always delayed. For example, if each packet was 15 bytes long, the stream delegate would not fires until about 150 bytes.
Will polling help?
EDIT:
Also I found it hard to recover the session after the app switching back from background to foreground. Trying to open session again would fail. Any idea?
Read every bytes when NSStreamEventHasBytesAvailable arrives.
Did you develop your own Bluetooth accessory? May be the MCU only flushes after sending every 150 bytes.
Also you mentioned initial transmission. Do you know once the Bluetooth device is paired and connected to iPhone, it has to go through some identification process, handshaking some secret certificate. This may take few and even 10 seconds, depending on signal quality. This may be the cause of delay.
Related
Is it possible on Wear OS to constantly record heart rate data and/or other sensor data in the background and send it via WiFi/4G without a phone?
Can such a service start on boot?
Yes - but if long lived you must use passive updates to get batched data, otherwise you will likely ruin battery life.
https://developer.android.com/training/wearables/health-services
https://developer.android.com/training/wearables/health-services/passive
You can request an LTE or Wifi network to sned data when you have enough to send. But you shouldn't try to keep the network open permanently.
Our application uses the Twilio voice SDKs for iOS, Android, and Web. Our use case relies on precise device synchronization and time stamping. We are playing an audio stream on multiple adjacent devices (in a Twilio conference call) and we need that audio playback to be in sync. Most of the time, it works great, but every now-and-then, one of the devices falls a little bit behind and throws off the whole experience. We want to detect when a device is falling behind (receiving packets late) so we can temporarily mute it so it does not throw off the user experience we are going for.
We believe that Twilio voice uses real time communication (web RTC) and real-time transport protocol (RTP) under the hood. We also believe RTP has time stamping information for when packets are sent out and when packets are received.
We are looking for any suggestions for how we might read this timestamp information (both sent & received) to detect device synchronization issues.
Our iOS and Android clients are built using Flutter & Dart, so any way to look at this packet information using Dart would be great. If not, we can use native channels through Swift and Kotlin. For the web, we would need a way to look at this timestamp data using javascript.
If possible, we'd like to access this information through the SDK. I don't see anything about timestamps in Twilio's voice documentation. So, if not possible, we might have to sniff for packets on the devices? This way, we could look at the RTP packets coming from Twilio to see what information is available. As long as this does not break Twilio terms of service, of course :)
Even if you could get this information I don't think it will be useful. The timestamp field in RTP has little to do with real time. In voice it's actually a sample offset into the audio stream. With a typical narrowband codec with a fixed bit rate and no silence suppression it's completely predictable from the RTP sequence number. For example, with 20ms packets of G.711 it will increment by exactly 160 each packet.
RTP receivers expect there to be random variation between the receipt time of a packet and its timestamp - known as jitter. This is introduced by delays at the sender, in the network and at the receiver. This is why receivers use jitter buffers to reduce the likelihood of buffer underrun on playing. The definition of jitter for RTCP - the interarrival jitter - is a calculation that measures this. That is - the variation between the (predictable) RTP timestamp and the measured wallclock time at the receiver.
Maybe you need something more like an NTP protocol between your client and your server.
I have an Arduino based device interfaced to a 3G modem which I use to record data from several sensors in a remote environment. I would like to be able to send commands and stream some data from the device every now and then back to my standard network connected PC. If the remote device was connected to a WIFI or other local area network this would be relatively straightforward, but as the device connects over 3G this means that it is behind the 3G carriers NAT and so establishing a connection to the device becomes difficult.
The device can, of course, open a TCP connection to my host PC any time it wishes, the problem is telling the device when i want it to do so. I need some way of getting some kind of message to the device to notify it that I would like it to initiate a connection to my PC.
I've been reading up on NAT traversal techniques that app developers use to initiate P2P comms between 2 devices both behind NATs such as UDP and TCP 'hole punching' but this method seems rather too complex for my arduino system. Another general idea is to have the device polling a web server periodically looking for a signal to initiate a connection, but I'm not sure how much traffic (and data usage costs) this would generate as the device would have to poll every 10 seconds or so in order to make sure it initiates it's connection within a reasonable time frame of the request being set on the web server that it polls.
Is there any commonly used method of achieving something like this? Any general ideas or insight would be much appreciated
Thanks,
James
I think the solution will depend largely on your particular applications and requirements.
There are several ways to achieve this type of functionality and it looks like you have covered some of them already. The most common are:
have the device poll the server. This may be ok depending on the response times you need. If you need to poll as regularly as you suggest above then I imagine power may be more important to you than data rates, especially if you are battery connected. With a typical 3G data plan the polling itself will have a negligible data overhead, I would think.
have the server send a SMS which then triggers the device to contact the server. You need to make sure the SMS variable delivery time is ok for you and you also have to be aware that SMS delivery is not guaranteed so you would have to build in some sort of check for delivery at a higher layer (or into your application).
use some low cost Android based device for your 3G connectivity and leverage the Google push notifications mechanism
It is worth noting that server polling typically gets very bad press as it is seems intuitively wasteful to have the client and the server constantly checking for messages, especially when the actual messages are fairly infrequent. However, underneath most push solutions there is still a pull mechanism in the background, albeit generally a very efficient one that may, for example, piggy back on other messages between the network and the mobile device and hence have minimal power and data overhead. Personally, I would say that if you do not have major concerns with battery/power or with the load polling might generate for your servers, then it is worth exploring if the simplicity benefits of a polling solution outweigh its other disadvantages.
I'm trying to create an iOS application that sends data over UDP continuously over wifi/3G network.
I have an issue when I launch my app over 3G network after like 10 seconds I get this message :
sendto() : No buffer space available
It's not that a big deal because my app still works well BUT when I quit the app, I guess my buffer stays full because I can't use 3G anymore (I have to wait some time or reboot my phone)
Is there a way to flush this buffer before I quit my app ?
It sounds as if you're hitting the outbound bandwidth limit. If your app does this continuously while in use, isn't that going to make it very expensive for users to run? Most mobile users, I would guess, are on some kind of metered plan where they pay for transferred data.
I would guess that closing the socket normally before exiting should flush it first, since you've requested the data to be sent after all, but sometimes UDP sockets don't try very hard to deliver the data (since they are "lossy"), perhaps that's what's happening in your case too.
I would like to trigger an event (e.g. play music) on multiple iOS devices at the exact same time (by means of milliseconds)
My approach is to keep a socket connection and send a timestamp to iOS devices (10 seconds later from current time) and trigger the event on iOS devices at that timestamp.
Problem is iOS devices might differ 1 or 2 seconds and that would cause a desynchronize. And even timestamps are pointing out the same time on each devices (AFAIK) they are not on millisecond sensivity.
Is there any way to trigger an event simultaneously on multiple devices, or an approach which should be followed?
Don't send the data over the Internet. You can't assume the connection latency will be low enough for your needs. Use Bluetooth instead. You can do with with GameKit, with dns-sd, or with a library like HHServices.
Pick a device that will act as the controller. Apple provide sample code to do so with GameKit, but it's not difficult to think up your own method. When you want to trigger the action, that controller will send a packet over Bluetooth to the other devices.
I doubt you need lower latency than that, but if you do, have the controller send packets to each connected device to ascertain the latency for each connection, have them send their timestamps to the controller, then the controller should be able to calculate a timestamp for each of them that will occur at the same time.