firmware: Implement debug command via USB control vendor class

Allows to collect talloc reports and other debug information
from a script while the remsim-client is still running.

Change-Id: I1f4d29335eb0d2feef376b8ecdfe57a0162914d6
This commit is contained in:
Alexander Couzens
2026-07-13 19:59:58 +02:00
parent bcc8241833
commit 4ac723a985
5 changed files with 171 additions and 0 deletions
+24
View File
@@ -19,6 +19,7 @@
#include "board.h"
#include "simtrace.h"
#include "talloc.h"
#include "utils.h"
#include "main_common.h"
#include <osmocom/core/timer.h>
@@ -39,6 +40,8 @@ typedef struct {
void (*usart0_irq) (void);
/* Interrupt handler for USART1 */
void (*usart1_irq) (void);
/* ctrl vendor request handler */
void (*ctrl_vendor_req) (const USBGenericRequest *request);
} conf_func;
static const conf_func config_func_ptrs[] = {
@@ -74,6 +77,7 @@ static const conf_func config_func_ptrs[] = {
.usart0_irq = mode_cardemu_usart0_irq,
.usart1_irq = mode_cardemu_usart1_irq,
#endif
.ctrl_vendor_req = mode_cardemu_ctrl_vendor_req,
},
#endif
#ifdef HAVE_MITM
@@ -137,6 +141,26 @@ static void check_exec_dbg_cmd(void)
board_exec_dbg_cmd(ch);
}
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
{
if (USBGenericRequest_GetType(request) != USBGenericRequest_VENDOR)
return USBDDriver_RequestHandler(USBD_GetDriver(), request);
if (config_func_ptrs[simtrace_config].ctrl_vendor_req)
config_func_ptrs[simtrace_config].ctrl_vendor_req(request);
else {
/* only ctrl in is supported */
if (USBGenericRequest_GetDirection(request) == USBGenericRequest_IN)
/* Return ZLP */
USBD_Write(0, NULL, 0, NULL, NULL);
else /* stall Ctrl out vendor requests */
USBD_Stall(0);
return;
}
}
/*------------------------------------------------------------------------------
* Main
*------------------------------------------------------------------------------*/
+3
View File
@@ -120,6 +120,9 @@ extern void Sniffer_usart1_irq(void);
extern void mode_cardemu_usart0_irq(void);
extern void mode_cardemu_usart1_irq(void);
/* Vendor request functions */
void mode_cardemu_ctrl_vendor_req(const USBGenericRequest *request);
/* Timer helper function */
void Timer_Init( void );
void TC0_Counter_Reset( void );
@@ -86,6 +86,12 @@ enum simtrace_msg_type_sniff {
SIMTRACE_MSGT_SNIFF_TPDU,
};
/* Simtrace ctrl vendor requests */
enum simtrace_vendor_req {
/* get debug infos */
SIMTRACER_VENDOR_REQ_GET_DEBUG_INFO = 0,
};
/* common message header */
struct simtrace_msg_hdr {
uint8_t msg_class; /* simtrace_msg_class */
+36
View File
@@ -689,6 +689,42 @@ void mode_cardemu_exit(void)
#endif
}
void mode_cardemu_ctrl_vendor_req(const USBGenericRequest *request)
{
if (USBGenericRequest_GetRecipient(request) != USBGenericRequest_DEVICE) {
USBD_Stall(0);
return;
}
if (USBGenericRequest_GetDirection(request) != USBGenericRequest_IN) {
USBD_Stall(0);
return;
}
uint16_t req = USBGenericRequest_GetRequest(request);
uint8_t buf[32] = {};
uint8_t len = 0;
unsigned int used, i;
switch (req) {
case SIMTRACER_VENDOR_REQ_GET_DEBUG_INFO:
/* don't use msgb here to prevent an additional allocation */
used = talloc_report_buf(&buf[0], 16);
/* add queues */
for (i = 0; i < ARRAY_SIZE(cardem_inst); i++) {
struct cardem_inst *ci = &cardem_inst[i];
buf[used++] = i + 1;
buf[used++] = usb_get_buf_ep(ci->ep_in)->queue_len;
buf[used++] = usb_get_buf_ep(ci->ep_out)->queue_len;
buf[used++] = usb_get_buf_ep(ci->ep_int)->queue_len;
}
USBD_Write(0, &buf, used, 0, 0);
break;
default:
USBD_Stall(0);
break;
}
}
/* handle a single USB command as received from the USB host */
static void dispatch_usb_command_generic(struct msgb *msg, struct cardem_inst *ci)
{