@@ -11,6 +11,49 @@ Form.ino
1111
1212bool websocketConnected = false ;
1313
14+ class CaptiveRequestHandler : public AsyncWebHandler
15+ {
16+ public:
17+ // https://en.wikipedia.org/wiki/Captive_portal
18+ String urls[5 ] = {" /hotspot-detect.html" , " /library/test/success.html" , " /generate_204" , " /ncsi.txt" ,
19+ " /check_network_status.txt" };
20+ CaptiveRequestHandler ()
21+ {
22+ }
23+ virtual ~CaptiveRequestHandler ()
24+ {
25+ }
26+
27+ bool canHandle (AsyncWebServerRequest *request)
28+ {
29+ for (int i = 0 ; i < 5 ; i++)
30+ {
31+ if (request->url ().equals (urls[i]))
32+ return true ;
33+ }
34+ return false ;
35+ }
36+
37+ // Provide a custom small site for redirecting the user to the config site
38+ // HTTP redirect does not work and the relative links on the default config site do not work, because the phone is
39+ // requesting a different server
40+ void handleRequest (AsyncWebServerRequest *request)
41+ {
42+ String logmessage = " Captive Portal Client:" + request->client ()->remoteIP ().toString () + " " + request->url ();
43+ systemPrintln (logmessage);
44+ AsyncResponseStream *response = request->beginResponseStream (" text/html" );
45+ response->print (" <!DOCTYPE html><html><head><title>RTK Config</title></head><body>" );
46+ response->print (" <div class='container'>" );
47+ response->printf (" <div align='center' class='col-sm-12'><img src='http://%s/src/rtk-setup.png' alt='SparkFun "
48+ " RTK WiFi Setup'></div>" ,
49+ WiFi.softAPIP ().toString ().c_str ());
50+ response->printf (" <div align='center'><h3>Configure your RTK receiver <a href='http://%s/'>here</a></h3></div>" ,
51+ WiFi.softAPIP ().toString ().c_str ());
52+ response->print (" </div></body></html>" );
53+ request->send (response);
54+ }
55+ };
56+
1457// Start webserver in AP mode
1558bool startWebServer (bool startWiFi = true , int httpPort = 80 )
1659{
@@ -62,6 +105,7 @@ bool startWebServer(bool startWiFi = true, int httpPort = 80)
62105 }
63106
64107 websocket->onEvent (onWsEvent);
108+ webserver->addHandler (new CaptiveRequestHandler ()).setFilter (ON_AP_FILTER); // only when requested from AP
65109 webserver->addHandler (websocket);
66110
67111 // * index.html (not gz'd)
@@ -91,7 +135,8 @@ bool startWebServer(bool startWiFi = true, int httpPort = 80)
91135 handleUpload); // Run handleUpload function when any file is uploaded. Must be before server.on() calls.
92136
93137 webserver->on (" /" , HTTP_GET, [](AsyncWebServerRequest *request) {
94- AsyncWebServerResponse *response = request->beginResponse_P (200 , " text/html" , index_html, sizeof (index_html));
138+ AsyncWebServerResponse *response =
139+ request->beginResponse_P (200 , " text/html" , index_html, sizeof (index_html));
95140 response->addHeader (" Content-Encoding" , " gzip" );
96141 request->send (response);
97142 });
@@ -104,8 +149,8 @@ bool startWebServer(bool startWiFi = true, int httpPort = 80)
104149 });
105150
106151 webserver->on (" /src/bootstrap.bundle.min.js" , HTTP_GET, [](AsyncWebServerRequest *request) {
107- AsyncWebServerResponse *response =
108- request-> beginResponse_P ( 200 , " text/javascript " , bootstrap_bundle_min_js, sizeof (bootstrap_bundle_min_js));
152+ AsyncWebServerResponse *response = request-> beginResponse_P ( 200 , " text/javascript " , bootstrap_bundle_min_js,
153+ sizeof (bootstrap_bundle_min_js));
109154 response->addHeader (" Content-Encoding" , " gzip" );
110155 request->send (response);
111156 });
@@ -132,7 +177,8 @@ bool startWebServer(bool startWiFi = true, int httpPort = 80)
132177 });
133178
134179 webserver->on (" /src/main.js" , HTTP_GET, [](AsyncWebServerRequest *request) {
135- AsyncWebServerResponse *response = request->beginResponse_P (200 , " text/javascript" , main_js, sizeof (main_js));
180+ AsyncWebServerResponse *response =
181+ request->beginResponse_P (200 , " text/javascript" , main_js, sizeof (main_js));
136182 response->addHeader (" Content-Encoding" , " gzip" );
137183 request->send (response);
138184 });
@@ -349,7 +395,7 @@ static void handleFileManager(AsyncWebServerRequest *request)
349395 {
350396 fileExists = SD_MMC.exists (slashFileName);
351397 }
352- #endif // COMPILE_SD_MMC
398+ #endif // COMPILE_SD_MMC
353399
354400 if (fileExists == false )
355401 {
@@ -427,7 +473,7 @@ static void handleFileManager(AsyncWebServerRequest *request)
427473#ifdef COMPILE_SD_MMC
428474 else
429475 SD_MMC.remove (slashFileName);
430- #endif // COMPILE_SD_MMC
476+ #endif // COMPILE_SD_MMC
431477 request->send (200 , " text/plain" , " Deleted File: " + String (fileName));
432478 }
433479 else
@@ -731,7 +777,7 @@ void createSettingsString(char *newSettings)
731777#ifdef COMPILE_L_BAND
732778 int daysRemaining = daysFromEpoch (settings.pointPerfectNextKeyStart + settings.pointPerfectNextKeyDuration + 1 );
733779 snprintf (apDaysRemaining, sizeof (apDaysRemaining), " %d" , daysRemaining);
734- #endif // COMPILE_L_BAND
780+ #endif // COMPILE_L_BAND
735781 }
736782 else
737783 snprintf (apDaysRemaining, sizeof (apDaysRemaining), " No Keys" );
@@ -1346,7 +1392,7 @@ void updateSettingWithValue(const char *settingName, const char *settingValueStr
13461392 requestChangeState (STATE_ROVER_NOT_STARTED); // If update failed, return to Rover mode.
13471393 }
13481394 else if (strcmp (settingName, " factoryDefaultReset" ) == 0 )
1349- factoryReset (false ); // We do not have the sdSemaphore
1395+ factoryReset (false ); // We do not have the sdSemaphore
13501396 else if (strcmp (settingName, " exitAndReset" ) == 0 )
13511397 {
13521398 // Confirm receipt
@@ -1761,7 +1807,7 @@ void getFileList(String &returnText)
17611807
17621808 root.close ();
17631809 }
1764- #endif // COMPILE_SD_MMC
1810+ #endif // COMPILE_SD_MMC
17651811
17661812 xSemaphoreGive (sdCardSemaphore);
17671813 }
@@ -1883,4 +1929,4 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index,
18831929 }
18841930}
18851931
1886- #endif // COMPILE_AP
1932+ #endif // COMPILE_AP
0 commit comments