Skip to content

Commit 1cc47b1

Browse files
committed
handle too many responses gracefully
1 parent 8acde80 commit 1cc47b1

3 files changed

Lines changed: 35 additions & 22 deletions

File tree

devices/airlift/common-hal/wifi/Radio.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
// Print out SPI traffic with AirLift.
32-
#define DEBUG_AIRLIFT 0
32+
#define DEBUG_AIRLIFT 1
3333

3434
#if DEBUG_AIRLIFT
3535
static const char *command_name(uint8_t command) {
@@ -346,7 +346,7 @@ bool wifi_radio_send_command(wifi_radio_obj_t *self, uint8_t cmd,
346346

347347
#if DEBUG_AIRLIFT
348348
PLAT_PRINTF(">cmd %s (%02x)\n", command_name(cmd), cmd);
349-
#endif // DEBUG_AIRLIFT
349+
#endif
350350

351351
for (size_t i = 0; i < num_params; i++) {
352352
switch (param_lengths_size) {
@@ -399,36 +399,50 @@ size_t wifi_radio_wait_response_cmd(wifi_radio_obj_t *self, uint8_t cmd,
399399
wifi_radio_read_and_check_byte(self, cmd | REPLY_FLAG);
400400
uint8_t num_responses = wifi_radio_read_byte(self);
401401

402-
if (num_responses > max_responses) {
403-
num_responses = max_responses;
404-
}
405-
402+
#if DEBUG_AIRLIFT
406403
if (num_responses == 0) {
407404
PLAT_PRINTF("<zero responses\n\n");
408405
}
406+
#endif
407+
409408
for (size_t i = 0; i < num_responses; i++) {
410409
size_t response_length = wifi_radio_read_byte(self);
411410
// Two-byte response lengths are big-endian.
412411
if (response_lengths_size == LENGTHS_16) {
413412
response_length = (response_length << 8) | wifi_radio_read_byte(self);
414413
}
415-
// Don't overflow the supplied buffer.
416-
size_t read_length = MIN(response_length, response_lengths[i]);
417-
wifi_radio_read(self, responses[i], read_length);
418-
// Update the passed-in length with what was actually read, so the caller knows how many bytes
419-
// were read for each response.
420-
response_lengths[i] = read_length;
421-
422-
// Read and discard bytes that didn't fit in buffer.
423-
if (read_length > response_lengths[i]) {
414+
415+
size_t discard_count = 0;
416+
if (i >= max_responses) {
417+
// Discard all responses past max_responses.
418+
discard_count = response_length;
419+
424420
#if DEBUG_AIRLIFT
425-
PLAT_PRINTF("<!! response %d too long. expected %d, got %d\n", i, response_lengths[i], response_length);
421+
PLAT_PRINTF("<!! discarding response %d past max_responses: %d\n", i, max_responses);
426422
#endif
427-
while (read_length-- > 0) {
428-
wifi_radio_read_byte(self);
423+
} else {
424+
// Don't overflow the supplied buffer.
425+
size_t length_to_read = MIN(response_length, response_lengths[i]);
426+
427+
wifi_radio_read(self, responses[i], length_to_read);
428+
// Update the passed-in length with what was actually read, so the caller knows how many bytes
429+
// were read for each response.
430+
response_lengths[i] = length_to_read;
431+
432+
if (response_length > response_lengths[i]) {
433+
discard_count = response_length - response_lengths[i];
434+
435+
#if DEBUG_AIRLIFT
436+
PLAT_PRINTF("<!! response %d too long. max %d, got %d\n", i, response_lengths[i], response_length);
437+
#endif
429438
}
430439
}
431440

441+
// Discard any extra bytes, or discard whole response if it's past max responses.
442+
while (discard_count-- > 0) {
443+
wifi_radio_read_byte(self);
444+
}
445+
432446
#if DEBUG_AIRLIFT
433447
PLAT_PRINTF("<response #%d (length %d) --x", i, response_length);
434448
for (size_t j = 0; j < response_length; j++) {
@@ -450,7 +464,7 @@ size_t wifi_radio_wait_response_cmd(wifi_radio_obj_t *self, uint8_t cmd,
450464

451465
spi_end_transaction(self);
452466

453-
return num_responses;
467+
return MIN(num_responses, max_responses);
454468
}
455469

456470
size_t wifi_radio_send_command_get_response(wifi_radio_obj_t *self, uint8_t cmd,

devices/airlift/common-hal/wifi/Radio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ typedef enum {
162162

163163
#define AIRLIFT_DEFAULT_TIMEOUT_MS (1000)
164164

165-
// Maximum is 10 in NINA-FW.
166-
#define AIRLIFT_MAX_NETWORKS (10)
165+
// More networks may be found, but we return a max of 20.
166+
#define AIRLIFT_MAX_NETWORKS (20)
167167
// SSID does not include a terminating null byte, because the length is passed.
168168
#define MAX_SSID_LENGTH (32)
169169
// NINA-FW allows this length internally. Does not include trailing null.

devices/airlift/common-hal/wifi/ScannedNetworks.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ mp_obj_t wifi_scannednetworks_do_scan(wifi_radio_obj_t *self) {
2929
size_t num_networks = wifi_radio_send_command_get_response(self, SCAN_NETWORKS,
3030
NULL, NULL, LENGTHS_8, 0,
3131
network_responses, network_response_lengths, LENGTHS_8, AIRLIFT_MAX_NETWORKS,
32-
// AIRLIFT_DEFAULT_TIMEOUT_MS);
3332
10000);
3433

3534
// Now fetch each network's details and store them in Network objects.

0 commit comments

Comments
 (0)