Skip to content

Commit 005d9d0

Browse files
committed
Merge pull request #1257 from Links2004/httpUpdate
check bin magic, add peekBytes
2 parents 3f0fdab + a04c225 commit 005d9d0

File tree

9 files changed

+166
-42
lines changed

9 files changed

+166
-42
lines changed

cores/esp8266/Esp.cpp

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -177,26 +177,7 @@ uint32_t EspClass::getFlashChipSize(void)
177177
uint8_t * bytes = (uint8_t *) &data;
178178
// read first 4 byte (magic byte + flash config)
179179
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
180-
switch((bytes[3] & 0xf0) >> 4) {
181-
case 0x0: // 4 Mbit (512KB)
182-
return (512_kB);
183-
case 0x1: // 2 MBit (256KB)
184-
return (256_kB);
185-
case 0x2: // 8 MBit (1MB)
186-
return (1_MB);
187-
case 0x3: // 16 MBit (2MB)
188-
return (2_MB);
189-
case 0x4: // 32 MBit (4MB)
190-
return (4_MB);
191-
case 0x5: // 64 MBit (8MB)
192-
return (8_MB);
193-
case 0x6: // 128 MBit (16MB)
194-
return (16_MB);
195-
case 0x7: // 256 MBit (32MB)
196-
return (32_MB);
197-
default: // fail?
198-
return 0;
199-
}
180+
return magicFlashChipSize((bytes[3] & 0xf0) >> 4);
200181
}
201182
return 0;
202183
}
@@ -207,18 +188,7 @@ uint32_t EspClass::getFlashChipSpeed(void)
207188
uint8_t * bytes = (uint8_t *) &data;
208189
// read first 4 byte (magic byte + flash config)
209190
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
210-
switch(bytes[3] & 0x0F) {
211-
case 0x0: // 40 MHz
212-
return (40_MHz);
213-
case 0x1: // 26 MHz
214-
return (26_MHz);
215-
case 0x2: // 20 MHz
216-
return (20_MHz);
217-
case 0xf: // 80 MHz
218-
return (80_MHz);
219-
default: // fail?
220-
return 0;
221-
}
191+
return magicFlashChipSpeed(bytes[3] & 0x0F);
222192
}
223193
return 0;
224194
}
@@ -230,10 +200,53 @@ FlashMode_t EspClass::getFlashChipMode(void)
230200
uint8_t * bytes = (uint8_t *) &data;
231201
// read first 4 byte (magic byte + flash config)
232202
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
233-
mode = (FlashMode_t) bytes[2];
234-
if(mode > FM_DOUT) {
235-
mode = FM_UNKNOWN;
236-
}
203+
mode = magicFlashChipMode(bytes[2]);
204+
}
205+
return mode;
206+
}
207+
208+
uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
209+
switch(byte & 0x0F) {
210+
case 0x0: // 4 Mbit (512KB)
211+
return (512_kB);
212+
case 0x1: // 2 MBit (256KB)
213+
return (256_kB);
214+
case 0x2: // 8 MBit (1MB)
215+
return (1_MB);
216+
case 0x3: // 16 MBit (2MB)
217+
return (2_MB);
218+
case 0x4: // 32 MBit (4MB)
219+
return (4_MB);
220+
case 0x5: // 64 MBit (8MB)
221+
return (8_MB);
222+
case 0x6: // 128 MBit (16MB)
223+
return (16_MB);
224+
case 0x7: // 256 MBit (32MB)
225+
return (32_MB);
226+
default: // fail?
227+
return 0;
228+
}
229+
}
230+
231+
uint32_t EspClass::magicFlashChipSpeed(uint8_t byte) {
232+
switch(byte & 0x0F) {
233+
case 0x0: // 40 MHz
234+
return (40_MHz);
235+
case 0x1: // 26 MHz
236+
return (26_MHz);
237+
case 0x2: // 20 MHz
238+
return (20_MHz);
239+
case 0xf: // 80 MHz
240+
return (80_MHz);
241+
default: // fail?
242+
return 0;
243+
}
244+
}
245+
246+
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte) {
247+
FlashMode_t mode = (FlashMode_t) byte;
248+
if(mode > FM_DOUT) {
249+
mode = FM_UNKNOWN;
237250
}
238251
return mode;
239252
}

cores/esp8266/Esp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ class EspClass {
117117
FlashMode_t getFlashChipMode();
118118
uint32_t getFlashChipSizeByChipId();
119119

120+
uint32_t magicFlashChipSize(uint8_t byte);
121+
uint32_t magicFlashChipSpeed(uint8_t byte);
122+
FlashMode_t magicFlashChipMode(uint8_t byte);
123+
120124
bool checkFlashConfig(bool needsEquals = false);
121125

122126
bool flashEraseSector(uint32_t sector);

libraries/ESP8266WiFi/src/WiFiClient.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,27 @@ int WiFiClient::peek()
239239
return _client->peek();
240240
}
241241

242+
size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) {
243+
size_t count = 0;
244+
245+
if(!_client) {
246+
return 0;
247+
}
248+
249+
_startMillis = millis();
250+
while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
251+
yield();
252+
}
253+
254+
if(available() < (int) length) {
255+
count = available();
256+
} else {
257+
count = length;
258+
}
259+
260+
return _client->peekBytes((char *)buffer, count);
261+
}
262+
242263
void WiFiClient::flush()
243264
{
244265
if (_client)

libraries/ESP8266WiFi/src/WiFiClient.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class WiFiClient : public Client, public SList<WiFiClient> {
5656
virtual int read();
5757
virtual int read(uint8_t *buf, size_t size);
5858
virtual int peek();
59+
virtual size_t peekBytes(uint8_t *buffer, size_t length);
60+
size_t peekBytes(char *buffer, size_t length) {
61+
return peekBytes((uint8_t *) buffer, length);
62+
}
5963
virtual void flush();
6064
virtual void stop();
6165
virtual uint8_t connected();

libraries/ESP8266WiFi/src/WiFiClientSecure.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ class SSLContext {
133133
return _read_ptr[0];
134134
}
135135

136+
size_t peekBytes(char *dst, size_t size) {
137+
if(!_available) {
138+
if(!_readAll())
139+
return -1;
140+
}
141+
142+
size_t will_copy = (_available < size) ? _available : size;
143+
memcpy(dst, _read_ptr, will_copy);
144+
return will_copy;
145+
}
146+
136147
int available() {
137148
auto cb = _available;
138149
if (cb == 0) {
@@ -278,6 +289,27 @@ int WiFiClientSecure::peek() {
278289
return _ssl->peek();
279290
}
280291

292+
size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
293+
size_t count = 0;
294+
295+
if(!_ssl) {
296+
return 0;
297+
}
298+
299+
_startMillis = millis();
300+
while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) {
301+
yield();
302+
}
303+
304+
if(available() < (int) length) {
305+
count = available();
306+
} else {
307+
count = length;
308+
}
309+
310+
return _ssl->peekBytes((char *)buffer, count);
311+
}
312+
281313
int WiFiClientSecure::available() {
282314
if (!_ssl)
283315
return 0;

libraries/ESP8266WiFi/src/WiFiClientSecure.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class WiFiClientSecure : public WiFiClient {
4646
int available() override;
4747
int read() override;
4848
int peek() override;
49+
size_t peekBytes(uint8_t *buffer, size_t length) override;
4950
void stop() override;
5051

5152
void setCertificate(const uint8_t* cert_data, size_t size);

libraries/ESP8266WiFi/src/include/ClientContext.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ class ClientContext {
179179
return reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
180180
}
181181

182+
size_t peekBytes(char *dst, size_t size) {
183+
if(!_rx_buf) return 0;
184+
185+
size_t max_size = _rx_buf->tot_len - _rx_buf_offset;
186+
size = (size < max_size) ? size : max_size;
187+
188+
DEBUGV(":pd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset);
189+
size_t buf_size = _rx_buf->len - _rx_buf_offset;
190+
size_t copy_size = (size < buf_size) ? size : buf_size;
191+
DEBUGV(":rpi %d, %d\r\n", buf_size, copy_size);
192+
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, copy_size);
193+
return copy_size;
194+
}
195+
182196
void flush() {
183197
if(!_rx_buf) {
184198
return;

libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ String ESP8266HTTPUpdate::getLastErrorString(void) {
124124
return String("Forbidden (403)");
125125
case HTTP_UE_SERVER_WRONG_HTTP_CODE:
126126
return String("Wrong HTTP code");
127+
case HTTP_UE_SERVER_FAULTY_MD5:
128+
return String("Faulty MD5");
129+
case HTTP_UE_BIN_VERIFY_HEADER_FAILED:
130+
return String("Verify bin header failed");
131+
case HTTP_UE_BIN_FOR_WRONG_FLASH:
132+
return String("bin for wrong flash size");
127133
}
128134

129135
return String();
@@ -232,6 +238,33 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
232238
DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n");
233239
}
234240

241+
uint8_t buf[4];
242+
if(tcp->peekBytes(&buf[0], 4) != 4) {
243+
DEBUG_HTTP_UPDATE("[httpUpdate] peekBytes magic header failed\n");
244+
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
245+
http->end();
246+
return HTTP_UPDATE_FAILED;
247+
}
248+
249+
// check for valid first magic byte
250+
if(buf[0] != 0xE9) {
251+
DEBUG_HTTP_UPDATE("[httpUpdate] magic header not starts with 0xE9\n");
252+
lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
253+
http->end();
254+
return HTTP_UPDATE_FAILED;
255+
256+
}
257+
258+
uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4);
259+
260+
// check if new bin fits to SPI flash
261+
if(bin_flash_size > ESP.getFlashChipRealSize()) {
262+
DEBUG_HTTP_UPDATE("[httpUpdate] magic header, new bin not fits SPI Flash\n");
263+
lastError = HTTP_UE_BIN_FOR_WRONG_FLASH;
264+
http->end();
265+
return HTTP_UPDATE_FAILED;
266+
}
267+
235268
if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
236269
ret = HTTP_UPDATE_OK;
237270
DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");

libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@
3939
#endif
4040

4141
/// note we use HTTP client errors too so we start at 100
42-
#define HTTP_UE_TOO_LESS_SPACE (-100)
43-
#define HTTP_UE_SERVER_NOT_REPORT_SIZE (-101)
44-
#define HTTP_UE_SERVER_FILE_NOT_FOUND (-102)
45-
#define HTTP_UE_SERVER_FORBIDDEN (-103)
46-
#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104)
47-
#define HTTP_UE_SERVER_FAULTY_MD5 (-105)
42+
#define HTTP_UE_TOO_LESS_SPACE (-100)
43+
#define HTTP_UE_SERVER_NOT_REPORT_SIZE (-101)
44+
#define HTTP_UE_SERVER_FILE_NOT_FOUND (-102)
45+
#define HTTP_UE_SERVER_FORBIDDEN (-103)
46+
#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104)
47+
#define HTTP_UE_SERVER_FAULTY_MD5 (-105)
48+
#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106)
49+
#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107)
4850

4951
typedef enum {
5052
HTTP_UPDATE_FAILED,

0 commit comments

Comments
 (0)