This is an old revision of the document!
Bei dieser Anleitung geht es um das Einrichten und Erklären des SDK Scripts das automatisch zu einem der WLAN access point wechselt. Die erlaubten APs und das dazu passende Passwort sind in einer seperaten Datei zu finden.
Hintergrund ist das ein Kunde, der unsere Router in Zügen einsetzt, gerne automatisiert zu dem WLAN am jeweiligen Bahnhof wecheln möchte. Jedoch aber nur zu diesen APs und nicht zu irgendwelchen anderen WLAN Netzen die irgendwo noch verfügbar sein sollten.
Es folgt nun der step-by-step guide zum Einrichten der Wifi Switcher funktionalität.
Zunächst ist zu beachten das, nach dem Einrichten den Wifi Client, unser WLAN an Position 2 im Link Manager zu finden ist. Dies ist nötig damit das Script das richtige WAN Interface nach seinem Status abfragt. Die Rheinfolge der WAN Interfaces kann unter INTERFACES → WAN → Link Management geändert werden. Das WLAN Interface wird auch auf permanent gesetzt.
Nach den folgenden Schritten ist das wifi-switcher.are Script(findet sich weiter unten in dieser Anleitung) angelegt und kann schon laufen. Es fehlt allerdings noch die Liste der Access Points (erledigen wir im nächsten Schritt).
Hier richten wir den Trigger ein der das SDK Script starten wird. Da es die ganze Zeit laufen soll wird hier event-based → sdk-startup gewählt. Sobald SDK also enabled ist wird auch under Wifi Switcher Script laufen.
Anders als das Wifi Switcher Script ist es hier nicht nötig für diese Liste von Access Points Job und Trigger zu setzen. Es reicht aus wenn die Datei einfach nur zu finden ist. Der Grund warum wir die Liste via GUI einfügen und nicht einfach per Hand auf den Router kopieren ist das es so Update sicher ist und auch in der config auftaucht.
Wichtig ist aber das hier der korrekte Namen eingetragen wird. Also einfach die Liste (auch weiter unten zu finden) hoch laden und den Namen “wifi-networks.cfg” vergeben. Es können übrigens beliebig viele WLAN Access Points in diese Liste eingetragen werden.
Nach erfolgreichem Einrichten solle unser Scripts Tab nun so aussehen.
Hier eine kurze Erklärung wie das Script funktioniert.
DEBUG kann optional auf 1 gesetzt werden um Output im tail-log zu erhalten.
Das Script fragt in der while Schleife immer wieder den status vom WLAN Uplink (WANLINK2) ab. Wenn hier “dialing” oder “up” zurück gegeben wird machen wir nichts, warten 5 Sekunden und fragen nochmal.
Falls das WLAN down sein sollte und bereits mehr als 30 Sekunden seit dem letzten Scan vergangen sind machen wir jetzt einen neuen Scan der uns die aktuell sichtbaren WLAN NEtzwerke liefern wird.
Nachdem der Scan abgeschlossen holen wir und die Daten der Access Points und schauen in der Liste nach ob dort dieser AP vorhanden ist. Falls ja wird das WLAN umkonfiguriert jedoch nur wenn mehr als 120 Sekunden seit der letzten konfiguration vergangen sind.
include "wifi-networks.cfg"; DEBUG=0; SLEEP=5; SCAN_TIME_WAIT=30; CFG_TIME_WAIT=120; string enc_to_cfg(enc) { switch(enc) { case "WPA2-SAE": enc = "wpa3"; break; case "WPA2-PSK": enc = "wpa2"; break; default: enc = "wpa2"; if(DEBUG) nb_syslog("wifi swticher: undefinded enc: %s, using wpa2...", enc); } return enc; } while(1) { // we get the current state of wanlink2 (wlan) wan_status=nb_status("wan"); state=struct_get(wan_status, "WANLINK2_STATE"); if(DEBUG) nb_syslog("wifi switcher: current state = %s", state); // in case the wlan connection is up or dialing we do not start a new scan if (state != "down") { sleep(SLEEP); continue; } // only scan networks if last scan is more than SCAN_TIME_WAIT in the past if(DEBUG) nb_syslog("wifi switcher: last scan was %ds ago", uptime() - SCAN_TIME); if (uptime() - SCAN_TIME > SCAN_TIME_WAIT){ SCAN_TIME=uptime(); scan_res = nb_scan_networks("WLAN1"); if(DEBUG) nb_syslog("wifi switcher: scanning WLAN networks took %ds", uptime() - SCAN_TIME); } found=false; i=1; // get all the wifi information from the ap do { ssid= struct_get(scan_res, sprintf("NETWORK%d_SSID", i)); chipher=struct_get(scan_res, sprintf("NETWORK%d_CIPHER_1", i)); enc= struct_get(scan_res, sprintf("NETWORK%d_ENCRYPTION_1", i)); /* if(DEBUG) nb_syslog("wifi switcher: position in do loop i = %d",i); */ i++; for (j=0; j<length(wifi_list); j++) { if (ssid == wifi_list[j][0]) { if(DEBUG) nb_syslog("wifi switcher: configuring wifi with ssid: %s", ssid); cfg=sprintf("wlan.0.client.0.ssid=%s ", ssid); cfg=strcat(cfg, sprintf("wlan.0.client.0.secmode=wpa-psk ")); cfg=strcat(cfg, sprintf("wlan.0.client.0.secproto=%s ", enc_to_cfg(enc))); cfg=strcat(cfg, sprintf("wlan.0.client.0.cipher=%s ", tolower(chipher))); cfg=strcat(cfg, sprintf("wlan.0.client.0.minqual=2 ")); cfg=strcat(cfg, sprintf("wlan.0.client.0.minrssi=-99 ")); cfg=strcat(cfg, sprintf("wlan.0.client.0.psk=%s", wifi_list[j][1])); // only apply config if last config set is more tan CFG_TIME_WAIT in the past if(DEBUG) nb_syslog("wifi switcher: last config set was %ds ago", uptime() - CFG_TIME); if (uptime() - CFG_TIME > CFG_TIME_WAIT){ CFG_TIME = uptime(); nb_config_set(cfg); if(DEBUG) nb_syslog("wifi switcher: new wlan config got setup"); } found=true; break; } } if(found) break; } while ( !is_void(ssid) ); sleep(SLEEP); }
wifi_list=mkarray( mkarray("SSID1", "wifipassword1"), mkarray("SSID2", "wifipassword2"), mkarray("SSID3", "wifipassword3"), mkarray("SSID4", "wifipassword4"), mkarray("SSID5", "wifipassword5"), mkarray("SSID6", "wifipassword6"), mkarray("SSID7", "wifipassword7") );