diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 49b1ddd3e..7e6b2e4e1 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -32,7 +32,6 @@ void UpdaterClass::_reset() { _currentAddress = 0; _size = 0; _command = U_FLASH; - _target_md5 = 0; } bool UpdaterClass::begin(size_t size, int command) { @@ -97,15 +96,14 @@ bool UpdaterClass::begin(size_t size, int command) { _size = size; _buffer = new uint8_t[FLASH_SECTOR_SIZE]; _command = command; - - _target_md5 = new char[64]; + _md5.begin(); return true; } void UpdaterClass::setMD5(const char * expected_md5){ if(strlen(expected_md5) != 32) return; - strcpy(_target_md5, expected_md5); + _target_md5 = expected_md5; } bool UpdaterClass::end(bool evenIfRemaining){ @@ -131,21 +129,21 @@ bool UpdaterClass::end(bool evenIfRemaining){ } _size = progress(); } - + _md5.calculate(); - if(_target_md5 && strlen(_target_md5) == 32){ - if(strcmp(_target_md5, _md5.toString().c_str()) != 0){ + if(_target_md5.length()) { + if(_target_md5 != _md5.toString()){ _error = UPDATE_ERROR_MD5; #ifdef DEBUG_UPDATER - DEBUG_UPDATER.printf("MD5 Failed: expected:%s, calculated:%s\n", _target_md5, _md5.toString().c_str()); + DEBUG_UPDATER.printf("MD5 Failed: expected:%s, calculated:%s\n", _target_md5.c_str(), _md5.toString().c_str()); #endif return false; } #ifdef DEBUG_UPDATER - else DEBUG_UPDATER.printf("MD5 Success: %s\n", _md5.toString().c_str()); + else DEBUG_UPDATER.printf("MD5 Success: %s\n", _target_md5.c_str()); #endif } - + if (_command == U_FLASH) { eboot_command ebcmd; ebcmd.action = ACTION_COPY_RAW; diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index 5b0a56de2..b9f1b3d06 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -15,6 +15,7 @@ #define U_FLASH 0 #define U_SPIFFS 100 +#define U_AUTH 200 //#define DEBUG_UPDATER Serial @@ -26,13 +27,13 @@ class UpdaterClass { Will return false if there is not enough space */ bool begin(size_t size, int = U_FLASH); - + /* Writes a buffer to the flash and increments the address Returns the amount written */ size_t write(uint8_t *data, size_t len); - + /* Writes the remaining bytes from the Stream to the flash Uses readBytes() and sets UPDATE_ERROR_STREAM on timeout @@ -41,7 +42,7 @@ class UpdaterClass { Usable for slow streams like Serial */ size_t writeStream(Stream &data); - + /* If all bytes are written this call will write the config to eboot @@ -53,27 +54,27 @@ class UpdaterClass { evenIfRemaining is helpfull when you update without knowing the final size first */ bool end(bool evenIfRemaining = false); - + /* Prints the last error to an output stream */ void printError(Stream &out); - + /* sets the expected MD5 for the firmware (hexString) */ void setMD5(const char * expected_md5); - + /* returns the MD5 String of the sucessfully ended firmware */ String md5String(void){ return _md5.toString(); } - + /* populated the result with the md5 bytes of the sucessfully ended firmware */ void md5(uint8_t * result){ return _md5.getBytes(result); } - + //Helpers uint8_t getError(){ return _error; } void clearError(){ _error = UPDATE_ERROR_OK; } @@ -83,7 +84,7 @@ class UpdaterClass { size_t size(){ return _size; } size_t progress(){ return _currentAddress - _startAddress; } size_t remaining(){ return _size - (_currentAddress - _startAddress); } - + /* Template to write from objects that expose available() and read(uint8_t*, size_t) methods @@ -125,7 +126,7 @@ class UpdaterClass { } return written; } - + private: void _reset(); bool _writeBuffer(); @@ -137,8 +138,8 @@ class UpdaterClass { uint32_t _startAddress; uint32_t _currentAddress; uint32_t _command; - - char *_target_md5; + + String _target_md5; MD5Builder _md5; }; diff --git a/libraries/ArduinoOTA/ArduinoOTA.cpp b/libraries/ArduinoOTA/ArduinoOTA.cpp index 4014c4384..5833d2f5b 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/ArduinoOTA.cpp @@ -6,154 +6,160 @@ //#define OTA_DEBUG 1 -#define U_AUTH 200 - ArduinoOTAClass::ArduinoOTAClass() +: _port(0) +, _state(OTA_IDLE) +, _size(0) +, _cmd(0) +, _ota_port(0) +, _start_callback(NULL) +, _end_callback(NULL) +, _progress_callback(NULL) +, _error_callback(NULL) { - _udp_ota = new WiFiUDP(); - _password = 0; - _hostname = 0; - _port = 0; - _nonce = 0; - _state = OTA_IDLE; - - _size = 0; - _cmd = 0; - _ota_port = 0; - _ota_ip = (uint32_t)0; - _md5 = new char[33]; - - _start_callback = NULL; - _end_callback = NULL; - _progress_callback = NULL; - _error_callback = NULL; } -void ArduinoOTAClass::onStart(OTA_CALLBACK(fn)){ +void ArduinoOTAClass::onStart(OTA_CALLBACK(fn)) { _start_callback = fn; } -void ArduinoOTAClass::onEnd(OTA_CALLBACK(fn)){ +void ArduinoOTAClass::onEnd(OTA_CALLBACK(fn)) { _end_callback = fn; } -void ArduinoOTAClass::onProgress(OTA_CALLBACK_PROGRESS(fn)){ +void ArduinoOTAClass::onProgress(OTA_CALLBACK_PROGRESS(fn)) { _progress_callback = fn; } -void ArduinoOTAClass::onError(OTA_CALLBACK_ERROR(fn)){ +void ArduinoOTAClass::onError(OTA_CALLBACK_ERROR(fn)) { _error_callback = fn; } -ArduinoOTAClass::~ArduinoOTAClass(){ - delete _udp_ota; +ArduinoOTAClass::~ArduinoOTAClass() { } -void ArduinoOTAClass::setPort(uint16_t port){ - if(!_initialized && !_port && port){ +void ArduinoOTAClass::setPort(uint16_t port) { + if (!_initialized && !_port && port) { _port = port; } } -void ArduinoOTAClass::setHostname(const char * hostname){ - if(!_initialized && !_hostname && hostname){ - _hostname = new char[strlen(hostname)]; - sprintf(_hostname, "%s", hostname); +void ArduinoOTAClass::setHostname(const char * hostname) { + if (!_initialized && !_hostname.length() && hostname) { + _hostname = hostname; } } -void ArduinoOTAClass::setPassword(const char * password){ - if(!_initialized && !_password && password){ - _password = new char[strlen(password)]; - sprintf(_password, "%s", password); +void ArduinoOTAClass::setPassword(const char * password) { + if (!_initialized && !_password.length() && password) { + _password = password; } } void ArduinoOTAClass::begin() { - if(_initialized) + if (_initialized) return; _initialized = true; - if(!_hostname){ - _hostname = new char[15]; - sprintf(_hostname, "esp8266-%02x", ESP.getChipId()); + + if (!_hostname.length()) { + char tmp[15]; + sprintf(tmp, "esp8266-%02x", ESP.getChipId()); + _hostname = tmp; } - if(!_port) + if (!_port) { _port = 8266; - - _udp_ota->begin(_port); - MDNS.begin(_hostname); - if(_password){ - _nonce = new char[33]; + } + + _udp_ota.begin(_port); + MDNS.begin(_hostname.c_str()); + + if (_password.length()) { MDNS.enableArduino(_port, true); - } else + } else { MDNS.enableArduino(_port); + } _state = OTA_IDLE; #if OTA_DEBUG - Serial.printf("OTA server at: %s.local:%u\n", _hostname, _port); + Serial.printf("OTA server at: %s.local:%u\n", _hostname.c_str(), _port); #endif } -void ArduinoOTAClass::_runUpdate(){ - if(!Update.begin(_size, _cmd)){ +void ArduinoOTAClass::_runUpdate() { + if (!Update.begin(_size, _cmd)) { #if OTA_DEBUG Serial.println("Update Begin Error"); #endif - if (_error_callback) _error_callback(OTA_BEGIN_ERROR); - _udp_ota->begin(_port); + if (_error_callback) { + _error_callback(OTA_BEGIN_ERROR); + } + _udp_ota.begin(_port); _state = OTA_IDLE; return; } - Update.setMD5(_md5); + Update.setMD5(_md5.c_str()); WiFiUDP::stopAll(); WiFiClient::stopAll(); - - - if (_start_callback) _start_callback(); - if (_progress_callback) _progress_callback(0, _size); + + if (_start_callback) { + _start_callback(); + } + if (_progress_callback) { + _progress_callback(0, _size); + } WiFiClient client; if (!client.connect(_ota_ip, _ota_port)) { #if OTA_DEBUG Serial.printf("Connect Failed\n"); #endif - _udp_ota->begin(_port); - if (_error_callback) _error_callback(OTA_CONNECT_ERROR); + _udp_ota.begin(_port); + if (_error_callback) { + _error_callback(OTA_CONNECT_ERROR); + } _state = OTA_IDLE; } uint32_t written, total = 0; - while(!Update.isFinished() && client.connected()){ + while (!Update.isFinished() && client.connected()) { int waited = 1000; - while(!client.available() && waited--) + while (!client.available() && waited--) delay(1); - if(!waited){ + if (!waited){ #if OTA_DEBUG Serial.printf("Recieve Failed\n"); #endif - _udp_ota->begin(_port); - if (_error_callback) _error_callback(OTA_RECIEVE_ERROR); + _udp_ota.begin(_port); + if (_error_callback) { + _error_callback(OTA_RECIEVE_ERROR); + } _state = OTA_IDLE; } - written = Update.write(client); - if(written > 0){ + written = Update.write(client); + if (written > 0) { client.print(written, DEC); total += written; - if(_progress_callback) _progress_callback(total, _size); + if(_progress_callback) { + _progress_callback(total, _size); + } } } - if(Update.end()){ + if (Update.end()) { client.print("OK"); client.stop(); delay(10); #if OTA_DEBUG Serial.printf("Update Success\nRebooting...\n"); #endif - if(_end_callback) _end_callback(); + if (_end_callback) { + _end_callback(); + } ESP.restart(); } else { - _udp_ota->begin(_port); - if (_error_callback) _error_callback(OTA_END_ERROR); + _udp_ota.begin(_port); + if (_error_callback) { + _error_callback(OTA_END_ERROR); + } Update.printError(client); #if OTA_DEBUG Update.printError(Serial); @@ -163,64 +169,65 @@ void ArduinoOTAClass::_runUpdate(){ } void ArduinoOTAClass::handle() { - if (!*_udp_ota) { - _udp_ota->begin(_port); + if (!_udp_ota) { + _udp_ota.begin(_port); #if OTA_DEBUG - Serial.println("OTA restarted"); + Serial.println("OTA restarted"); #endif } - if (!_udp_ota->parsePacket()) return; + if (!_udp_ota.parsePacket()) return; - if(_state == OTA_IDLE){ - int cmd = _udp_ota->parseInt(); - if(cmd != U_FLASH && cmd != U_SPIFFS) + if (_state == OTA_IDLE) { + int cmd = _udp_ota.parseInt(); + if (cmd != U_FLASH && cmd != U_SPIFFS) return; - _ota_ip = _udp_ota->remoteIP(); + _ota_ip = _udp_ota.remoteIP(); _cmd = cmd; - _ota_port = _udp_ota->parseInt(); - _size = _udp_ota->parseInt(); - _udp_ota->read(); - sprintf(_md5, "%s", _udp_ota->readStringUntil('\n').c_str()); - if(strlen(_md5) != 32) + _ota_port = _udp_ota.parseInt(); + _size = _udp_ota.parseInt(); + _udp_ota.read(); + _md5 = _udp_ota.readStringUntil('\n'); + _md5.trim(); + if(_md5.length() != 32) return; #if OTA_DEBUG Serial.print("Update Start: ip:"); Serial.print(_ota_ip); - Serial.printf(", port:%d, size:%d, md5:%s\n", _ota_port, _size, _md5); + Serial.printf(", port:%d, size:%d, md5:%s\n", _ota_port, _size, _md5.c_str()); #endif - - _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); - if(_password){ + + _udp_ota.beginPacket(_ota_ip, _udp_ota.remotePort()); + if (_password){ MD5Builder nonce_md5; nonce_md5.begin(); nonce_md5.add(String(micros())); nonce_md5.calculate(); - nonce_md5.getChars(_nonce); - _udp_ota->printf("AUTH %s", _nonce); - _udp_ota->endPacket(); + _nonce = nonce_md5.toString(); + _udp_ota.printf("AUTH %s", _nonce.c_str()); + _udp_ota.endPacket(); _state = OTA_WAITAUTH; return; } else { - _udp_ota->print("OK"); - _udp_ota->endPacket(); + _udp_ota.print("OK"); + _udp_ota.endPacket(); _state = OTA_RUNUPDATE; } - } else if(_state == OTA_WAITAUTH){ - int cmd = _udp_ota->parseInt(); - if(cmd != U_AUTH){ + } else if (_state == OTA_WAITAUTH) { + int cmd = _udp_ota.parseInt(); + if (cmd != U_AUTH) { _state = OTA_IDLE; return; } - _udp_ota->read(); - String cnonce = _udp_ota->readStringUntil(' '); - String response = _udp_ota->readStringUntil('\n'); - if(cnonce.length() != 32 || response.length() != 32){ + _udp_ota.read(); + String cnonce = _udp_ota.readStringUntil(' '); + String response = _udp_ota.readStringUntil('\n'); + if (cnonce.length() != 32 || response.length() != 32) { _state = OTA_IDLE; return; } - + MD5Builder _passmd5; _passmd5.begin(); _passmd5.add(_password); @@ -235,21 +242,22 @@ void ArduinoOTAClass::handle() { String result = _challengemd5.toString(); if(result.equals(response)){ - _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); - _udp_ota->print("OK"); - _udp_ota->endPacket(); + _udp_ota.beginPacket(_ota_ip, _udp_ota.remotePort()); + _udp_ota.print("OK"); + _udp_ota.endPacket(); _state = OTA_RUNUPDATE; } else { - _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); - _udp_ota->print("Authentication Failed"); - _udp_ota->endPacket(); + _udp_ota.beginPacket(_ota_ip, _udp_ota.remotePort()); + _udp_ota.print("Authentication Failed"); + _udp_ota.endPacket(); if (_error_callback) _error_callback(OTA_AUTH_ERROR); _state = OTA_IDLE; } } - - if(_state == OTA_RUNUPDATE) + + if (_state == OTA_RUNUPDATE) { _runUpdate(); + } } ArduinoOTAClass ArduinoOTA; diff --git a/libraries/ArduinoOTA/ArduinoOTA.h b/libraries/ArduinoOTA/ArduinoOTA.h index 350c129e5..5d5161e5e 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.h +++ b/libraries/ArduinoOTA/ArduinoOTA.h @@ -23,26 +23,6 @@ typedef enum { class ArduinoOTAClass { - private: - int _port; - char *_password; - char * _hostname; - char * _nonce; - WiFiUDP* _udp_ota; - bool _initialized; - - ota_state_t _state; - int _size, _cmd, _ota_port; - IPAddress _ota_ip; - char * _md5; - - OTA_CALLBACK(_start_callback); - OTA_CALLBACK(_end_callback); - OTA_CALLBACK_ERROR(_error_callback); - OTA_CALLBACK_PROGRESS(_progress_callback); - - void _runUpdate(void); - public: ArduinoOTAClass(); ~ArduinoOTAClass(); @@ -55,6 +35,27 @@ class ArduinoOTAClass void onError(OTA_CALLBACK_ERROR (fn)); void begin(); void handle(); + + private: + int _port; + String _password; + String _hostname; + String _nonce; + WiFiUDP _udp_ota; + bool _initialized; + ota_state_t _state; + int _size; + int _cmd; + int _ota_port; + IPAddress _ota_ip; + String _md5; + + OTA_CALLBACK(_start_callback); + OTA_CALLBACK(_end_callback); + OTA_CALLBACK_ERROR(_error_callback); + OTA_CALLBACK_PROGRESS(_progress_callback); + + void _runUpdate(void); }; extern ArduinoOTAClass ArduinoOTA; diff --git a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino index 1cbb24e7b..b9150c9b1 100644 --- a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino +++ b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino @@ -3,37 +3,50 @@ #include #include -const char* ssid = "..."; -const char* password = "..."; +const char* ssid = ".........."; +const char* password = ".........."; void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); - while (WiFi.waitForConnectResult() != WL_CONNECTED){ - Serial.println("Connection Failed! Rebooting..."); - delay(5000); - ESP.reset(); + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("Connection Failed! Rebooting..."); + delay(5000); + ESP.restart(); } - //ArduinoOTA.setPort(8266);//Defaults to 8266 - //ArduinoOTA.setHostname((const char *)"myesp8266");//Defaults to esp8266-[ChipID] - //ArduinoOTA.setPassword((const char *)"123");//defaults to no authentication - ArduinoOTA.onStart([]() { Serial.println("Start"); }); - ArduinoOTA.onEnd([]() { Serial.println("End"); }); + + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + + // Hostname defaults to esp8266-[ChipID] + // ArduinoOTA.setHostname("myesp8266"); + + // No authentication by default + // ArduinoOTA.setPassword((const char *)"123"); + + ArduinoOTA.onStart([]() { + Serial.println("Start"); + }); + ArduinoOTA.onEnd([]() { + Serial.println("End"); + }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\n", (progress/(total/100))); + Serial.printf("Progress: %u%%\n", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); - if(error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); - else if(error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); - else if(error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); - else if(error == OTA_RECIEVE_ERROR) Serial.println("Recieve Failed"); - else if(error == OTA_END_ERROR) Serial.println("End Failed"); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECIEVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("Ready"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); } void loop() {