Add native USB CDC broker transport
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
#include "usb_console.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_console.h"
|
||||
#include "esp_err.h"
|
||||
#include "session_broker.h"
|
||||
#include "usb_cdc_transport.h"
|
||||
|
||||
static const char *yes_no(bool value)
|
||||
{
|
||||
return value ? "yes" : "no";
|
||||
}
|
||||
|
||||
static const char *stop_bits_name(uint8_t stop_bits)
|
||||
{
|
||||
switch (stop_bits) {
|
||||
case USB_CDC_TRANSPORT_STOP_BITS_1:
|
||||
return "1";
|
||||
case USB_CDC_TRANSPORT_STOP_BITS_1_5:
|
||||
return "1.5";
|
||||
case USB_CDC_TRANSPORT_STOP_BITS_2:
|
||||
return "2";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *parity_name(uint8_t parity)
|
||||
{
|
||||
switch (parity) {
|
||||
case USB_CDC_TRANSPORT_PARITY_NONE:
|
||||
return "none";
|
||||
case USB_CDC_TRANSPORT_PARITY_ODD:
|
||||
return "odd";
|
||||
case USB_CDC_TRANSPORT_PARITY_EVEN:
|
||||
return "even";
|
||||
case USB_CDC_TRANSPORT_PARITY_MARK:
|
||||
return "mark";
|
||||
case USB_CDC_TRANSPORT_PARITY_SPACE:
|
||||
return "space";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int show_status(void)
|
||||
{
|
||||
usb_cdc_transport_snapshot_t snapshot;
|
||||
esp_err_t err = usb_cdc_transport_get_snapshot(&snapshot);
|
||||
if (err != ESP_OK) {
|
||||
printf("Could not read USB CDC status: %s\n", esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool host_open = snapshot.attached && snapshot.dtr;
|
||||
printf("USB CDC: initialized=%s attached=%s host-open=%s DTR=%s RTS=%s\n",
|
||||
yes_no(snapshot.initialized),
|
||||
yes_no(snapshot.attached),
|
||||
yes_no(host_open),
|
||||
yes_no(snapshot.dtr),
|
||||
yes_no(snapshot.rts));
|
||||
|
||||
if (snapshot.broker_client_id == SESSION_BROKER_NO_CLIENT) {
|
||||
printf("Broker: disconnected\n");
|
||||
} else {
|
||||
printf("Broker: client=%" PRIu32 " role=%s\n",
|
||||
snapshot.broker_client_id,
|
||||
snapshot.writer ? "writer" : "observer");
|
||||
}
|
||||
|
||||
printf("Last host line coding: baud=%" PRIu32 " data=%u parity=%s stop=%s\n",
|
||||
snapshot.line_coding.baud_rate,
|
||||
(unsigned int)snapshot.line_coding.data_bits,
|
||||
parity_name(snapshot.line_coding.parity),
|
||||
stop_bits_name(snapshot.line_coding.stop_bits));
|
||||
printf("USB line coding changes RAM only; use 'serial save' to persist it.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_counters(void)
|
||||
{
|
||||
usb_cdc_transport_snapshot_t snapshot;
|
||||
esp_err_t err = usb_cdc_transport_get_snapshot(&snapshot);
|
||||
if (err != ESP_OK) {
|
||||
printf("Could not read USB CDC counters: %s\n", esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const usb_cdc_transport_counters_t *counter = &snapshot.counters;
|
||||
printf("Host RX: received=%" PRIu64 " stream-dropped=%" PRIu64
|
||||
" broker-accepted=%" PRIu64 " discarded=%" PRIu64 "\n",
|
||||
counter->host_rx_bytes,
|
||||
counter->host_rx_stream_dropped_bytes,
|
||||
counter->broker_accepted_bytes,
|
||||
counter->broker_rejected_bytes);
|
||||
printf("Host TX: broker-read=%" PRIu64 " USB-queued=%" PRIu64
|
||||
" local-dropped=%" PRIu64 "\n",
|
||||
counter->broker_to_usb_bytes,
|
||||
counter->usb_tx_queued_bytes,
|
||||
counter->usb_tx_dropped_bytes);
|
||||
printf("Sessions: connect=%" PRIu64 " disconnect=%" PRIu64
|
||||
" grants=%" PRIu64 " denials=%" PRIu64
|
||||
" revocations=%" PRIu64 " writer-events=%" PRIu64 "\n",
|
||||
counter->connections,
|
||||
counter->disconnections,
|
||||
counter->writer_grants,
|
||||
counter->writer_denials,
|
||||
counter->writer_revocations,
|
||||
counter->writer_events);
|
||||
printf("Line coding: applied=%" PRIu64 " rejected=%" PRIu64
|
||||
" failed=%" PRIu64 " service-start-failures=%" PRIu64 "\n",
|
||||
counter->line_coding_applied,
|
||||
counter->line_coding_rejected,
|
||||
counter->line_coding_failed,
|
||||
counter->service_start_failures);
|
||||
printf("Control/callback drops: control=%" PRIu64 " callback=%" PRIu64 "\n",
|
||||
counter->control_drops,
|
||||
counter->callback_drops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int queue_writer_request(bool request)
|
||||
{
|
||||
esp_err_t err = request ? usb_cdc_transport_request_writer()
|
||||
: usb_cdc_transport_release_writer();
|
||||
if (err != ESP_OK) {
|
||||
printf("Could not queue USB writer %s: %s\n",
|
||||
request ? "request" : "release",
|
||||
esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("USB writer %s queued; use 'usb status' to observe the result.\n",
|
||||
request ? "request" : "release");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
printf("Usage: usb status|counters|clear-counters|request-writer|release-writer\n");
|
||||
}
|
||||
|
||||
static int command_usb(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1 || (argc == 2 && strcmp(argv[1], "status") == 0)) {
|
||||
return show_status();
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "counters") == 0) {
|
||||
return show_counters();
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "clear-counters") == 0) {
|
||||
esp_err_t err = usb_cdc_transport_clear_counters();
|
||||
if (err != ESP_OK) {
|
||||
printf("Could not clear USB CDC counters: %s\n", esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
printf("USB CDC counters cleared.\n");
|
||||
return 0;
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "request-writer") == 0) {
|
||||
return queue_writer_request(true);
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "release-writer") == 0) {
|
||||
return queue_writer_request(false);
|
||||
}
|
||||
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t usb_console_register_commands(void)
|
||||
{
|
||||
const esp_console_cmd_t command = {
|
||||
.command = "usb",
|
||||
.help = "Inspect native USB CDC and manage its broker writer request",
|
||||
.hint = NULL,
|
||||
.func = &command_usb,
|
||||
.argtable = NULL,
|
||||
};
|
||||
return esp_console_cmd_register(&command);
|
||||
}
|
||||
Reference in New Issue
Block a user