PoTrolls
Cette page se vit ans un résau
WiFi local protégé (
wpa,
wep,) où le service DHCP est disponible
GAFFE: il faut trouverl' l'adresse IP affectée.
AlAIK: possible en se connecvtant au
SoftAp? zlot qu'il est en mode "ruinnong"
faire alternative par envoi d'un email comme les webcam
envisager une version pour les réseaux "abonnés" (wifi ouvert, mais débouchant sur un portail) , genre orange, FreeWifi, SfrPublic, Fon... )
gaFFE: actuellement,;
Il y a une version plus tordue:
PoTrollAnyTwoSteps
utilise
PotrollPerm pour mémoriser le réseau wifi (ssid et passphrase) et le compteur de reboot (selon
PotrollInit)
design:
- choisir si on souhaite conserver l'accès config en permanence (mais en passant par le réseau wifi local, le réseau "spécialisé" n'est pas réellement éteint au reboot qui suit la définition de la clé, mais il n'accepteplus aucune commande)?
- choisir si on souhaite autoriser les tâches "normales" en mode config (donc sans avoir à passer par un réseau local wifi); bien sûr ce sera sans accès Internet!
base pour un potroll à lâcher dans la jungle:
- livré serveur WPA avec (passphrase=MacAddress), donné dans le nom du ssid diffusé
- accessible depuis un client wifi (smartphone, tablette, voire ordinateur wifi)
- permet la configuration pour rejoindre un réseau wifi local (par choix dans l'environnement ou manuel si réseau non diffusé ou non disponible).
- choix parmi les réseaux à portée
- définition d'un réseau absent"
pour l'instant testé avec la mémoire interne d'un
Esp8266 (in true life:
WemosD1Mini, et [20170117]:
NodeMcu Lolim)
la bête à deux états:
- usine:
- diffuse un réseau wifi WPA, clé écrite sous la boîte
- fixe le SSOD du wifi local à utiliser
- la clé
- éventuellement fonctionnelle
- running
- éventuellement en rendant la config inaccessible ?
il est possible de
- passer de running à config par 4 cycles off/on (permet de changer de réseau wifi local)
GAFFE: par conception, l'
Esp8266 a tendance à chercher à se re-connecter au Point d'accès "précédent", même après enregistrement de nouveaux ssid/passphrase
(si c'estun réseau ouvert (orange, freewifi, la bête est perdue: fait 5 cycle off/on pour le remettre en configutration usine et pouvoir y accéder)
20170119 GAFFE: work in progress , nécessite un grand nettoyage
exemple d'utiloisaton:
#include <PERM_ESP8266.h>
#include "WifiConnectOrAp.h"
#define VERSION "14 jan 2017"
enum state {config,running};
#define RUNSERVER true // http server will be active in runnig state
#define CONFIGSERVER true // server available in config mode
state current=config;
String rep="";
WifiConnectOrAp local;
WiFiServer server(80);
#define SEUILAP 4
#define SECOUT 20 // 80 for digispark
PERM lastssid(32);
PERM lastkey(32);
PERM reboot(1);
void setup()
{
Serial.begin(74880);
bool manual=false;
delay(1000);
Serial.println(VERSION);
Serial.println((byte)reboot.get(0));
current=running;
Serial.println(lastssid.get());
Serial.println(lastkey.get());
bool doconfig=false;
if (reboot.get(0)>SEUILAP) {
// reboot.put(0,0);
doconfig=true;
}else{
reboot.put(0,reboot.get(0)+1);
// protextc
String ssid=lastssid.get();
String key=lastkey.get();
Serial.println("eeprom ssid:<"+ssid+">");
Serial.println("eeprom key:<"+key+">");
if (lastssid.get()==""){
Serial.println("empty, ignored");
doconfig=true;
}
if (lastssid.get().substring(1,2)==" "){
Serial.println("old, ignored");
doconfig=true;
}
}
bool ok=false;
if (!doconfig){
Serial.println("triing client of last wifi ");
ok=local.ConnectHomeAp(lastssid.get(),lastkey.get(),10) ;
}
if (ok){
Serial.println("Connected ");
}else{
Serial.println("echec connexion "+lastssid.get()+"/"+lastkey.get());
doconfig=true;
}
if (doconfig) {
local.SoftAp(local.appendMac("Troll_",6)+":192.168.4.1",local.appendMac("",6));
// local.SoftAp(local.appendMac("12345xxxx123425789_",6),local.appendMac("",6));
current=config;
}
if (RUNSERVER) server.begin();
} // setup
void loop_running(){
if (RUNSERVER){
WiFiClient client=server.available();
String req=local.dummyrun(client);
if (req=="") return;
}
return;
}
void loop(){
if (millis()>SECOUT*100){
if (reboot.get(0)>0 && current==running) {
Serial.println(reboot.get(0));
Serial.println(millis());
Serial.println("sursis termine back to reboot");
reboot.put(0,0);
// 2do: zet a flag prohibitin server config
}
}
switch (current) {
case config:{
WiFiClient client=server.available();
String req=local.yafull(client,reboot,lastssid, lastkey);
if (req=="") return;
delay(1);
return;
}
case running:{
loop_running();
break;
} // running
} // switch current
} // loop
/*
#include <ESP8266WiFi.h>
#include <PERM_ESP8266.h>
// wifi
class WifiConnectOrAp {
public:
bool ConnectHomeAp(String ssid,String wifikey,int sectimeout);
bool SoftAp(String ssid, String phrase);
String appendMac(String root, byte mac[6]);
String appendMac(String root, byte mac[6], int lon);
String appendMac(String root);
String appendMac(String root, int lon);
String yafull(WiFiClient client,PERM reboot, PERM lastssid, PERM lastkey);
String dummyrun(WiFiClient client);
private:
String help();
//String listidlink();
String listid();
String listidlink();
bool extract(PERM mem,String hive,String needle);
bool is(String hive,String needle);
bool choose(PERM mem,String hive,String needle);
String execconfig(PERM reboot,PERM lastssid, PERM lastkey, String request);
char hex(byte x);
String list;
String rep;
};
*/
// wifi
#include "WifiConnectOrAp.h"
//String rep="";
#define VERSION "2017 01 13"
String WifiConnectOrAp::dummyrun(WiFiClient client){
//Serial.println(millis());
if (!client) return "";
String received=client.readStringUntil('\r');
client.flush();
IPAddress ip= WiFi.localIP();
Serial.print("received by accueil run "+received);
// Prepare the response. Start with the common header:
String s = "HTTP/1.1 200 OK\r\n";
s += "Content-Type: text/html\r\n\r\n";
s += "<!DOCTYPE HTML>\r\n<html>\r\n";
s+= ip.toString();
s+= " hello (2) , now ";
s.concat(millis()/1000);
s += "</html>";
client.print(s);
Serial.println("accuilrun repone ");
return ".";
}
String WifiConnectOrAp::yafull(WiFiClient client,PERM reboot, PERM lastssid, PERM lastkey){
if (!client) return "";
String received=client.readStringUntil('\r');
client.flush();
Serial.println("yafull received:"+received);
if ( received.indexOf("GET / ")==0) received="GET /index.htm ";
if (received.indexOf("GET /index.htm")==-1 ) {
String s = "HTTP/1.1 404 ERROR\r\n";
s += "Content-Type: text/html\r\n\r\n";
s += "<!DOCTYPE HTML>\r\n<html>\r\n";
s += "ERROR 404 not found";
s += "</html>\n";
client.print(s);
return "";
}
String retour= execconfig(reboot, lastssid,lastkey,received);
// Serial.println("yafull received rep de config:"+retour);
// Prepare the response. Start with the common header:
String s = "HTTP/1.1 200 OK\r\n";
s += "Content-Type: text/html\r\n\r\n";
s += "<!DOCTYPE HTML>\r\n<html>\r\n";
s += retour;
s += "</html>\n";
client.print(s);
Serial.print("yafull sent :");
Serial.println(s);
return "...";
}
bool WifiConnectOrAp::ConnectHomeAp(String ssid,String wifikey,int sectimeout){
long start=millis();
Serial.print("\nConnecting to wifi ");
Serial.println("<"+ssid+">");
Serial.println("<"+wifikey+">");
// choose mode
WiFi.mode(WIFI_AP);
WiFi.begin( ssid.c_str(),wifikey.c_str());
while ( (millis()-start) < sectimeout*1000L) {
if (WiFi.status() == WL_CONNECTED) {
Serial.print(" now connected as ");
Serial.println(WiFi.localIP());
return true;
}
delay(500);
Serial.print(".");
}
return false;
}
String WifiConnectOrAp::appendMac(String root, byte mac[6]){
return WifiConnectOrAp::appendMac(root, mac, 3);
}
String WifiConnectOrAp::appendMac(String root){
return WifiConnectOrAp::appendMac(root, 3);
}
String WifiConnectOrAp::appendMac(String root,int lon ){
byte mac[6];
WiFi.macAddress(mac);
return WifiConnectOrAp::appendMac(root, mac, lon);
}
String WifiConnectOrAp::appendMac(String root, byte mac[6], int lon){
String perso=root;
for (int i=6-lon;i<6;i++){
perso.concat(hex(mac[i]/16));
perso.concat(hex(mac[i]%16));
}
return perso;
}
/*
String WifiConnectOrAp::listid(){
int n=WiFi.scanNetworks();
String ssids="<br>";
for (int i=0;i<n;i++){
ssids.concat(i);
ssids.concat(":");
ssids.concat(WiFi.SSID(i));
ssids.concat("<br>");
}
return ssids;
}
*/
String WifiConnectOrAp::listidlink(){
int n=WiFi.scanNetworks();
String ssids="PoTroll Wifi Client Access configuration <br>Choose SSID <br>";
for (int i=0;i<n;i++){
ssids.concat("<a href=\"index.htm?ssid=");
ssids.concat(WiFi.SSID(i));
ssids.concat("\" ><button>");
ssids.concat(WiFi.SSID(i));
ssids.concat("</button></a><br>");
}
/* ssids.concat("<a href=\"index.htm?ssid=");
ssids.concat("\" ><button>");
ssids.concat("hidden or not funning");
ssids.concat("</button></a><br>");
*/
return ssids;
}
String WifiConnectOrAp::help(){
String h="<br><a href=\"/index.htm?survey\"> SURVEY </a><br>" ;
h += "<form>Manual SSID: <input type=\"text\" name=\"ssid\"> Wifi PassPhrase <input type=\"text\" name=\"key\">" ;
h+= "<input type=\"submit\" value=\"go\" ></form>";
return h;
}
bool WifiConnectOrAp::SoftAp(String ssid, String phrase){
byte mac[6];
WiFi.macAddress(mac);
Serial.println();
Serial.println(ssid.length());
Serial.println("Configuring access point...");
WiFi.softAP(ssid.c_str(),phrase.c_str());
Serial.println(ssid+" SoftAp running... phrase="+phrase);
IPAddress myIP = WiFi.softAPIP();
Serial.print("Server IP address: ");
Serial.println(myIP);
return true;
}
char WifiConnectOrAp::hex(byte x){
char d;
d='0'+x%16;
if (d>'9')d=d+7;
return d;
}
String WifiConnectOrAp::execconfig(PERM reboot, PERM lastssid, PERM lastkey, String request){
rep="";
bool donessid=false;
bool donekey=false;
Serial.print(millis());
Serial.print(" execconfig request: ");
Serial.println(request);
// Match the request
if (extract(lastssid,request,"ssid=")){
Serial.println ("key ssid !! now:" +lastssid.get());
// return ("key ssid now:" +lastssid.get())+"<br><a href=\"index.htm?key=\" >entrer key</a><br>"+
// "<form>Enter new Key for wap protected wifi AP :<input type=\"text\" name=\"key\"></form>" ;
rep += " ssid set ";
donessid =true;
;
}
if (extract(lastkey,request,"key=")){
reboot.put(0,0);
Serial.println ("put raz key now:" +lastkey.get());
// return ("put raz key now:" +lastkey.get());
rep += " key set ";
donekey=true;
}
if (donekey && donessid) {
return "Ssid and key set, reboot";
}
if (donessid) return ("key ssid now:" +lastssid.get())+"<br><a href=\"index.htm?key=\" >entrer key</a><br>"+
"<form>Enter new Key for wap protected wifi AP :<input type=\"text\" name=\"key\"></form>" ;
if (donekey) {
return "key set, reboot";
}
if (choose(lastssid,request,"choose=")){
;
}
if (request.indexOf("GET /index.htm?survey ")==0) {
rep=listidlink();
}
if (request.indexOf("GET /index.htm ")==0){
Serial.println("recuindex.htm nacked");
rep=help();
}
Serial.print(millis());
Serial.println(rep);
if (rep.length()==0) rep="nothing to do for: "+request;
Serial.println("execconfig built html answer "+rep);
// Return the response
return rep;
}
bool WifiConnectOrAp::extract(PERM mem,String hive,String needle){
Serial.println("extract "+needle+ " in "+hive);
int deb1=hive.indexOf("&"+needle);
int deb2=hive.indexOf("?"+needle);
int deb=deb1;
if (deb2>=0) deb=deb2;
if (deb>=0){
deb=deb+1;
Serial.println(deb);
String bew=hive.substring(deb+needle.length(),hive.indexOf(' ',deb+1));
if (bew.indexOf('?')>=0) bew=bew.substring(0,bew.indexOf('?'));
if (bew.indexOf('&')>=0) bew=bew.substring(0,bew.indexOf('&'));
mem.put(bew);
rep=" stored by extract "+bew;
return true;
}
return false;
}
bool WifiConnectOrAp::choose(PERM mem,String hive,String needle){
Serial.println("choose "+needle+ " in "+hive);
rep ="";
int deb=hive.indexOf(needle);
if (deb<0){
rep="";
return false;
}
// choose trouve
Serial.println(deb);
String bew=hive.substring(deb+needle.length(),hive.indexOf(' ',deb+1));
Serial.println("choosen: "+bew);
int wh=list.indexOf("<br>"+bew+":");
Serial.println(wh);
if (wh>=0) {
if (list.length()==0) {
rep="Use list before choose";
return false;
}
int deuxpt=list.indexOf(':',wh);
mem.put(list.substring(deuxpt+1,list.indexOf('<',wh+1)));
Serial.println("selected "+mem.get());
rep="choosen : "+mem.get();
return true;
}
}
bool WifiConnectOrAp::is(String hive,String needle){
Serial.println(" is "+needle+" == "+hive);
int deb=hive.indexOf(needle);
if (deb>=0){
String bew=hive.substring(deb,hive.indexOf(' ',deb+1));
return bew.equals(needle);
}
return false;
}