iOS DHCP Request - ios

I have observed from a wireless packet capture in my home network that anytime my iPhone device switches from asleep to active, and it is not attached to a power source, it sends a DHCP Request. I have validated this behavior with two different iPhones (with different iOS versions). I have also tested an Android device and this does not happen.
Hence this makes me wonder why does an iPhone need to send a DHCP Request, once switched from asleep to active, if the DHCP lease has not expired? In addition, why doesn't this happen in an Android device?
I am pretty sure this is not an issue related to a bug, such as the one reported in
http://www.net.princeton.edu/apple-ios/ios41-allows-lease-to-expire-keeps-using-IP-address.html

If the device thinks it has an unexpired lease, and the device's network interface has just brought up physical LINK, then that the client should start in the DHCP INIT-REBOOT state (or even INIT state).
Alternatively, if the device thinks it has an unexpired lease, and has kept LINK up continuously since going to sleep, then the client could start in the BOUND state when awaking.
Basically the main reason that the devices react differently is the way they handle the sleep mode (most iOS will disable the wireless interface, whereas in Android it is configurable in the menu).

Related

When does iOS display "need to bond" dialog?

I am writing an iOS app that communicates with a BLE device that we are developing. Most communication does not require bonding, but there are some secure features where bonding will be required. I've put those secure features in a separate service which has been flagged as requiring bonding, and when I try to access that service iOS correctly starts the bonding process.
The problem I'm having, is that I want to be able to control exactly when this bonding takes place so I can design my UI appropriately. Most of the time, iOS waits until I try to access the secure service before it starts the bonding process, but I have also seen the bonding dialog appear shortly after I call CBPeripheral.DiscoverCharacteristics() and long before I actually use the secure service for anything. The bonding dialog seems to appear later if I'm re-running the app when I've already bonded once and then deleted the bonding both in iOS and the remote BLE device.
I'm guessing that iOS is caching the service/characteristic information, so after the first connection when I call CBPeripheral.DiscoverCharacteristics() it's not actually communicating with the remote BLE device, and thus isn't triggering the need to bond.
There's a discussion about how to clear the bluetooth cache on OSX, but nothing similar for iOS. I've tried this:
Unbond device in iOS
Turn off Bluetooth
Turn off iPad
Turn iPad back on
Turn Bluetooth back on
But the bonding request dialog still comes later, which I'm guessing means the cache didn't actually get cleared.
If the devices are unbonded and the peripheral sends an SMP "Security Request", it will show the popup.
It also shows it when you try to interact with a protected characteristic.

Failure to reconnect after De-authentication from Cisco AP Wifi

Apologizing in advance, I am no 802.11 expert and this is a long winded question...
I am working on an iOS voip client, we use the Cocoaasyncsocket library for our TCP/UDP connections. The app/iDevice is allowed to roam in/out of wifi coverage (for the purposes of this discussion we will assume the app is using wifi only... no cellular connection). We have the appropriate plist settings for backgroundmode (voip, audio) as well as requiring persistent wifi.
We are having a problem that seems particular to Cisco AP's. With the client app in the foreground and roaming out and in of wifi range, we noticed that eventually the iOS device will eventually not automatically rejoin the network. After a great deal of debug the failure to rejoin was noted to have nothing to do with the app. The failure to re-join can ultimately be reproduced by forcing the AP (via config) to deauthenticate the iDevice three times. After the 1st and 2nd deauthentications, the iDevice readily automatically re-joins. But after the 3rd time, iOS does not automatically rejoin the network.
The network will be rejoined if, for example, the iOS email app is put in the foreground.
We were curious if any other VOIP type apps suffered this problem, and ran an experiment with running FaceTime and Skype on the iOS device.
Skype behaved much like our voip app, after the 3rd deauth the connection was lost. Trying to initiate another call resulted in a message to the effect of "must have an internet connection to make a call".
FaceTime did disconnect on the 3rd deauth and failed to automatically rejoin... however, we were able to re-initiate another FaceTime call which caused iOS to rejoin the network and make the call.
We would like to emulate the FaceTime behavior, but so far do not understand what we should be doing differently. To the best of our knowledge, we are properly closing the open sockets when we get disconnected. Is anyone familiar with this issue and have some insight to offer?

CoreBluetooth: detect device out of range/ connection timeout

I am designing an iOS framework to handle multiple BLE devices (all of the same kind). Everything is working very well at the moment, except one thing:
The client wants a list with available devices. But how can I detect when a device, that has been discovered in the past, is not available anymore?
Another problem occurs, when I try to connect to a device that is not available anymore. Documentation says: Connection attempts never time out and
And yes, I never get an error via didFailToConnectPeripheral.
I did some research but couldn't figure out how handle these problems via CoreBluetooth properly. So I developed my own solutions, but I am not sure if that is the right way (or at least a good way, cause there may be several ways to do it).
1. Detecting devices that are not available anymore
I scan with
[_centralManager scanForPeripheralsWithServices:services options:#{CBCentralManagerScanOptionAllowDuplicatesKey: #(TRUE)}];
so I receive advertisments all the time as long as a device is not connected. I check with a timer that the advertisement reoccured in a given time interval (large enough corresponding to the devices ad interval). If the advertisement didn't occur in the interval, I remove the device from the list.
2. Detecting connection timeout
Well, that's a pretty easy one I think. I use my own timeout function and cancel the connection request if the timer expires.
If somebody ever came across these problem, I would be very interested in your opinion and/or your solution of course.
UPDATE 2014-12-17:
In the meantime I worked on my own solution using timers and it seems to work pretty well.
Connection timeout is straight forward. Simply set a timer to 5 seconds or whatever you think is good for you. If the timer expires and the device did not connect, simply cancel the connection and tell the user that there was a problem.
Detecting devices that go out of range was a bit trickier. For every discovered device I start a timer that fires after double the time, the device sends advertisements. If the device does send another advertisement till the timer expires, it probably went out of range or was turned off or connected to another device.
I don't want to answer my own question because I hope that maybe Apple will one day take care of those problems.
The correct way to determine whether a device is available is to store the peripheral identifier value. Before you attempt to reconnect, call retrievePeripheralsWithIdentifiers. However, this still does not guarantee that the device will be in range by the time you attempt to connect!
Connection attempts do not time out at the OS level, and this is explicitly documented.
Some apps may need to use the Core Bluetooth framework to perform
long-term actions in the background. As an example, imagine you are
developing a home security app for an iOS device that communicates
with a door lock (equipped with Bluetooth low energy technology). The
app and the lock interact to automatically lock the door when the user
leaves home and unlock the door when the user returns—all while the
app is in the background. When the user leaves home, the iOS device
may eventually become out of range of the lock, causing the connection
to the lock to be lost. At this point, the app can simply call the
connectPeripheral:options: method of the CBCentralManager class, and
because connection requests do not time out, the iOS device will
reconnect when the user returns home.

"Internet connection is offline" when connecting to AP without internet access - WiFi off/on fixes

BACKGROUND
We're trying to use an iOS app running on iPhone/iPad to give WiFi credentials to an embedded device (using an ARM SoC running Linux). The embedded device starts an AP (access point), we instruct the user to connect to this AP and then the user submits their WiFi credentials. After WiFi credentials are received the device drops the AP and connects to the WiFi the user gave credentials for.
Initially, we try to hit a PHP page to get the list of WiFi networks the embedded device can see.
ISSUE
We instruct the user to join XYZ network (in iOS they must background the app, go into settings and switch to our WiFi network). We listen for an app resumed from background notification, check the devices current ESSID (ensure its our AP ESSID) and try to hit a PHP page to receive the list of WiFi networks. Often, this connection fails reports "The internet connection appears to be offline" (or something of that nature).
We currently have a stop gap when this happens telling the user to toggle their WiFi off and then back on (in settings). The device will reconnect to our AP as it's the most recently connected network. This ALWAYS fixes the issue, we've never had to toggle the WiFi twice in order to reach the PHP page on the device. Please tell me any possible way we can avoid having to instruct the user to toggle WiFi and still access PHP pages on the embedded device.
Note: when we're connected to the AP (whether this bug is active or fixed) the device DOES NOT show the WiFi icon in the status bar. We assume this is because the AP doesn't have a viable connection to the internet (can only access pages served by the embedded device). We've been testing on a device that has LTE cellular access, but the error still says "Internet connection appears to be offline".
Obviously we have a DHCP server running on the embedded device.
It's looking like this was caused by an omission in our dhcpd.conf file.
This omission was causing iOS to believe the connection was unviable.
We added the following line and are getting much better results:
option domain-name-servers 10.10.10.1;

Is it possible to build socket connection between 2 iOS devices

Is it possible to build a socket connection between 2 iOS devices connected to the same network (Without net)?
if it's possible .. Is (CocoaAsyncSocket project) useful for me?
I just want to send a message from Device A to Device B which put the app in background .. when Device B receive the message should show notification to return the app to foreground.
It's not for the App Store, so I don't care if Apple would reject the app because of this behavior.
Yes, you can do it, and yes, CocoaAsyncSocket would be useful. If you don't have to worry about the carrier network's firewalls and filters, then you should certainly be able to build a client-server app running on two iOS devices. One opens the server socket to listen, and the other one (the client) connects, via the Wi-Fi network.
Trying searching on Google (e.g. "CocoaAsyncSocket iPhone iOS site:stackoverflow.com") or directly here on Stack Overflow.
Here's somebody who seems to have accomplished this
Another link
And a post from Robbie Hanson himself, referring you to the EchoServer projects in the github repository
EchoServer project
You may have to use a static IP address for the server device (I'm not sure how much control you have over the Wi-Fi network's configuration), or use some other mechanism for letting the two devices discover each other.

Resources