From 9632e868d5559eac48a0b72ef27157ea25b5ce4a Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 16 Apr 2020 15:15:00 -0700 Subject: [PATCH] Fix espota completion success/fail check (#7204) The OTA script was not reporting the actual reported upload status from the ESP8266, and instead always printed "Result: OK" no matter what happened. Now check for ERROR or OK in final message (and ensure the message is not accidentally merged with the final byte count) and report properly. Fixes #7162 --- libraries/ArduinoOTA/ArduinoOTA.cpp | 8 ++++++-- tools/espota.py | 30 +++++++++++++++++------------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/libraries/ArduinoOTA/ArduinoOTA.cpp b/libraries/ArduinoOTA/ArduinoOTA.cpp index 0b0789474..64e8397a2 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/ArduinoOTA.cpp @@ -328,9 +328,13 @@ void ArduinoOTAClass::_runUpdate() { } if (Update.end()) { - client.print("OK"); - client.stop(); + // Ensure last count packet has been sent out and not combined with the final OK + client.flush(); delay(1000); + client.print("OK"); + client.flush(); + delay(1000); + client.stop(); #ifdef OTA_DEBUG OTA_DEBUG.printf("Update Success\n"); #endif diff --git a/tools/espota.py b/tools/espota.py index 373020a91..d6b5a8086 100755 --- a/tools/espota.py +++ b/tools/espota.py @@ -132,7 +132,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm sys.stderr.write('FAIL\n') logging.error('%s', data) sock2.close() - sys.exit(1); + sys.exit(1) return 1 sys.stderr.write('OK\n') else: @@ -172,7 +172,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm connection.sendall(chunk) if connection.recv(32).decode().find('O') >= 0: # connection will receive only digits or 'OK' - received_ok = True; + received_ok = True except: sys.stderr.write('\n') logging.error('Error Uploading') @@ -188,19 +188,25 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm # the connection before receiving the 'O' of 'OK' try: connection.settimeout(60) - while not received_ok: - if connection.recv(32).decode().find('O') >= 0: - # connection will receive only digits or 'OK' - received_ok = True; - logging.info('Result: OK') + received_ok = False + received_error = False + while not (received_ok or received_error): + reply = connection.recv(64).decode() + # Look for either the "E" in ERROR or the "O" in OK response + # Check for "E" first, since both strings contain "O" + if reply.find('E') >= 0: + sys.stderr.write('\n') + logging.error('%s', reply) + received_error = True + elif reply.find('O') >= 0: + logging.info('Result: OK') + received_ok = True connection.close() f.close() sock.close() - if (data != "OK"): - sys.stderr.write('\n') - logging.error('%s', data) - return 1; - return 0 + if received_ok: + return 0 + return 1 except: logging.error('No Result!') connection.close()