Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDE OTA Upload changes #980

Merged
merged 8 commits into from
Nov 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions cores/esp8266/MD5Builder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "Arduino.h"
#include "md5.h"
#include "MD5Builder.h"

#define hex_char_to_byte(c) (((c)>='a'&&(c)<='f')?((c)-87):((c)>='A'&&(c)<='F')?((c)-55):((c)>='0'&&(c)<='9')?((c)-48):0)

void MD5Builder::begin(void){
memset(_buf, 0x00, 16);
MD5Init(&_ctx);
}

void MD5Builder::add(uint8_t * data, uint16_t len){
MD5Update(&_ctx, data, len);
}

void MD5Builder::addHexString(const char * data){
uint16_t i, len = strlen(data);
uint8_t * tmp = (uint8_t*)malloc(len/2);
if(tmp == NULL)
return;
for(i=0; i<len; i+=2) tmp[i/2] = (hex_char_to_byte(data[i]) & 0x0F) << 4 | (hex_char_to_byte(data[i+1]) & 0x0F);
add(tmp, len/2);
free(tmp);
}

void MD5Builder::calculate(void){
MD5Final(_buf, &_ctx);
}

void MD5Builder::getBytes(uint8_t * output){
memcpy(output, _buf, 16);
}

void MD5Builder::getChars(char * output){
for(uint8_t i = 0; i < 16; i++)
sprintf(output + (i * 2), "%02x", _buf[i]);
}

String MD5Builder::toString(void){
char out[32];
getChars(out);
return String(out);
}
47 changes: 47 additions & 0 deletions cores/esp8266/MD5Builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
md5.h - exposed md5 ROM functions for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ESP8266_MD5_BUILDER__
#define __ESP8266_MD5_BUILDER__

#include "Arduino.h"
#include "md5.h"

class MD5Builder {
private:
md5_context_t _ctx;
uint8_t _buf[16];
public:
void begin(void);
void add(uint8_t * data, uint16_t len);
void add(const char * data){ add((uint8_t*)data, strlen(data)); }
void add(char * data){ add((const char*)data); }
void add(String data){ add(data.c_str()); }
void addHexString(const char * data);
void addHexString(char * data){ addHexString((const char*)data); }
void addHexString(String data){ addHexString(data.c_str()); }
void calculate(void);
void getBytes(uint8_t * output);
void getChars(char * output);
String toString(void);
};


#endif
29 changes: 27 additions & 2 deletions cores/esp8266/Updater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void UpdaterClass::_reset() {
_currentAddress = 0;
_size = 0;
_command = U_FLASH;
_target_md5 = 0;
}

bool UpdaterClass::begin(size_t size, int command) {
Expand Down Expand Up @@ -96,10 +97,17 @@ 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);
}

bool UpdaterClass::end(bool evenIfRemaining){
if(_size == 0){
#ifdef DEBUG_UPDATER
Expand All @@ -123,7 +131,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){
_error = UPDATE_ERROR_MD5;
#ifdef DEBUG_UPDATER
DEBUG_UPDATER.printf("MD5 Failed: expected:%s, calculated:%s\n", _target_md5, _md5.toString().c_str());
#endif
return false;
}
#ifdef DEBUG_UPDATER
else DEBUG_UPDATER.printf("MD5 Success: %s\n", _md5.toString().c_str());
#endif
}

if (_command == U_FLASH) {
eboot_command ebcmd;
ebcmd.action = ACTION_COPY_RAW;
Expand Down Expand Up @@ -157,6 +179,7 @@ bool UpdaterClass::_writeBuffer(){
#endif
return false;
}
_md5.add(_buffer, _bufferLen);
_currentAddress += _bufferLen;
_bufferLen = 0;
return true;
Expand Down Expand Up @@ -232,6 +255,8 @@ void UpdaterClass::printError(Stream &out){
out.println("Bad Size Given");
} else if(_error == UPDATE_ERROR_STREAM){
out.println("Stream Read Timeout");
} else if(_error == UPDATE_ERROR_MD5){
out.println("MD5 Check Failed");
} else {
out.println("UNKNOWN");
}
Expand Down
24 changes: 22 additions & 2 deletions cores/esp8266/Updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@

#include "Arduino.h"
#include "flash_utils.h"
#include "MD5Builder.h"

#define UPDATE_ERROR_OK 0
#define UPDATE_ERROR_WRITE 1
#define UPDATE_ERROR_ERASE 2
#define UPDATE_ERROR_SPACE 3
#define UPDATE_ERROR_SIZE 4
#define UPDATE_ERROR_STREAM 5
#define UPDATE_ERROR_MD5 6

#define U_FLASH 0
#define U_SPIFFS 100

//#define DEBUG_UPDATER Serial1
//#define DEBUG_UPDATER Serial

class UpdaterClass {
public:
Expand Down Expand Up @@ -56,7 +58,22 @@ class UpdaterClass {
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; }
Expand Down Expand Up @@ -103,7 +120,7 @@ class UpdaterClass {
}
if(remaining() == 0)
return written;
yield();
delay(1);
available = data.available();
}
return written;
Expand All @@ -120,6 +137,9 @@ class UpdaterClass {
uint32_t _startAddress;
uint32_t _currentAddress;
uint32_t _command;

char *_target_md5;
MD5Builder _md5;
};

extern UpdaterClass Update;
Expand Down
44 changes: 44 additions & 0 deletions cores/esp8266/md5.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
md5.h - exposed md5 ROM functions for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

original C source from https://github.com/morrissinger/ESP8266-Websocket/raw/master/MD5.h

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ESP8266_MD5__
#define __ESP8266_MD5__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
uint32_t state[4];
uint32_t count[2];
uint8_t buffer[64];
} md5_context_t;

extern void MD5Init (md5_context_t *);
extern void MD5Update (md5_context_t *, uint8_t *, uint16_t);
extern void MD5Final (uint8_t [16], md5_context_t *);

#ifdef __cplusplus
} // extern "C"
#endif

#endif
Loading