I want to understand how the AP provisioning works on a headless device, specifically for IoT applications (I'm developing on a Texas Instruments CC3200). It seems that the universally accepted method of provisioning an IoT device is for the device to act as an AP then the user connects to it in order to send the Wifi AP credentials via smartphone. I'm assuming this could be done via UDP or TCP.
Most of these IoT modules can act as an Access Point OR a Station but not both at the same time. So how does the device know that the Wifi credentials are correct? It must have to shut down the AP that it creates to try and connect to the user's Wifi, right? If the credentials are NOT correct, how does it let the user know on the smartphone side? At this point, the device's AP doesn't exists and the user would have to jump back on it again. What's really happening there?
So how does the device know that the Wifi credentials are correct ?
It have to try if using those credentials AP association is possible. For successful connection SSID, passphrase, encryption type have to be provided. All or some of those information can be already in device memory ie. application can connect only to known SSID.
It must have to shut down the AP that it creates to try and connect to the user's Wifi, right?
Yes. In case of TI CC3200 you can switch mode while application is running.
If the credentials are NOT correct, how does it let the user know on the smartphone side?
It is highly implementation depending. For example, if your IoT device cannot obtain outside world it can switch back to AP mode, what can be detected on the smartphone side. Other solution is that you can send and receive data while in AP mode so it is possible to write server application that will inform smartphone application about the connection state.
At this point, the device's AP doesn't exists and the user would have to jump back on it again. What's really happening there?
Not sure if understand this question. As I mentioned above IoT device knows the state of AP association (TI CC3200 SDK return known values for wide range of errors), if IoT device cannot connected as station using provided credentials it should rollback to AP mode.
Related
I was looking at this BLE demo for Arduino:
https://github.com/dzindra/BLE-iOS-demo/blob/master/esp32blinky/esp32blinky.ino
I noticed that there is no "Authentication / Authorization" or explicit "Connection code".
The code consists of creating services and characteristics, and advertising them. At best you can see the following callbacks which are triggered when a client connects:
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Connected");
};
void onDisconnect(BLEServer* pServer) {
Serial.println("Disconnected");
}
};
I was wondering what approach people follow for ensuring that users can connect to an Arduino's BLE only if they are the owner (for example, pressing a button to "trigger" connection mode) etc...
On deeper searching I found :
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/Arduino/security/BLE_server/BLE_server_passkey/BLE_server_passkey.ino
This other example shows how an ESP32 acting as a client would authenticate into a server:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/Arduino/security/BLE_client/BLE_client_passkey/BLE_client_passkey.ino
Both seem to be good examples for how two ESP32's could act as a client / server and authenticate each other. But then how would I get my iPhone to authenticate ? I use the following iPhone example for simply connecting without authentication.
Things seem a bit "hacky", and was wondering if there is an authoritative answer on how to connect to an Arduino BLE with authentication ?
EDIT: Basically, I wan't to prevent random people from just connecting to my BLE Device. I do not need anything more than that (I don't need encryption). I just want to prevent random people from connecting to my device, and breaking my smartphones connection with my BLE Device.
It seems no matter what mechanism you use to verify a valid connection the problem remains that if your BLE device is actually using advertising packets to deliver data, then when someone trys to connect, until you disconnect an unauthorised connection the advertising packet transmission is interrupted.
I use a small window of opportunity to write a correct value to a register otherwise resetting the connection.
I can't for the life of me figure out why my ESP8266s create WiFi access points.
I plug it in and send an empty sketch, and it creates an AP called "ESP_28F2F8" and here the ESP is at 192.168.4.1.
I do not want it to create a WiFi network. I just want it to connect to one.
Has anyone else run into this issue? Is this perhaps some weird OS?
That's normal operation of the underlying Espressif's SDK. It remembers some of the settings in flash, like the last created AP and last WiFi network connected.
You need to run
WiFi.softAPdisconnect(true);
so the ESP disconnects all clients currently connected to it, disables AP and remembers it to flash.
If you might also need to disable automatic connection to the last WiFi network, you need to call:
WiFi.setAutoConnect(false);
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?
I need to connect an iOS device (iDevice) to a WiFi access port but keep using the cellular data connection.
Default behavior is for iOS to set the WiFi connection as the default gateway, routing all internet traffic there. In my case the access point is a black box device supplying a WiFi network to access it's services, but not the internet.
One solution which we have tried, is to make the iDevice the access point (hot spot) and have the black box device connect though it. This is far less desirable as the black box device has no UI. So it is difficult to setup. We have lessened the pain by using Bonjour but still...
Is it possible to make a system call (iOS application) to restore the gateway setting back to the cellular gateway after the iDevice joins a WiFi network?
Would be even better if there is some way to setup the iDevice (IPhone or IPad) to maintain it's cellular gateway after connecting to a WiFi access point.
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;