Avoid-Hard-Coding-WiFi-Credentials-on-Your-ESP8266 without using Wifimanage - esp8266

Is it possible? ESP8266 connect to router wifi via iOS application?
I want to make an application control something by ESP8266. My workflow bellow:
Open the app, on the device connected to wifi router.
Connect to ESP8266 and give it SSID and PASSWORD info from current Wifi.
ESP8266 receive this infos and auto connect to Wifi router.
Thank for your advices first.
I tried this way but I get user experience. Because user has to do many steps.
- Using WiFiManager, make ESP8266 as wifi router.
- Go to Wifi setting from device to connect to ESP8266 Wifi.
- Give Wifi infos (SSID, PASSWORD) by go to 192.168.4.1 from web browser.
Just note here to avoid this way
Please give me your advices.
Thank you

First of all, I don't think you made ESP8266 as a Wi-Fi router. I think you mean it goes into AP mode to prompt the user for the credentials.
I have worked around this by using the EEPROM library. You can easily find code example here
So basically:
Pre hard code credentials (can be dummy data for first run) to the EEPROM.
When ESP8266 boots up, load those credentials and try to connect to
the Wi-Fi.
If it can't connect, prompt the user to input credentials.
ESP8266 tries to reconnect. If it can connect, then write
credentials to EEPROM.
Repeat from step 2 every time it boots up.
Now instead of having user input credentials every single time, it will try to connect first. If it fails, then user will have to do extra work.
Let me know if I can help, I have work extensively on this problem and have working code.

WiFiManager requires you to:
Connect to ESP8266's AP
Go to 192.168.4.1 (or any other set address) - on iOS it should appear automatically
Click on Wifi scan
Choose the network you want your ESP8266 to connect to
Provide password if any
Click Save button
This is the minimal thing a user has to do. He/she has to connect to ESP8266's AP and provide WiFi credentials somehow. The only thing that you can change is how the user provides that credentials. If you already make your user download your iOS app, then maybe it's okay to add possibility to configure ESP8266 within your app.
In order to configure ESP8266 with WiFiManager on board your app would have to:
Scan for WiFi networks and connect to ESP8266's AP (eg. by searching
for particular SSIDs)
Send GET request to http://192.168.4.1/wifisave?s=NETWORK_SSID&p=NETWORK_PASSWORD
However, please bear in mind that it's pointless otherwise. If your user isn't required to download any app before configuring ESP8266, then don't require him/her to do it. Web applications are a way to go in these days. This approach won't require a user to download another app just to type in the WiFi credentials. WiFiManager should appear automatically after user connects to the device's AP.

I found the way to do that:
This is code on iOS application:
https://github.com/EspressifApp/EsptouchForIOS
This is code on ESP8266 run on Arduino:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
WiFiUDP Udp;
void setup() {
int cnt = 0;
//Allocate baud 115200
Serial.begin(115200);
//Mode wifi is station
WiFi.mode(WIFI_STA);
//Waiting for connect
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if(cnt++ >= 10){
WiFi.beginSmartConfig();
while(1){
delay(1000);
//Check the connect and print inform if success
if(WiFi.smartConfigDone()){
Serial.println("SmartConfig Success");
break;
}
}
}
}
Serial.println("");
Serial.println("");
WiFi.printDiag(Serial);
// Allocate server
Udp.begin(49999);
Serial.println("Server started");
// Print IP address
Serial.println(WiFi.localIP());
}
void loop() {
// Receive the package from ESPTouch
Udp.parsePacket();
//Print IP of ESP8266
while(Udp.available()){
Serial.println(Udp.remoteIP());
Udp.flush();
delay(5);
}
}

Related

Inconsistent connectivity via WiFi manager in ESP8266

I am facing a peculiar problem. The below code snippet connects to new WiFi network. No hard-coded ssid or password in the program. I am using AsyncWifiManager and AsyncWebServer modules. When I am connecting to my home WiFi router providing ssid and password in autoconnect portal, NodeMCU is getting connected and the server is working fine. But whenever I am changing the WiFi, connecting to my mobile phone hotspot, then server is not running, though I am getting local IP address in Serial Monitor.
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPAsyncWiFiManager.h>
#include <FS.h>
#include <Wire.h>
AsyncWiFiManager wifiManager(&server,&dns);
// To clean previous settings. Use one time, then comment
// wifiManager.resetSettings();
// set custom static ip for portal
IPAddress staticIP(192,168,0,20); //ESP static ip
IPAddress gateway(192,168,0,1); //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255,255,255,0); //Subnet mask
wifiManager.setSTAStaticIPConfig(staticIP, gateway, subnet);
// Open WiFi Setup portal
wifiManager.autoConnect();
Serial.println("Connecting to WiFi..");
// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());
WiFi.begin();
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
I am programming the NodeMCU board via Arduino IDE.
As your code uses fix parameters for IP/subnet/gateway you have to setup your different hotspots accordingly or you have the following options to choose from as you connect your ESP8266 server to different hotspots:
always being in the same network/subnetwork (all hotspots are part of a local network) you can use fix IP-addresses for all devices irrelevant of the hotspot you connect to
If you do not want to use above (=fix IP for all devices): Set the DHCP server to always give the same IP addresses to the NodeMCUs based on their MAC addresses.
You use mDNS and give the ESP8266 a fixed name and call via http://nyPreferredESP.local (allthough the IP varies) and use on your Android phone something like this APP
If you want to work with changing gateways (Devices not on the same net/subnet, access over the internet): This would require something a little more robust. Use a Dynamic DNS service along with a domain name. The Dynamic DNS will update your DNS records in almost real time if your gateway address changes. Example here
The complexity of the solution results from the factor always in the same network/subnet and a fixed gateway or everything (except MAC-address and name of the device are fix) and the rest may be variable. Read some basics about setting up a local network here

How to prevent unauthorized users from connecting to Arduino BLE device?

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.

how to establish internet connection to "ttgo t call esp32 sim800L" using Lua

I used the "Nodemcu Module v3" and it supports wifi based internet connection only.
I always start with a wifi initiation steps (By Lua Scripting) to connect my "Nodemcu" board with internet and After making the wifi connection I am sure that my device has access to internet (Though my Wifi router has internet connection) and I can do any internet based communication.
But how can I teach my "ttgo t call esp32 sim800L" board to use the Sim card data?
Is there any steps for that or it connects to internet automatically on insertion of sim card?
Please Guide me to start work on it.
Thank You

How to Provide and Check Wifi Credentials for Headless Device

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.

iOS WiFi probe interval

I am writing an app which connects via WiFi to a proprietary device. The proprietary device acts as a WiFi access point.
When the device powers down, the WiFi connection is terminated, as I would expect.
The iPhone continues to send probe requests, looking for networks to connect to. It follows an exponential backoff algorithm for sending probes.
My problem is that eventually the intervals between the probe requests sent by the iPhone are longer than the timeout on my device, so they don't make a connection.
I am using the Reachability code and it works as I would expect.
It seems that pressing the home button will reset the backoff and send a probe request immediately. Does anyone know of a way to have my app do something similar?
Thanks for any help.
Instead of pinging the internet every time with Reachability, ping a host on the local network like the DNS server or the router (192.168.1.1).
I somehow experienced a similar situation to check if the device was connected in a specific VPN connection. The approach was to ping to a machine in the local network, via standard ping or implementing a ping web service.
If you don't have a backend in your local network then the easiest would be the ping. You can check the following code example from the Apple developer site:
http://developer.apple.com/library/mac/#samplecode/SimplePing/Introduction/Intro.html
I would suspect that if you reconfigure the connection (re-set the WiFi configuration) in your app that the iPhone would restart scanning without the backoff. So your app could keep track of how long it was since the connection was lost and then reconfigure the link after an appropriate amount of time. Possibly you would have to reconfigure to a different SSID and then switch back, depending on how smart the iOS-libraries are.
I'm not shure, if i understand you right. You want to check if the device is still connected to the access point?
I've build an app to connect to a scanner via wifi, the scanner acts as access point. for that i check if the SSID the device is currently connected to is the one of the scanner. to check the CurrentSSID you can use the following code:
+(NSString*)currentSSID {
CFArrayRef myArray = CNCopySupportedInterfaces();
CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
if (!myDict) {
return nil;
}
NSDictionary *myDictionary = (__bridge_transfer NSDictionary*)myDict;
return [myDictionary objectForKey:#"SSID"];
}
hope that helps.
I am afraid there is no way of doing so without being rejected during the review (you could read on how to access the SBWifiManager). Apple does not enable any way to access the wifi manager from the sandbox environment. I experienced similar issue connecting my device to various access points (for locating with probe request), up to now with the iOS 7 the probe requests were sent between huge intervals (even 15 min). Try to modify your access points.

Resources