1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #17128 from dylad/pr/usbus/dfu/fix_underflow_condition

usbus/dfu: fix underflow condition while updating firmware
This commit is contained in:
Koen Zandberg 2021-11-04 09:50:18 +01:00 committed by GitHub
commit b0d5e9a027
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -157,10 +157,9 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
usbus_handler_set_flag(handler, USBUS_HANDLER_FLAG_RESET);
}
static void _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_setup_t *pkt)
static int _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_setup_t *pkt)
{
static const usbopt_enable_t disable = USBOPT_DISABLE;
DEBUG("DFU control request:%x\n", pkt->request);
switch (pkt->request) {
case DFU_DETACH:
@ -186,18 +185,29 @@ static void _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_
else {
/* Retrieve firmware data */
size_t len = 0;
int ret = 0;
uint8_t *data = usbus_control_get_out_data(usbus, &len);
/* skip writing the riotboot signature */
if (dfu->skip_signature) {
/* Avoid underflow condition */
if (len < RIOTBOOT_FLASHWRITE_SKIPLEN) {
dfu->dfu_state = USB_DFU_STATE_DFU_ERROR;
return -1;
}
riotboot_flashwrite_init(&dfu->writer, dfu->selected_slot);
len -= RIOTBOOT_FLASHWRITE_SKIPLEN;
dfu->skip_signature = false;
riotboot_flashwrite_putbytes(&dfu->writer,
ret = riotboot_flashwrite_putbytes(&dfu->writer,
&data[RIOTBOOT_FLASHWRITE_SKIPLEN],
len, true);
}
else {
riotboot_flashwrite_putbytes(&dfu->writer, data, len, true);
ret = riotboot_flashwrite_putbytes(&dfu->writer, data, len, true);
}
if (ret < 0) {
/* Error occurs, stall the current transfer */
dfu->dfu_state = USB_DFU_STATE_DFU_ERROR;
return -1;
}
}
break;
@ -227,11 +237,17 @@ static void _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_
break;
}
case DFU_CLR_STATUS:
DEBUG("CLRSTATUS To be implemented\n");
if (dfu->dfu_state == USB_DFU_STATE_DFU_ERROR) {
dfu->dfu_state = USB_DFU_STATE_DFU_IDLE;
} else {
DEBUG("CLRSTATUS: unhandled case");
}
break;
default:
DEBUG("Unhandled DFU control request:%d\n", pkt->request);
}
return 0;
}
static int _control_handler(usbus_t *usbus, usbus_handler_t *handler,
@ -240,12 +256,16 @@ static int _control_handler(usbus_t *usbus, usbus_handler_t *handler,
{
(void)usbus;
(void)state;
usbus_dfu_device_t *dfu = (usbus_dfu_device_t *)handler;
DEBUG("DFU: Request: 0x%x\n", setup->request);
/* Process DFU class request */
if (setup->type & USB_SETUP_REQUEST_TYPE_CLASS) {
_dfu_class_control_req(usbus, dfu, setup);
if (_dfu_class_control_req(usbus, dfu, setup) < 0) {
DEBUG("DFU: control request %u failed\n", setup->request);
return -1;
}
}
else {
switch (setup->request) {