Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ customers cannot upgrade their bootloader, its changes are recorded separately.
- simulator: simulate a Nova device
- Add API call to fetch multiple xpubs at once
- Add the option for the simulator to write its memory to file.
- simulator: spin tasks at max speed instead of at the client poll interval

### 9.23.1
- EVM: add HyperEVM (HYPE) and SONIC (S) to known networks
Expand Down
50 changes: 35 additions & 15 deletions test/simulator/simulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
#include <unistd.h>
#include <version.h>

#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/select.h>
#include <stdbool.h>
#include <sys/socket.h>

Expand All @@ -45,11 +47,6 @@ int commfd;
static volatile sig_atomic_t sigint_called = false;
static int sockfd;

static int get_usb_message_socket(uint8_t* input)
{
return read(commfd, input, USB_HID_REPORT_OUT_SIZE);
}

static void send_usb_message_socket(void)
{
const uint8_t* data = queue_pull(queue_hww_queue());
Expand All @@ -63,14 +60,6 @@ static void send_usb_message_socket(void)
}
}

static void simulate_firmware_execution(const uint8_t* input)
{
usb_packet_process((const USB_FRAME*)input);
rust_workflow_spin();
rust_async_usb_spin();
usb_processing_process(usb_processing_hww());
}

static void _int_handler(int signum)
{
(void)signum;
Expand Down Expand Up @@ -170,13 +159,44 @@ int main(int argc, char* argv[])
}
printf("Socket connection setup success\n");

// Set commfd to non-blocking
int flags = fcntl(commfd, F_GETFL, 0);
if (flags == -1 || fcntl(commfd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl");
close(commfd);
continue;
}

// BitBox02 firmware loop
uint8_t input[BUFFER_SIZE];
int temp_len;
while (1) {
// Simulator polls for USB messages from client and then processes them
if (!get_usb_message_socket(input)) break;
simulate_firmware_execution(input);

fd_set readfds;
FD_ZERO(&readfds);
FD_SET(commfd, &readfds);
// 0.05ms timeout, so this loop does not lead to 100% CPU usage, but is also not
// unbearably slow. It is a trade-off as we don't have proper waking of our Rust tasks,
// just busy polling.
struct timeval timeout = {0, 500};

if (select(commfd + 1, &readfds, NULL, NULL, &timeout) < 0) {
break;
}

if (FD_ISSET(commfd, &readfds)) {
int bytes_read = read(commfd, input, USB_HID_REPORT_OUT_SIZE);
if (bytes_read == 0) break;
else if (bytes_read > 0) {
usb_packet_process((const USB_FRAME*)input);
}
}


usb_processing_process(usb_processing_hww());
rust_workflow_spin();
rust_async_usb_spin();

// If the USB message to be sent from firmware is bigger than one packet,
// then the simulator sends the message in multiple packets. Packets use
Expand Down