Split listdir entries across two packets
when the MTU of the BLE connection is smaller than the 28 bytes of the header. (The smallest possible MTU is 20.) Fixes #5511
This commit is contained in:
parent
a8b69f2852
commit
bf0bef9684
@ -356,9 +356,12 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, c
|
||||
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
|
||||
return -1;
|
||||
}
|
||||
uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
|
||||
mp_int_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
|
||||
if (outgoing_packet_length < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t total_len = len + header_len;
|
||||
mp_int_t total_len = len + header_len;
|
||||
if (total_len > outgoing_packet_length) {
|
||||
// Supplied data will not fit in a single BLE packet.
|
||||
mp_raise_ValueError_varg(translate("Total data to write is larger than %q"), MP_QSTR_outgoing_packet_length);
|
||||
@ -369,7 +372,7 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, c
|
||||
}
|
||||
outgoing_packet_length = MIN(outgoing_packet_length, self->max_packet_size);
|
||||
|
||||
if (len + self->pending_size > outgoing_packet_length) {
|
||||
if (len + self->pending_size > (size_t)outgoing_packet_length) {
|
||||
// No room to append len bytes to packet. Wait until we get a free buffer,
|
||||
// and keep checking that we haven't been disconnected.
|
||||
while (self->pending_size != 0 &&
|
||||
|
@ -525,18 +525,33 @@ STATIC uint8_t _process_mkdir(const uint8_t *raw_buf, size_t command_len) {
|
||||
return ANY_COMMAND;
|
||||
}
|
||||
|
||||
STATIC void send_listdir_entry_header(const struct listdir_entry *entry, mp_int_t max_packet_size) {
|
||||
mp_int_t response_size = sizeof(struct listdir_entry);
|
||||
if (max_packet_size >= response_size) {
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, response_size, NULL, 0);
|
||||
return;
|
||||
}
|
||||
// Split into 16 + 12 size packets to fit into 20 byte minimum packet size.
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, 16, NULL, 0);
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, ((const uint8_t *)entry) + 16, response_size - 16, NULL, 0);
|
||||
}
|
||||
|
||||
STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) {
|
||||
const struct listdir_command *command = (struct listdir_command *)raw_buf;
|
||||
struct listdir_entry *entry = (struct listdir_entry *)raw_buf;
|
||||
size_t header_size = sizeof(struct listdir_command);
|
||||
size_t response_size = sizeof(struct listdir_entry);
|
||||
mp_int_t max_packet_size = common_hal_bleio_packet_buffer_get_outgoing_packet_length(&_transfer_packet_buffer);
|
||||
if (max_packet_size < 0) {
|
||||
// -1 means we're disconnected
|
||||
return ANY_COMMAND;
|
||||
}
|
||||
// We reuse the command buffer so that we can produce long packets without
|
||||
// making the stack large.
|
||||
if (command->path_length > (COMMAND_SIZE - header_size - 1)) { // -1 for the null we'll write
|
||||
// TODO: throw away any more packets of path.
|
||||
entry->command = LISTDIR_ENTRY;
|
||||
entry->status = STATUS_ERROR;
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, response_size, NULL, 0);
|
||||
send_listdir_entry_header(entry, max_packet_size);
|
||||
return ANY_COMMAND;
|
||||
}
|
||||
// We need to receive another packet to have the full path.
|
||||
@ -560,7 +575,7 @@ STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) {
|
||||
|
||||
if (res != FR_OK) {
|
||||
entry->status = STATUS_ERROR_NO_FILE;
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, response_size, NULL, 0);
|
||||
send_listdir_entry_header(entry, max_packet_size);
|
||||
return ANY_COMMAND;
|
||||
}
|
||||
FILINFO file_info;
|
||||
@ -594,7 +609,7 @@ STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) {
|
||||
|
||||
size_t name_length = strlen(file_info.fname);
|
||||
entry->path_length = name_length;
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, response_size, NULL, 0);
|
||||
send_listdir_entry_header(entry, max_packet_size);
|
||||
size_t fn_offset = 0;
|
||||
while (fn_offset < name_length) {
|
||||
size_t fn_size = MIN(name_length - fn_offset, 4);
|
||||
@ -607,7 +622,7 @@ STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) {
|
||||
entry->entry_number = entry->entry_count;
|
||||
entry->flags = 0;
|
||||
entry->file_size = 0;
|
||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)entry, response_size, NULL, 0);
|
||||
send_listdir_entry_header(entry, max_packet_size);
|
||||
return ANY_COMMAND;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user