When does iOS display "need to bond" dialog? - ios

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.

Related

How to get connected/disconnected information for the apps with Xamarin.Android and WearOs?

I am trying to implement communication between WearOs watch and Android phone Apps. Here is the key point is between Apps, not between Devices because for me important is that, i can get the information about if the watch app is connected with the Phone app and vice versa. But it seems that On Android and WearOs, it happens on device level.
I have implemented WearableListenerService on both side and works perfectly fine. OnCapabilityChanged is fired as well but problem with the OnCapabilityChanged method is only fired if connection is lost and connected again. It is not fired when phone and watch are already connected and when I start the app on the phone, I am not able to know if there is already connection.
OnPeerConnected seems to be a good candidate in this sense but it is deprecated and never fired.
What is the best way to get this information? I have tried also Activity level CapabilityClient.IOnCapabilityChangedListener on MainActivity but OnCapabilityChanged behavior seems to be exactly the same. It is not called when the activity is started.
I have tried to implement code below also in OnResume but it returns always null.
var capabilityInfo = capabilityClient
.GetCapability(capability_wear, CapabilityClient.FilterReachable);
capabilityInfo.AddOnSuccessListener(this);
public async void OnSuccess(Java.Lang.Object capabilityInfo)
{
}
Beside this question, related question, is it even possible to disconnect phone app to watch apps?
I have had similar experience on Tizen watches and There is a SocketService with Connect and Close endpoints implements. Simply can be connected between Apps. But here on WearOs, it seems to happen on Device level only.
What's your definition of "watch app is connected"?
The Node (device) is connected and the app is installed? Or do you mean the app is running.
If you just mean app installed and device connected, then your code should work. Are you using a custom capability that your app declares? That should prove it is your app installed and not just the device connected.
File a bug using a reproduction in the https://github.com/android/wear-os-samples/tree/main/DataLayer project. https://issuetracker.google.com/issues/new?component=1065087&template=1592236
https://developer.android.com/training/wearables/data/data-layer
The CapabilityClient provides information on which Nodes on the Wear OS network support which custom app capabilities.
If you mean connected as in both running simultaneously then you would probably use ChannelClient, MessageClient, or DataClient to send observable updates. But this should generally be careful how you do that as you shouldn't try to maintain a live connection, say using the ChannelClient, between your watch and mobile apps. It will waste battery on both sides and there are hopefully more efficient patterns to achieve whatever you are trying to do.

iPhone Bluetooth pairing without confirming passcode

In my BLE app, the user story is like, bluetooth pairing should happen without the passcode confirmation step. As far as i have researched so far, it is possible in Android (like Android Bluetooth Pairing without User Enter Pin and Confirmation Using Android API)
Is it possible in iPhone?
Sadly, on iOS it is not possible to skip the pairing dialog. It is directly sent from the OS. It is a strict convention from apple that apps are not able to skip security processes.
Some additional information:
Dependent on the IOCapabilityResponse from the peripheral device on bluetooth level iOS will show you a dialog asking to pair or to confirm a pass code. If iOS will show you the dialog at all depends if the bondable flag is set in the IOCapabilityResponse from the peripheral.
There are three types of connection in BLE:
connection: pin not required, connection not secure
pair: pin could be requested or not, connection secured with short term key, a popup will be displayed
bond: pin could be requested or not, connection secured with long term
key, a popup will be displayed
All of these method are managed by BLE peripheral firmware, iOS only adapts its connection based on how the peripheral is configured

Handling multiple Bluetooth Pairing Request Dialogs at once

I have an app that integrates with BLE devices. I can connect to any number of devices. When initiating a pairing from the app to the device via [CBCentralManager connectPeripheral:options:] the system bluetooth pairing request alert will fire if no previous pairing information is found. This all works great.
However, I am implementing a functionality that discovers, pairs, and reads characteristics from multiple devices at once. This also works great if the devices have been paired previously. But if this is the first pairing for more than one of the devices, only one of the pairing request alert controllers is displayed. What makes this even more difficult is that I also don't receive a failed connection error from CB for the other devices waiting for response from the pairing dialog.
Is there any way I can elegantly handle situations where there are multiple pairing requests needing attention? It would be helpful if at least one of these was possible:
The ability to complete the outstanding pair requests sequentially
Notification of failed pairing for other devices
Knowledge of whether a pairing request dialog will be fired before initializing the pairing so I can pair one at a time
There are no APIs in CoreBluetooth that lets you interact with the pairing.
Are you in control of the firmware of the peripherals you want to be able to pair with? If so, you can enable notifications and send events how the pairing process is going. That way you know in the app the current status of a pairing process.
For some examples, by looking at status and error codes (details depends on your peripheral BLE stack), you will be able to identify when iOS shows the pair dialog, when the user presses cancel and when pairing succeeds. It will also be possible to identify when iOS didn't put up the pair dialog.

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?

Are there new requirements for a voip app in ios 8?

I have a voip app, but it won't wake up from standby mode when a call comes in. The docs say the following:
There are several requirements for implementing a VoIP app:
1. Enable the Voice over IP background mode for your app. (Because VoIP
apps involve audio content, it is recommended that you also enable
the Audio and AirPlay background mode.) You enable background modes
in the Capabilities tab of your Xcode project.
// I did this using the "capabilities" tab in the project's settings.
// I have "audio and airplay", "voice over ip",
// "background fetch" and "remote notifications" checked.
2. Configure one of the app’s sockets for VoIP usage.
// I have 2 sockets, one for sending stuff to the server that closes after sending.
// One socket that stays alive all the time, which is used to
// receive stuff from the server.
// The one that stays alive is configured as voip*.
3. Before moving to the background, call the
setKeepAliveTimeout:handler: method to install a handler to be
executed periodically. Your app can use this handler to maintain its
service connection.
// I did this and in the handler I send a login message to the server,
// On the server side it's detected that the account is already logged in so
// it refreshes the connection instead.
4. Configure your audio session to handle transitions to and from active use.
// I did not do this yet, I might in the future.
5. To ensure a better user experience on iPhone, use the Core Telephony
framework to adjust your behavior in relation to cell-based phone
calls; see Core Telephony Framework Reference.
// I did not do this and probably never will (company's decision, not mine).
6. To ensure good performance for your VoIP app, use the System
Configuration framework to detect network changes and allow your app
to sleep as much as possible.
// I don't do this yet, but will implement it once all the basics run fine.
When a call comes in I create a local notification to let the user know about the call. When the app is minimized this works fine, but when the device is in standby (sleep) there is no notification. When I wake the device from standby, the notification pops up after a few seconds (so it's not already there, it really appears after waking up the device).
I created more voip apps in the past, and I can't remember ever having trouble with this. I'm running ios 8 now, perhaps I have to do some more to make it work while in standby? Are there more requirements for voip now? Or am I missing something stupid?
Note: I know about push notifications. They are an option (in fact, I already tested and they make it work), but I'd rather not be dependent on the apns.
I just spent two full days troubleshooting a similar problem. An iPhone 6+ worked properly but neither of two iPhone 6's did. To make a long story short, SIP packets were not being transmitted reliably. I pinged the VOIP servers offered me and found that I was using one with a latency of 30 milliseconds but one with 15 milliseconds' latency was available, so I tried switching servers. That did the trick.
Be aware that if the user closes the App manually (double click home button, swipe up) your application will not be able to run in the background until the user manually opens it up.
However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.
Check it here.

Resources