Skip to content

Commit db26ef4

Browse files
author
Me No Dev
committed
Merge remote-tracking branch 'esp8266/master'
2 parents e6578b4 + 0f0386e commit db26ef4

20 files changed

+599
-80
lines changed

cores/esp8266/Schedule.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "Schedule.h"
2+
3+
struct scheduled_fn_t
4+
{
5+
scheduled_fn_t* mNext;
6+
std::function<void(void)> mFunc;
7+
};
8+
9+
static scheduled_fn_t* sFirst = 0;
10+
static scheduled_fn_t* sLast = 0;
11+
12+
static scheduled_fn_t* sFirstUnused = 0;
13+
static scheduled_fn_t* sLastUnused = 0;
14+
15+
static int sCount = 0;
16+
17+
static void init_lists()
18+
{
19+
if (sCount != 0) {
20+
return;
21+
}
22+
while (sCount < SCHEDULED_FN_INITIAL_COUNT) {
23+
scheduled_fn_t* it = new scheduled_fn_t;
24+
if (sCount == 0) {
25+
sFirstUnused = it;
26+
}
27+
else {
28+
sLastUnused->mNext = it;
29+
}
30+
sLastUnused = it;
31+
++sCount;
32+
}
33+
sLastUnused->mNext = NULL;
34+
}
35+
36+
static scheduled_fn_t* get_fn() {
37+
scheduled_fn_t* result = NULL;
38+
// try to get an item from unused items list
39+
if (sFirstUnused) {
40+
result = sFirstUnused;
41+
sFirstUnused = result->mNext;
42+
if (sFirstUnused == NULL) {
43+
sLastUnused = NULL;
44+
}
45+
}
46+
// if no unused items, and count not too high, allocate a new one
47+
else if (sCount != SCHEDULED_FN_MAX_COUNT) {
48+
result = new scheduled_fn_t;
49+
result->mNext = NULL;
50+
++sCount;
51+
}
52+
return result;
53+
}
54+
55+
static void recycle_fn(scheduled_fn_t* fn)
56+
{
57+
if (!sLastUnused) {
58+
sFirstUnused = fn;
59+
}
60+
else {
61+
sLastUnused->mNext = fn;
62+
}
63+
fn->mNext = NULL;
64+
sLastUnused = fn;
65+
}
66+
67+
bool schedule_function(std::function<void(void)> fn)
68+
{
69+
scheduled_fn_t* item = get_fn();
70+
if (!item) {
71+
return false;
72+
}
73+
item->mFunc = fn;
74+
item->mNext = NULL;
75+
if (!sFirst) {
76+
sFirst = item;
77+
}
78+
else {
79+
sLast->mNext = item;
80+
}
81+
sLast = item;
82+
return true;
83+
}
84+
85+
void run_scheduled_functions()
86+
{
87+
while (sFirst) {
88+
scheduled_fn_t* item = sFirst;
89+
sFirst = item->mNext;
90+
if (sFirst == NULL) {
91+
sLast = NULL;
92+
}
93+
item->mFunc();
94+
item->mFunc = std::function<void(void)>();
95+
recycle_fn(item);
96+
}
97+
}

cores/esp8266/Schedule.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef ESP_SCHEDULE_H
2+
#define ESP_SCHEDULE_H
3+
4+
#include <functional>
5+
6+
#define SCHEDULED_FN_MAX_COUNT 32
7+
#define SCHEDULED_FN_INITIAL_COUNT 4
8+
9+
// Warning
10+
// This API is not considered stable.
11+
// Function signatures will change.
12+
// You have been warned.
13+
14+
// Run given function next time `loop` function returns,
15+
// or `run_scheduled_functions` is called.
16+
// Use std::bind to pass arguments to a function, or call a class member function.
17+
// Note: there is no mechanism for cancelling scheduled functions.
18+
// Keep that in mind when binding functions to objects which may have short lifetime.
19+
// Returns false if the number of scheduled functions exceeds SCHEDULED_FN_MAX_COUNT.
20+
bool schedule_function(std::function<void(void)> fn);
21+
22+
// Run all scheduled functions.
23+
// Use this function if your are not using `loop`, or `loop` does not return
24+
// on a regular basis.
25+
void run_scheduled_functions();
26+
27+
#endif //ESP_SCHEDULE_H

cores/esp8266/core_esp8266_main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
//This may be used to change user task stack size:
2424
//#define CONT_STACKSIZE 4096
2525
#include <Arduino.h>
26+
#include "Schedule.h"
2627
extern "C" {
2728
#include "ets_sys.h"
2829
#include "os_type.h"
@@ -119,6 +120,7 @@ static void loop_wrapper() {
119120
setup_done = true;
120121
}
121122
loop();
123+
run_scheduled_functions();
122124
esp_schedule();
123125
}
124126

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
To upload through terminal you can use: curl -F "[email protected]" esp8266-webupdate.local/update
3+
*/
4+
5+
#include <ESP8266WiFi.h>
6+
#include <WiFiClient.h>
7+
#include <ESP8266WebServer.h>
8+
#include <ESP8266mDNS.h>
9+
#include <ESP8266HTTPUpdateServer.h>
10+
11+
const char* host = "esp8266-webupdate";
12+
const char* update_path = "/firmware";
13+
const char* update_username = "admin";
14+
const char* update_password = "admin";
15+
const char* ssid = "........";
16+
const char* password = "........";
17+
18+
ESP8266WebServer httpServer(80);
19+
ESP8266HTTPUpdateServer httpUpdater;
20+
21+
void setup(void){
22+
23+
Serial.begin(115200);
24+
Serial.println();
25+
Serial.println("Booting Sketch...");
26+
WiFi.mode(WIFI_AP_STA);
27+
WiFi.begin(ssid, password);
28+
29+
while(WiFi.waitForConnectResult() != WL_CONNECTED){
30+
WiFi.begin(ssid, password);
31+
Serial.println("WiFi failed, retrying.");
32+
}
33+
34+
MDNS.begin(host);
35+
36+
httpUpdater.setup(&httpServer, update_path, update_username, update_password);
37+
httpServer.begin();
38+
39+
MDNS.addService("http", "tcp", 80);
40+
Serial.printf("HTTPUpdateServer ready! Open http://%s.local%s in your browser and login with username '%s' and password '%s'\n", host, update_path, update_username, update_password);
41+
}
42+
43+
void loop(void){
44+
httpServer.handleClient();
45+
}

libraries/ESP8266HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino

-1
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,4 @@ void setup(void){
3939

4040
void loop(void){
4141
httpServer.handleClient();
42-
delay(1);
4342
}

libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.cpp

+27-12
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,41 @@
77

88

99
const char* ESP8266HTTPUpdateServer::_serverIndex =
10-
R"(<html><body><form method='POST' action='/update' enctype='multipart/form-data'>
10+
R"(<html><body><form method='POST' action='' enctype='multipart/form-data'>
1111
<input type='file' name='update'>
1212
<input type='submit' value='Update'>
1313
</form>
1414
</body></html>)";
15+
const char* ESP8266HTTPUpdateServer::_failedResponse = R"(Update Failed!)";
16+
const char* ESP8266HTTPUpdateServer::_successResponse = "<META http-equiv=\"refresh\" content=\"15;URL=\">Update Success! Rebooting...";
1517

1618
ESP8266HTTPUpdateServer::ESP8266HTTPUpdateServer(bool serial_debug)
1719
{
1820
_serial_output = serial_debug;
1921
_server = NULL;
22+
_username = NULL;
23+
_password = NULL;
24+
_authenticated = false;
2025
}
2126

22-
void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
27+
void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server, const char * path, const char * username, const char * password)
2328
{
2429
_server = server;
30+
_username = (char *)username;
31+
_password = (char *)password;
2532

2633
// handler for the /update form page
27-
_server->on("/update", HTTP_GET, [&](){
28-
_server->sendHeader("Connection", "close");
29-
_server->sendHeader("Access-Control-Allow-Origin", "*");
34+
_server->on(path, HTTP_GET, [&](){
35+
if(_username != NULL && _password != NULL && !_server->authenticate(_username, _password))
36+
return _server->requestAuthentication();
3037
_server->send(200, "text/html", _serverIndex);
3138
});
3239

3340
// handler for the /update form POST (once file upload finishes)
34-
_server->on("/update", HTTP_POST, [&](){
35-
_server->sendHeader("Connection", "close");
36-
_server->sendHeader("Access-Control-Allow-Origin", "*");
37-
_server->send(200, "text/html", (Update.hasError())?"FAIL":"<META http-equiv=\"refresh\" content=\"15;URL=/update\">OK");
41+
_server->on(path, HTTP_POST, [&](){
42+
if(!_authenticated)
43+
return _server->requestAuthentication();
44+
_server->send(200, "text/html", Update.hasError() ? _failedResponse : _successResponse);
3845
ESP.restart();
3946
},[&](){
4047
// handler for the file upload, get's the sketch bytes, and writes
@@ -43,27 +50,35 @@ void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
4350
if(upload.status == UPLOAD_FILE_START){
4451
if (_serial_output)
4552
Serial.setDebugOutput(true);
53+
54+
_authenticated = (_username == NULL || _password == NULL || _server->authenticate(_username, _password));
55+
if(!_authenticated){
56+
if (_serial_output)
57+
Serial.printf("Unauthenticated Update\n");
58+
return;
59+
}
60+
4661
WiFiUDP::stopAll();
4762
if (_serial_output)
4863
Serial.printf("Update: %s\n", upload.filename.c_str());
4964
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
5065
if(!Update.begin(maxSketchSpace)){//start with max available size
5166
if (_serial_output) Update.printError(Serial);
5267
}
53-
} else if(upload.status == UPLOAD_FILE_WRITE){
68+
} else if(_authenticated && upload.status == UPLOAD_FILE_WRITE){
5469
if (_serial_output) Serial.printf(".");
5570
if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
5671
if (_serial_output) Update.printError(Serial);
5772

5873
}
59-
} else if(upload.status == UPLOAD_FILE_END){
74+
} else if(_authenticated && upload.status == UPLOAD_FILE_END){
6075
if(Update.end(true)){ //true to set the size to the current progress
6176
if (_serial_output) Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
6277
} else {
6378
if (_serial_output) Update.printError(Serial);
6479
}
6580
if (_serial_output) Serial.setDebugOutput(false);
66-
} else if(upload.status == UPLOAD_FILE_ABORTED){
81+
} else if(_authenticated && upload.status == UPLOAD_FILE_ABORTED){
6782
Update.end();
6883
if (_serial_output) Serial.println("Update was aborted");
6984
}

libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.h

+22-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,30 @@ class ESP8266HTTPUpdateServer
99
bool _serial_output;
1010
ESP8266WebServer *_server;
1111
static const char *_serverIndex;
12+
static const char *_failedResponse;
13+
static const char *_successResponse;
14+
char * _username;
15+
char * _password;
16+
bool _authenticated;
1217
public:
1318
ESP8266HTTPUpdateServer(bool serial_debug=false);
14-
void setup(ESP8266WebServer *server=NULL);
19+
20+
void setup(ESP8266WebServer *server)
21+
{
22+
setup(server, NULL, NULL);
23+
}
24+
25+
void setup(ESP8266WebServer *server, const char * path)
26+
{
27+
setup(server, path, NULL, NULL);
28+
}
29+
30+
void setup(ESP8266WebServer *server, const char * username, const char * password)
31+
{
32+
setup(server, "/update", username, password);
33+
}
34+
35+
void setup(ESP8266WebServer *server, const char * path, const char * username, const char * password);
1536
};
1637

1738

0 commit comments

Comments
 (0)