mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Merge pull request #1257 from Links2004/httpUpdate
check bin magic, add peekBytes
This commit is contained in:
commit
005d9d0bfd
@ -177,7 +177,36 @@ uint32_t EspClass::getFlashChipSize(void)
|
|||||||
uint8_t * bytes = (uint8_t *) &data;
|
uint8_t * bytes = (uint8_t *) &data;
|
||||||
// read first 4 byte (magic byte + flash config)
|
// read first 4 byte (magic byte + flash config)
|
||||||
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
||||||
switch((bytes[3] & 0xf0) >> 4) {
|
return magicFlashChipSize((bytes[3] & 0xf0) >> 4);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t EspClass::getFlashChipSpeed(void)
|
||||||
|
{
|
||||||
|
uint32_t data;
|
||||||
|
uint8_t * bytes = (uint8_t *) &data;
|
||||||
|
// read first 4 byte (magic byte + flash config)
|
||||||
|
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
||||||
|
return magicFlashChipSpeed(bytes[3] & 0x0F);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashMode_t EspClass::getFlashChipMode(void)
|
||||||
|
{
|
||||||
|
FlashMode_t mode = FM_UNKNOWN;
|
||||||
|
uint32_t data;
|
||||||
|
uint8_t * bytes = (uint8_t *) &data;
|
||||||
|
// read first 4 byte (magic byte + flash config)
|
||||||
|
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
||||||
|
mode = magicFlashChipMode(bytes[2]);
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
|
||||||
|
switch(byte & 0x0F) {
|
||||||
case 0x0: // 4 Mbit (512KB)
|
case 0x0: // 4 Mbit (512KB)
|
||||||
return (512_kB);
|
return (512_kB);
|
||||||
case 0x1: // 2 MBit (256KB)
|
case 0x1: // 2 MBit (256KB)
|
||||||
@ -198,16 +227,9 @@ uint32_t EspClass::getFlashChipSize(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t EspClass::getFlashChipSpeed(void)
|
uint32_t EspClass::magicFlashChipSpeed(uint8_t byte) {
|
||||||
{
|
switch(byte & 0x0F) {
|
||||||
uint32_t data;
|
|
||||||
uint8_t * bytes = (uint8_t *) &data;
|
|
||||||
// read first 4 byte (magic byte + flash config)
|
|
||||||
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
|
||||||
switch(bytes[3] & 0x0F) {
|
|
||||||
case 0x0: // 40 MHz
|
case 0x0: // 40 MHz
|
||||||
return (40_MHz);
|
return (40_MHz);
|
||||||
case 0x1: // 26 MHz
|
case 0x1: // 26 MHz
|
||||||
@ -220,21 +242,12 @@ uint32_t EspClass::getFlashChipSpeed(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlashMode_t EspClass::getFlashChipMode(void)
|
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte) {
|
||||||
{
|
FlashMode_t mode = (FlashMode_t) byte;
|
||||||
FlashMode_t mode = FM_UNKNOWN;
|
|
||||||
uint32_t data;
|
|
||||||
uint8_t * bytes = (uint8_t *) &data;
|
|
||||||
// read first 4 byte (magic byte + flash config)
|
|
||||||
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
|
|
||||||
mode = (FlashMode_t) bytes[2];
|
|
||||||
if(mode > FM_DOUT) {
|
if(mode > FM_DOUT) {
|
||||||
mode = FM_UNKNOWN;
|
mode = FM_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +117,10 @@ class EspClass {
|
|||||||
FlashMode_t getFlashChipMode();
|
FlashMode_t getFlashChipMode();
|
||||||
uint32_t getFlashChipSizeByChipId();
|
uint32_t getFlashChipSizeByChipId();
|
||||||
|
|
||||||
|
uint32_t magicFlashChipSize(uint8_t byte);
|
||||||
|
uint32_t magicFlashChipSpeed(uint8_t byte);
|
||||||
|
FlashMode_t magicFlashChipMode(uint8_t byte);
|
||||||
|
|
||||||
bool checkFlashConfig(bool needsEquals = false);
|
bool checkFlashConfig(bool needsEquals = false);
|
||||||
|
|
||||||
bool flashEraseSector(uint32_t sector);
|
bool flashEraseSector(uint32_t sector);
|
||||||
|
@ -239,6 +239,27 @@ int WiFiClient::peek()
|
|||||||
return _client->peek();
|
return _client->peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) {
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if(!_client) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_startMillis = millis();
|
||||||
|
while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(available() < (int) length) {
|
||||||
|
count = available();
|
||||||
|
} else {
|
||||||
|
count = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _client->peekBytes((char *)buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
void WiFiClient::flush()
|
void WiFiClient::flush()
|
||||||
{
|
{
|
||||||
if (_client)
|
if (_client)
|
||||||
|
@ -56,6 +56,10 @@ public:
|
|||||||
virtual int read();
|
virtual int read();
|
||||||
virtual int read(uint8_t *buf, size_t size);
|
virtual int read(uint8_t *buf, size_t size);
|
||||||
virtual int peek();
|
virtual int peek();
|
||||||
|
virtual size_t peekBytes(uint8_t *buffer, size_t length);
|
||||||
|
size_t peekBytes(char *buffer, size_t length) {
|
||||||
|
return peekBytes((uint8_t *) buffer, length);
|
||||||
|
}
|
||||||
virtual void flush();
|
virtual void flush();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual uint8_t connected();
|
virtual uint8_t connected();
|
||||||
|
@ -133,6 +133,17 @@ public:
|
|||||||
return _read_ptr[0];
|
return _read_ptr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t peekBytes(char *dst, size_t size) {
|
||||||
|
if(!_available) {
|
||||||
|
if(!_readAll())
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t will_copy = (_available < size) ? _available : size;
|
||||||
|
memcpy(dst, _read_ptr, will_copy);
|
||||||
|
return will_copy;
|
||||||
|
}
|
||||||
|
|
||||||
int available() {
|
int available() {
|
||||||
auto cb = _available;
|
auto cb = _available;
|
||||||
if (cb == 0) {
|
if (cb == 0) {
|
||||||
@ -278,6 +289,27 @@ int WiFiClientSecure::peek() {
|
|||||||
return _ssl->peek();
|
return _ssl->peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if(!_ssl) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_startMillis = millis();
|
||||||
|
while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(available() < (int) length) {
|
||||||
|
count = available();
|
||||||
|
} else {
|
||||||
|
count = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _ssl->peekBytes((char *)buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
int WiFiClientSecure::available() {
|
int WiFiClientSecure::available() {
|
||||||
if (!_ssl)
|
if (!_ssl)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
int available() override;
|
int available() override;
|
||||||
int read() override;
|
int read() override;
|
||||||
int peek() override;
|
int peek() override;
|
||||||
|
size_t peekBytes(uint8_t *buffer, size_t length) override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
void setCertificate(const uint8_t* cert_data, size_t size);
|
void setCertificate(const uint8_t* cert_data, size_t size);
|
||||||
|
@ -179,6 +179,20 @@ class ClientContext {
|
|||||||
return reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
|
return reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t peekBytes(char *dst, size_t size) {
|
||||||
|
if(!_rx_buf) return 0;
|
||||||
|
|
||||||
|
size_t max_size = _rx_buf->tot_len - _rx_buf_offset;
|
||||||
|
size = (size < max_size) ? size : max_size;
|
||||||
|
|
||||||
|
DEBUGV(":pd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset);
|
||||||
|
size_t buf_size = _rx_buf->len - _rx_buf_offset;
|
||||||
|
size_t copy_size = (size < buf_size) ? size : buf_size;
|
||||||
|
DEBUGV(":rpi %d, %d\r\n", buf_size, copy_size);
|
||||||
|
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, copy_size);
|
||||||
|
return copy_size;
|
||||||
|
}
|
||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
if(!_rx_buf) {
|
if(!_rx_buf) {
|
||||||
return;
|
return;
|
||||||
|
@ -124,6 +124,12 @@ String ESP8266HTTPUpdate::getLastErrorString(void) {
|
|||||||
return String("Forbidden (403)");
|
return String("Forbidden (403)");
|
||||||
case HTTP_UE_SERVER_WRONG_HTTP_CODE:
|
case HTTP_UE_SERVER_WRONG_HTTP_CODE:
|
||||||
return String("Wrong HTTP code");
|
return String("Wrong HTTP code");
|
||||||
|
case HTTP_UE_SERVER_FAULTY_MD5:
|
||||||
|
return String("Faulty MD5");
|
||||||
|
case HTTP_UE_BIN_VERIFY_HEADER_FAILED:
|
||||||
|
return String("Verify bin header failed");
|
||||||
|
case HTTP_UE_BIN_FOR_WRONG_FLASH:
|
||||||
|
return String("bin for wrong flash size");
|
||||||
}
|
}
|
||||||
|
|
||||||
return String();
|
return String();
|
||||||
@ -232,6 +238,33 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
|
|||||||
DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n");
|
DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t buf[4];
|
||||||
|
if(tcp->peekBytes(&buf[0], 4) != 4) {
|
||||||
|
DEBUG_HTTP_UPDATE("[httpUpdate] peekBytes magic header failed\n");
|
||||||
|
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
|
||||||
|
http->end();
|
||||||
|
return HTTP_UPDATE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for valid first magic byte
|
||||||
|
if(buf[0] != 0xE9) {
|
||||||
|
DEBUG_HTTP_UPDATE("[httpUpdate] magic header not starts with 0xE9\n");
|
||||||
|
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
|
||||||
|
http->end();
|
||||||
|
return HTTP_UPDATE_FAILED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4);
|
||||||
|
|
||||||
|
// check if new bin fits to SPI flash
|
||||||
|
if(bin_flash_size > ESP.getFlashChipRealSize()) {
|
||||||
|
DEBUG_HTTP_UPDATE("[httpUpdate] magic header, new bin not fits SPI Flash\n");
|
||||||
|
lastError = HTTP_UE_BIN_FOR_WRONG_FLASH;
|
||||||
|
http->end();
|
||||||
|
return HTTP_UPDATE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
|
if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
|
||||||
ret = HTTP_UPDATE_OK;
|
ret = HTTP_UPDATE_OK;
|
||||||
DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
|
DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
|
||||||
|
@ -45,6 +45,8 @@
|
|||||||
#define HTTP_UE_SERVER_FORBIDDEN (-103)
|
#define HTTP_UE_SERVER_FORBIDDEN (-103)
|
||||||
#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104)
|
#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104)
|
||||||
#define HTTP_UE_SERVER_FAULTY_MD5 (-105)
|
#define HTTP_UE_SERVER_FAULTY_MD5 (-105)
|
||||||
|
#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106)
|
||||||
|
#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HTTP_UPDATE_FAILED,
|
HTTP_UPDATE_FAILED,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user