1#include "main-header.h"
4#include "espressif/esp8266_flash.h"
6#include "proto-esp-usart.h"
8#include "platform-header.h"
9#include "wireless_state_machine.h"
13#include "app_update.h"
14#include "metrics/metrics.h"
18static int esp_bridge_mode = 0;
19uint32_t acm_byte_received;
25void usb_byte_received(
byte b) {
29 if (hijack_receive_on_usb_acm((uint8_t *)&buf, 1)) {
33 IncMetric_METRIC_IRQ_USB;
34 acm_byte_received = 500;
38void usb_restore_irq() {
39 mculib_usb_set_received_callback(MAIN_MCULIBHANDLE, usb_byte_received);
43 memset(&acm, 0,
sizeof(acm));
44 uint64_t modid = config_get_moduleid();
53 snprintf(acm.serial + 2, 11,
"%i", (
int)modid);
57 strncpy(acm.product,
"module v3", 16);
58 acm.usb_callback = NULL;
59 acm.usb_received_callback = &usb_byte_received;
60 mculib_enable_usb_acm(MAIN_MCULIBHANDLE, &acm);
135#define SENDTOUSB simulate_send_to_usb
137#define SENDTOUSB send_usb
140const static char *ready =
"[USB_APPFLASH]\r\n";
141static byte pleasestop;
143static void *baseaddr;
144static uint32_t flash_flags;
145static uint32_t total_size;
146static int curpos = 0;
148static byte packet_ready = 0;
150static uint16_t lastpack = 0;
151static uint32_t received = 0;
152static long timer_ts = 0;
153static byte ackbuf[10];
154static byte started = 0;
157#define MAX_SECS_USBFLASH 20
160uint8_t usbdebugmode = 1;
161void usbdebugf(
char *format, ...) {
168 va_start(args, format);
169 vprintf(format, args);
173static void preerase(
void *adr, uint32_t size);
176 if (pack->type == 0x06) {
177 usbdebugf(
"[usbapp] Packet #0x%x START_UPLOAD: base=0x%X\r\n", pack->number, pack->start_upload.base);
178 }
else if (pack->type == 0x03) {
179 usbdebugf(
"[usbapp] Packet #0x%x ACK\r\n", pack->number);
180 }
else if (pack->type == 0x04) {
181 usbdebugf(
"[usbapp] Packet #0x%x NACK (code=%i)\r\n", pack->number, pack->nack.code);
182 }
else if (pack->type == 0x01) {
183 usbdebugf(
"[usbapp] Packet #0x%x DATA: len=0x%X, checksum=0x%0X\r\n", pack->number, pack->data.data_length, pack->data.checksum);
184 }
else if (pack->type == 0x05) {
185 usbdebugf(
"[usbapp] Packet #0x%x DONE, checksum=0x%X, len=%i,flags=%i\r\n", pack->number, pack->done.checksum, pack->done.len, pack->done.flags);
186 }
else if (pack->type == 0x07) {
187 usbdebugf(
"[usbapp] Packet #0x%x ACTION, action=0x%X\r\n", pack->number, pack->action.action);
188 }
else if (pack->type == 0x08) {
189 usbdebugf(
"[usbapp] Packet #0x%x ACTION_WITH_DATA, action=0x%X\r\n", pack->number, pack->action.action);
191 usbdebugf(
"[usbapp] Packet type=0x%x\r\n", pack->type);
196uint32_t parse32(
byte *tmpbuf,
int offset) {
199 res = (tmpbuf[offset++] & 0xFF);
200 res = (res << 8) | (tmpbuf[offset++] & 0xFF);
201 res = (res << 8) | (tmpbuf[offset++] & 0xFF);
202 res = (res << 8) | (tmpbuf[offset++] & 0xFF);
205uint16_t parse16(
byte *tmpbuf,
int offset) {
208 res = (tmpbuf[offset++] & 0xFF);
209 res = (res << 8) | (tmpbuf[offset++] & 0xFF);
213int usb_app_parse(
byte *tmpbuf,
int size,
struct usb_app_packet *target) {
215 usbdebugf(
"[usbapp] Parsing struct from %i bytes, type %i\n", size, target->type);
217 if (target->type == 0x06) {
218 target->number = parse16(tmpbuf, 0);
219 target->start_upload.base = parse32(tmpbuf, 2);
220 target->start_upload.flags = parse32(tmpbuf, 6);
221 target->start_upload.size = parse32(tmpbuf, 10);
224 if (target->type == 0x05) {
225 target->number = parse16(tmpbuf, 0);
226 target->done.checksum = parse32(tmpbuf, 2);
227 target->done.len = parse32(tmpbuf, 6);
228 target->done.flags = tmpbuf[10];
231 if (target->type == 0x07) {
232 target->number = parse16(tmpbuf, 0);
233 target->action.action = parse32(tmpbuf, 2);
234 target->action.actiondata = parse32(tmpbuf, 6);
237 if (target->type == 0x08) {
238 target->number = parse16(tmpbuf, 0);
239 target->action.action = parse32(tmpbuf, 2);
240 target->action.datalen = parse32(tmpbuf, 6);
243 if (target->type == 0x01) {
244 target->number = parse16(tmpbuf, 0);
245 target->data.header_length = tmpbuf[2];
246 target->data.data_length = parse16(tmpbuf, 3);
247 target->data.checksum = parse32(tmpbuf, 5);
250 if (target->type == 0x04) {
251 target->number = parse16(tmpbuf, 0);
252 target->nack.code = tmpbuf[2];
253 target->nack.extra = parse32(tmpbuf, 3);
256 if (target->type == 0x03) {
257 target->number = parse16(tmpbuf, 0);
258 target->ack.extra = parse32(tmpbuf, 2);
263 usbdebugf(
"[usbapp] Parsing struct failed from %i bytes, inv type: %i\n", size, target->type);
268void usb_appupdate_byte_received(
byte b) {
270 if (curpacket.type != 0x01) {
271 usbdebugf(
"[usbapp] State: %i, Pos: %i, Headersize=%i, Received 0x%x\n", state, curpos, curpacket.headersize, b);
283 usbdebugf(
"[usbapp] Command start\n");
286 }
else if (state == 1) {
289 usbdebugf(
"[usbapp] Command type %i\n", curpacket.type);
292 curpacket.datasize = 0;
294 if (curpacket.type == 0x06) {
295 curpacket.headersize = 14;
296 }
else if (curpacket.type == 0x07) {
297 curpacket.headersize = 10;
298 }
else if (curpacket.type == 0x08) {
299 curpacket.headersize = 10;
300 }
else if (curpacket.type == 0x01) {
301 curpacket.headersize = 9;
302 }
else if (curpacket.type == 0x05) {
303 curpacket.headersize = 11;
304 }
else if (curpacket.type == 0x04) {
305 curpacket.headersize = 7;
307 printf(
"Invpackettype %i\r\n", curpacket.type);
311 }
else if (state == 2) {
314 if (curpos >= curpacket.headersize) {
316 usbdebugf(
"[usbapp] command(header) completed\n");
318 int i = usb_app_parse(usbbuf, curpos, &curpacket);
321 usbdebugf(
"[usbapp] parse failed: %i\n", i);
326 print_usb_app_packet(&curpacket);
328 if ((curpacket.type == 0x01) || (curpacket.type == 0x08)) {
334 }
else if (state == 3) {
335 if (curpacket.type == 0x01) {
338 if (curpos < curpacket.data.data_length) {
344 }
else if (curpacket.type == 0x08) {
347 if (curpos < curpacket.action.datalen) {
355 printf(
"packet too early.\r\n");
358 printf(
"Inv state %i\r\n", state);
363static void send_usb(
int len,
byte *b) {
366 i = mculib_usb_send(MAIN_MCULIBHANDLE, len, b);
368 printf(
"USB send fail %i!=%i\r\n", b, i);
372static void sendsync() {
375 SENDTOUSB(strlen(ready), (
byte *)ready);
380 printf(
"idle sync\r\n");
382static void add32(
byte *buf,
int offset, uint32_t value) {
383 buf[offset++] = (value >> 24) & 0xFF;
384 buf[offset++] = (value >> 16) & 0xFF;
385 buf[offset++] = (value >> 8) & 0xFF;
386 buf[offset++] = (value) & 0xFF;
389void usb_app_update_ack(
struct usb_app_packet *pack, uint32_t extra) {
391 usbdebugf(
"[usbapp] [usbapp] ack type %i, seq=%i,extra=%i\r\n", pack->type, pack->number, extra);
395 ackbuf[2] = (pack->number >> 8) & 0xFF;
396 ackbuf[3] = (pack->number) & 0xFF;
397 add32(ackbuf, 4, extra);
400 SENDTOUSB(10, ackbuf);
402void usb_app_update_nack(
struct usb_app_packet *pack, uint8_t code, uint32_t extra) {
404 usbdebugf(
"[usbapp] nack type %i, seq=%i: %i\r\n", pack->type, pack->number, code);
408 ackbuf[2] = (pack->number >> 8) & 0xFF;
409 ackbuf[3] = (pack->number) & 0xFF;
411 add32(ackbuf, 5, extra);
413 SENDTOUSB(10, ackbuf);
415static void reinit() {
428static int runaction_data(uint32_t action, uint32_t datalen, uint32_t *extra) {
432 char *line = (
char *)usbbuf;
436 for (i = 0; i < datalen; i++) {
438 printf(
"setting ssid to \"%s\" with password \"%s\"\r\n", line, line + i + 1);
445 }
else if (action == 2) {
446 config_set_cloud_token(line);
456static int runaction(uint32_t action, uint32_t data, uint32_t *extra) {
458 usbdebugf(
"[usbapp] action %i, data %i\r\n", action, data);
465 *extra = (uint32_t)get_app_header();
467 usbdebugf(
"[usbapp] action request for base address: 0x%p\n", *extra);
469 }
else if (action == 3) {
470 int r = set_latest_app((
void *)data);
474 struct meta_header *m = get_other_meta_header((
void *)data);
478 *extra = m->meta_seq;
479 }
else if (action == 5) {
481 }
else if (action == 4) {
484 }
else if (action == 6) {
486 }
else if (action == 7) {
487 *extra = CNW_BUILD_VERSION;
488 }
else if (action == 8) {
490 int wf = esp8266_get_firmware_version();
492 usb_app_update_ack(&curpacket, wf);
493 esp8266_wififlash_usb_bridge();
503void usb_process_packet_appupdate() {
511 if ((curpacket.type == 0x07) && (curpacket.action.action == 5)) {
512 usb_app_update_ack(&curpacket, 0);
516 if (curpacket.number == 0) {
517 printf(
"[usbapp] Ignored pack 0\r\n");
524 if (curpacket.number != (lastpack + 1)) {
526 usbdebugf(
"[usbapp] Out of sequence. got %i, wanted %i\r\n", curpacket.number, (lastpack + 1));
528 usb_app_update_nack(&curpacket, USBAPP_ERROR_PACKET_ORDER, ((curpacket.number << 16) | (lastpack + 1)));
534 lastpack = curpacket.number;
536 usbdebugf(
"[usbapp] Processing type %i\r\n", curpacket.type);
539 if (curpacket.type == 0x06) {
540 if (((uint32_t)get_app_header()) == curpacket.start_upload.base) {
542 usb_app_update_nack(&curpacket, USBAPP_ERROR_CURRENT_BASE, (uint32_t)get_app_header());
545 printf(
"USB Flash. base: %p, length: %i\r\n", (
void *)curpacket.start_upload.base, curpacket.start_upload.size);
546 baseaddr = (
void *)curpacket.start_upload.base;
547 flash_flags = curpacket.start_upload.flags;
548 flash_app_init(baseaddr, flash_flags);
550 usb_app_update_ack(&curpacket, 0);
551 if (flash_flags & (1 << FLASH_FLAGS_PRE_ERASE)) {
552 preerase((
void *)curpacket.start_upload.base, curpacket.start_upload.size);
555 }
else if (curpacket.type == 0x07) {
557 int r = runaction(curpacket.action.action, curpacket.action.actiondata, &res);
559 usb_app_update_nack(&curpacket, USBAPP_ERROR_ACTION, r);
563 usbdebugf(
"[usbapp] Action result: %i\r\n", res);
565 usb_app_update_ack(&curpacket, res);
568 }
else if (curpacket.type == 0x08) {
570 int r = runaction_data(curpacket.action.action, curpacket.action.datalen, &res);
572 usb_app_update_nack(&curpacket, USBAPP_ERROR_ACTION, r);
576 usbdebugf(
"[usbapp] Action result: %i\r\n", res);
578 usb_app_update_ack(&curpacket, res);
581 }
else if (curpacket.type == 0x05) {
582 total_size = curpacket.done.len;
584 if (received != total_size) {
586 usbdebugf(
"[usbapp] ERROR: Received %i bytes, but advertised was %i\n", received, total_size);
588 usb_app_update_nack(&curpacket, USBAPP_ERROR_TOTAL_SIZE_MISMATCH, received);
592 uint32_t c = crc32(baseaddr, received);
593 if (c != curpacket.done.checksum) {
595 usbdebugf(
"[usbapp] ERROR: checksum calculated: 0x%X, reported: 0x%X\n", c, curpacket.done.checksum);
598 usb_app_update_nack(&curpacket, USBAPP_ERROR_TOTAL_CHECKSUM, c);
602 mculib_flash_lock(MAIN_MCULIBHANDLE);
603 usb_app_update_ack(&curpacket, 0);
605 }
else if (curpacket.type == 0x01) {
607 usb_app_update_nack(&curpacket, USBAPP_ERROR_DATA_BEFORE_START, 0);
610 if (curpacket.data.data_length != 512) {
611 usb_app_update_nack(&curpacket, USBAPP_ERROR_DATA_SIZE_INVALID, 512);
616 uint32_t c = crc32(usbbuf, curpacket.data.data_length);
617 if (c != curpacket.data.checksum) {
619 usbdebugf(
"[usbapp] checksum calculated: 0x%X, reported: 0x%X\n", c, curpacket.data.checksum);
622 usb_app_update_nack(&curpacket, USBAPP_ERROR_DATA_CHECKSUM, c);
628 usbdebugf(
"[usbapp] flash failed: %i\n", i);
630 usb_app_update_nack(&curpacket, USBAPP_ERROR_FLASH_FAILURE, i);
637 usb_app_update_ack(&curpacket, 0);
638 received = received + curpacket.data.data_length;
642 usbdebugf(
"[usbapp] Failed to process packet of type %i\n", curpacket.type);
644 usb_app_update_nack(&curpacket, USBAPP_ERROR_INV_PACKET, curpacket.type);
652int usb_start_app_update() {
653 printf(
"[usbapp] Starting usb app update\r\n");
661 if (usbbuf == NULL) {
662 printf(
"no usbbuf\r\n");
665 mculib_usb_set_received_callback(MAIN_MCULIBHANDLE, usb_appupdate_byte_received);
668 SENDTOUSB(strlen(ready), (
byte *)ready);
671void usb_finish_app_update() {
675 ringbuffer_init(&console_ringbuffer);
676 printf(
"[usbapp] finished usb app update\r\n");
683 int i = usb_start_app_update();
695 if (mculib_has_time_passed(2, &timer_ts)) {
698 if ((pctr >= 3) && (syncctr >= 3)) {
702 if (pctr >= (MAX_SECS_USBFLASH / 2)) {
707 usb_process_packet_appupdate();
709 flash_app_close(0, 0);
710 usb_finish_app_update();
715static void preerase(
void *adr, uint32_t size) {
718 printf(
"Erasing %i bytes @ %p\r\n", size, adr);
719 mculib_flash_lock(MAIN_MCULIBHANDLE);
720 if ((r = mculib_flash_unlock(MAIN_MCULIBHANDLE))) {
721 printf(
"Flash unlock failed (%i)\r\n", r);
722 mculib_flash_lock(MAIN_MCULIBHANDLE);
725 if ((r = mculib_flash_erase(MAIN_MCULIBHANDLE, adr, size))) {
726 printf(
"Flash erase failed (%i)\r\n", r);
728 mculib_flash_lock(MAIN_MCULIBHANDLE);
729 printf(
"Erase complete.\r\n");
void * mpm_reserve(int bytes)
long get_my_node_id()
get the id of my node
void esp8266_reset()
reset state machine and esp8266
int flash_app_consumer(int fd, byte *b, int size)
called by stream whenever we got sufficient bytes (and only on full blocks!)
void esp8266_add_ap(const char *ssid, const char *pw)
add an ap to the list of known ap