Skip to content

Commit

Permalink
setup form: email field, rejection path; store api token
Browse files Browse the repository at this point in the history
  • Loading branch information
tcsullivan committed May 11, 2024
1 parent b626f4e commit d4654e6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 13 deletions.
26 changes: 21 additions & 5 deletions noisemeter-device/access-point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ const char *AccessPoint::htmlSetup =
"<h1>Noise Meter Setup</h1>"
"<form method='POST' action='' enctype='multipart/form-data'>"
"<p>SSID:</p>"
"<input type='text' name='ssid'>"
"<input type='text' name='ssid' required>"
"<p>Password:</p>"
"<input type='password' name='psk'>"
"<input type='password' name='psk' required>"
"<p>Email:</p>"
"<input type='email' name='email' required>"
"<input type='submit' value='Connect'>"
"</form>"
HTML_FOOTER;
Expand All @@ -57,6 +59,13 @@ const char *AccessPoint::htmlSubmit =
"<p>Connecting...</p>"
HTML_FOOTER;

// HTML to show when a submission is rejected.
const char *AccessPoint::htmlSubmitFailed =
HTML_HEADER
"<h1>Noise Meter Setup</h1>"
"<p>Invalid setup form input! Please <a href='/'>go back and try again</a>.</p>"
HTML_FOOTER;

[[noreturn]]
void AccessPoint::run()
{
Expand Down Expand Up @@ -88,9 +97,16 @@ bool AccessPoint::handle(WebServer& server, HTTPMethod method, String uri)
if (method == HTTP_POST) {
if (uri == "/") {
server.client().setNoDelay(true);
server.send_P(200, PSTR("text/html"), htmlSubmit);
if (onCredentialsReceived)
onCredentialsReceived(server);

if (onCredentialsReceived) {
if (onCredentialsReceived(server)) {
server.send_P(200, PSTR("text/html"), htmlSubmit);
delay(2000);
ESP.restart(); // Software reset.
} else {
server.send_P(200, PSTR("text/html"), htmlSubmitFailed);
}
}
} else {
server.sendHeader("Location", "http://8.8.4.4/");
server.send(301);
Expand Down
12 changes: 10 additions & 2 deletions noisemeter-device/access-point.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,17 @@ class AccessPoint : public RequestHandler
static constexpr auto Passkey = "noisemeter";

public:
/**
* Submission handler receives WebServer for input data and returns true
* on success, false to reject bad submission.
*/
using SubmissionHandler = bool (*)(WebServer&);

/**
* Starts the WiFi access point using the fixed credentials.
* @param func Callback to handle user setup form submission.
*/
AccessPoint(void (*func)(WebServer&)):
AccessPoint(SubmissionHandler func):
server(80),
onCredentialsReceived(func) {}

Expand All @@ -63,7 +69,7 @@ class AccessPoint : public RequestHandler
/** Web server object for running the setup form. */
WebServer server;
/** Callback for setup form completion. */
void (*onCredentialsReceived)(WebServer&);
SubmissionHandler onCredentialsReceived;

/** Hard-coded IP address for the ESP32 when hosting the access point. */
static const IPAddress IP;
Expand All @@ -73,6 +79,8 @@ class AccessPoint : public RequestHandler
static const char *htmlSetup;
/** Hard-coded HTML for the page shown after completing the form. */
static const char *htmlSubmit;
/** Hard-coded HTML for the page shown when rejecting a form submission. */
static const char *htmlSubmitFailed;

/** Determines which HTTP requests should be handled. */
bool canHandle(HTTPMethod, String) override;
Expand Down
11 changes: 6 additions & 5 deletions noisemeter-device/noisemeter-device.ino
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ void printReadingToConsole(double reading);
/**
* Callback for AccessPoint that verifies and stores the submitted credentials.
* @param httpServer HTTP server which served the setup form
* @return True if successful
*/
void saveNetworkCreds(WebServer& httpServer);
bool saveNetworkCreds(WebServer& httpServer);

/**
* Generates a UUID that is unique to the hardware running this firmware.
Expand Down Expand Up @@ -298,7 +299,7 @@ void printReadingToConsole(double reading) {
SERIAL.println(output);
}

void saveNetworkCreds(WebServer& httpServer) {
bool saveNetworkCreds(WebServer& httpServer) {
// Confirm that the form was actually submitted.
if (httpServer.hasArg("ssid") && httpServer.hasArg("psk")) {
const auto ssid = httpServer.arg("ssid");
Expand All @@ -308,14 +309,14 @@ void saveNetworkCreds(WebServer& httpServer) {
if (!ssid.isEmpty() && Creds.canStore(ssid) && Creds.canStore(psk)) {
Creds.set(Storage::Entry::SSID, ssid);
Creds.set(Storage::Entry::Passkey, psk);
Creds.set(Storage::Entry::Token, API_TOKEN);
Creds.commit();

ESP.restart(); // Software reset.
return true;
}
}

// TODO inform user that something went wrong...
SERIAL.println("Error: Invalid network credentials!");
return false;
}

UUID buildDeviceId()
Expand Down
3 changes: 2 additions & 1 deletion noisemeter-device/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class Storage : protected EEPROMClass
Checksum = 0, /** Storage CRC32 Checksum */
SSID = Checksum + sizeof(uint32_t), /** User's WiFi SSID */
Passkey = SSID + StringSize, /** User's WiFi passkey */
TotalSize = Passkey + StringSize /** Marks storage end address */
Token = Passkey + StringSize, /** Device API token */
TotalSize = Token + StringSize /** Marks storage end address */
};

/**
Expand Down

0 comments on commit d4654e6

Please sign in to comment.