Convert to new generalized SIMTRACE2 USB protocol

The current protocol was card-emulation specific.  The new protocol is
generic/flexible enough to accommodate both tracing and card emulation,
as well as modem control and other future extensions.
diff --git a/firmware/libcommon/include/cardemu_prot.h b/firmware/libcommon/include/cardemu_prot.h
deleted file mode 100644
index 8b781bc..0000000
--- a/firmware/libcommon/include/cardemu_prot.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#pragma once
-
-/* Smart Card Emulation USB protocol */
-
-/* (C) 2015 by Harald Welte <hwelte@hmw-consulting.de>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <stdint.h>
-
-/* DT = Device Terminated. DO = Device Originated */
-enum cardemu_usb_msg_type {
-	/* Bulk out pipe */
-	CEMU_USB_MSGT_DT_TX_DATA,	/* TPDU Date */
-	CEMU_USB_MSGT_DT_SET_ATR,	/* Set the ATR stored in simulator */
-	CEMU_USB_MSGT_DT_GET_STATS,	/* request DO_STATS */
-	CEMU_USB_MSGT_DT_GET_STATUS,	/* request DO_STATUS */
-	CEMU_USB_MSGT_DT_CARDINSERT,	/* insert/remove card */
-
-	/* Bulk in pipe */
-	CEMU_USB_MSGT_DO_RX_DATA,	/* TPDU data */
-	CEMU_USB_MSGT_DO_STATUS,	/* Status information */
-	CEMU_USB_MSGT_DO_STATS,		/* Statistics */
-	CEMU_USB_MSGT_DO_PTS,		/* Information about PTS */
-	CEMU_USB_MSGT_DO_ERROR,		/* Error message */
-};
-
-/* generic header, shared by all messages */
-struct cardemu_usb_msg_hdr {
-	uint8_t msg_type;	/* enum cardemu_usb_msg_type */
-	uint8_t seq_nr;		/* sequence number */
-	uint16_t msg_len;	/* length of message including hdr */
-	uint8_t data[0];
-} __attribute__ ((packed));
-
-/* indicates a TPDU header is present in this message */
-#define CEMU_DATA_F_TPDU_HDR	0x00000001
-/* indicates last part of transmission in this direction */
-#define CEMU_DATA_F_FINAL	0x00000002
-/* incdicates a PB is present and we should continue with TX */
-#define CEMU_DATA_F_PB_AND_TX	0x00000004
-/* incdicates a PB is present and we should continue with RX */
-#define CEMU_DATA_F_PB_AND_RX	0x00000008
-
-/* CEMU_USB_MSGT_DT_CARDINSERT */
-struct cardemu_usb_msg_cardinsert {
-	struct cardemu_usb_msg_hdr hdr;
-	uint8_t card_insert;
-} __attribute__ ((packed));
-
-/* CEMU_USB_MSGT_DT_SET_ATR */
-struct cardemu_usb_msg_set_atr {
-	struct cardemu_usb_msg_hdr hdr;
-	uint8_t atr_len;
-	/* variable-length ATR data */
-	uint8_t atr[0];
-} __attribute__ ((packed));
-
-/* CEMU_USB_MSGT_DT_TX_DATA */
-struct cardemu_usb_msg_tx_data {
-	struct cardemu_usb_msg_hdr hdr;
-	uint32_t flags;
-	uint16_t data_len;
-	/* variable-length TPDU data */
-	uint8_t data[0];
-} __attribute__ ((packed));
-
-/* CEMU_USB_MSGT_DO_RX_DATA */
-struct cardemu_usb_msg_rx_data {
-	struct cardemu_usb_msg_hdr hdr;
-	uint32_t flags;
-	uint16_t data_len;
-	/* variable-length TPDU data */
-	uint8_t data[0];
-} __attribute__ ((packed));
-
-#define CEMU_STATUS_F_VCC_PRESENT	0x00000001
-#define CEMU_STATUS_F_CLK_ACTIVE	0x00000002
-#define CEMU_STATUS_F_RCEMU_ACTIVE	0x00000004
-#define CEMU_STATUS_F_CARD_INSERT	0x00000008
-#define CEMU_STATUS_F_RESET_ACTIVE	0x00000010
-
-/* CEMU_USB_MSGT_DO_STATUS */
-struct cardemu_usb_msg_status {
-	struct cardemu_usb_msg_hdr hdr;
-	uint32_t flags;
-	/* phone-applied target voltage in mV */
-	uint16_t voltage_mv;
-	/* Fi/Di related information */
-	uint8_t fi;
-	uint8_t di;
-	uint8_t wi;
-	uint32_t waiting_time;
-} __attribute__ ((packed));
-
-/* CEMU_USB_MSGT_DO_PTS */
-struct cardemu_usb_msg_pts_info {
-	struct cardemu_usb_msg_hdr hdr;
-	uint8_t pts_len;
-	/* PTS request as sent from reader */
-	uint8_t req[6];
-	/* PTS response as sent by card */
-	uint8_t resp[6];
-} __attribute__ ((packed));
-
-/* CEMU_USB_MSGT_DO_ERROR */
-struct cardemu_usb_msg_error {
-	struct cardemu_usb_msg_hdr hdr;
-	uint8_t severity;
-	uint8_t subsystem;
-	uint16_t code;
-	uint8_t msg_len;
-	/* human-readable error message */
-	uint8_t msg[0];
-} __attribute__ ((packed));
-
-static inline void cardemu_hdr_set(struct cardemu_usb_msg_hdr *hdr, uint16_t msgt)
-{
-	memset(hdr, 0, sizeof(*hdr));
-	hdr->msg_type = msgt;
-}
diff --git a/firmware/libcommon/include/simtrace_prot.h b/firmware/libcommon/include/simtrace_prot.h
new file mode 100644
index 0000000..91b569f
--- /dev/null
+++ b/firmware/libcommon/include/simtrace_prot.h
@@ -0,0 +1,278 @@
+#pragma once
+
+#include <stdint.h>
+
+/* SIMtrace2 USB protocol */
+
+/* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/***********************************************************************
+ * COMMON HEADER
+ ***********************************************************************/
+
+enum simtrace_msg_class {
+	SIMTRACE_MSGC_GENERIC = 0,
+	/* Card Emulation / Forwarding */
+	SIMTRACE_MSGC_CARDEM,
+	/* Modem Control (if modem is attached next to device */
+	SIMTRACE_MSGC_MODEM,
+	/* SIM protocol tracing */
+	SIMTRACE_MSGC_TRACE,
+
+	/* first vendor-specific request */
+	_SIMTRACE_MGSC_VENDOR_FIRST = 127,
+};
+
+enum simtrace_msg_type_generic {
+	/* Generic Error Message */
+	SIMTRACE_CMD_DO_ERROR	= 0,
+	/* Request/Response for simtrace_board_info */
+	SIMTRACE_CMD_BD_BOARD_INFO,
+};
+
+/* SIMTRACE_MSGC_CARDEM */
+enum simtrace_msg_type_cardem {
+	/* TPDU Data to be transmitted to phone */
+	SIMTRACE_MSGT_DT_CEMU_TX_DATA = 1,
+	/* Set the ATR to be returned at phone-SIM reset */
+	SIMTRACE_MSGT_DT_CEMU_SET_ATR,
+	/* Get Statistics Request / Response */
+	SIMTRACE_MSGT_BD_CEMU_STATS,
+	/* Get Status Request / Response */
+	SIMTRACE_MSGT_BD_CEMU_STATUS,
+	/* Request / Confirm emulated card insert */
+	SIMTRACE_MSGT_DT_CEMU_CARDINSERT,
+	/* TPDU Data received from phomne */
+	SIMTRACE_MSGT_DO_CEMU_RX_DATA,
+	/* Indicate PTS request from phone */
+	SIMTRACE_MSGT_DO_CEMU_PTS,
+};
+
+/* SIMTRACE_MSGC_MODEM */
+enum simtrace_msg_type_modem {
+	/* Modem Control: Reset an attached modem */
+	SIMTRACE_MSGT_DT_MODEM_RESET = 1,
+	/* Modem Control: Select local / remote SIM */
+	SIMTRACE_MSGT_DT_MODEM_SIM_SELECT,
+	/* Modem Control: Status (WWAN LED, SIM Presence) */
+	SIMTRACE_MSGT_BD_MODEM_STATUS,
+};
+
+/* SIMTRACE_MSGC_TRACE */
+enum simtrace_msg_type_trace {
+	/* FIXME */
+	_dummy,
+};
+
+/* common message header */
+struct simtrace_msg_hdr {
+	uint8_t msg_class;	/* simtrace_msg_class */
+	uint8_t msg_type;	/* simtrace_msg_type_xxx */
+	uint8_t seq_nr;
+	uint8_t slot_nr;	/* SIM slot number */
+	uint16_t _reserved;
+	uint16_t msg_len;	/* length including header */
+	uint8_t payload[0];
+} __attribute__ ((packed));
+
+/***********************************************************************
+ * CARD EMULATOR / FORWARDER
+ ***********************************************************************/
+
+/* generic capabilities */
+enum simtrace_capability_generic {
+	/* compatible with 5V SIM card interface */
+	SIMTRACE_CAP_VOLT_5V,
+	/* compatible with 3.3V SIM card interface */
+	SIMTRACE_CAP_VOLT_3V3,
+	/* compatible with 1.8V SIM card interface */
+	SIMTRACE_CAP_VOLT_1V8,
+	/* Has LED1 */
+	SIMTRACE_CAP_LED_1,
+	/* Has LED2 */
+	SIMTRACE_CAP_LED_2,
+	/* Has Single-Pole Dual-Throw (local/remote SIM */
+	SIMTRACE_CAP_SPDT,
+	/* Has Bus-Switch (trace / MITM) */
+	SIMTRACE_CAP_BUS_SWITCH,
+	/* Can read VSIM via ADC */
+	SIMTRACE_CAP_VSIM_ADC,
+	/* Can read temperature via ADC */
+	SIMTRACE_CAP_TEMP_ADC,
+	/* Supports DFU for firmware update */
+	SIMTRACE_CAP_DFU,
+	/* Supports Ctrl EP command for erasing flash / return to SAM-BA */
+	SIMTRACE_CAP_ERASE_FLASH,
+	/* Can read the status of card insert contact */
+	SIMTRACE_CAP_READ_CARD_DET,
+	/* Can control the status of a simulated card insert */
+	SIMTRACE_CAP_ASSERT_CARD_DET,
+	/* Can toggle the hardware reset of an attached modem */
+	SIMTRACE_CAP_ASSERT_MODEM_RST,
+};
+
+/* vendor-specific capabilities of sysmoocm devices */
+enum simtrace_capability_vendor {
+	/* Can erase a peer SAM3 controller */
+	SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER,
+	/* Can read/write an attached EEPROM */
+	SIMTRACE_CAP_SYSMO_QMOD_RW_EEPROM,
+	/* can reset an attached USB hub */
+	SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB,
+};
+
+
+/* SIMTRACE_CMD_BD_BOARD_INFO */
+struct simtrace_board_info {
+	struct {
+		char manufacturer[32];
+		char model[32];
+		char version[32];
+	} hardware;
+	struct {
+		/* who provided this software? */
+		char provider[32];
+		/* name of software image */
+		char name[32];
+		/* (git) version at build time */
+		char version[32];
+		/* built on which machine? */
+		char buildhost[32];
+		/* CRC-32 over software image */
+		uint32_t crc;
+	} software;
+	struct {
+		/* Maximum baud rate supported */
+		uint32_t max_baud_rate;
+	} speed;
+	/* number of bytes of generic capability bit-mask */
+	uint8_t cap_generic_bytes;
+	/* number of bytes of vendor capability bit-mask */
+	uint8_t cap_vendor_bytes;
+	uint8_t data[0];
+	/* cap_generic + cap_vendor */
+} __attribute__ ((packed));
+
+/***********************************************************************
+ * CARD EMULATOR / FORWARDER
+ ***********************************************************************/
+
+/* indicates a TPDU header is present in this message */
+#define CEMU_DATA_F_TPDU_HDR	0x00000001
+/* indicates last part of transmission in this direction */
+#define CEMU_DATA_F_FINAL	0x00000002
+/* incdicates a PB is present and we should continue with TX */
+#define CEMU_DATA_F_PB_AND_TX	0x00000004
+/* incdicates a PB is present and we should continue with RX */
+#define CEMU_DATA_F_PB_AND_RX	0x00000008
+
+/* CEMU_USB_MSGT_DT_CARDINSERT */
+struct cardemu_usb_msg_cardinsert {
+	uint8_t card_insert;
+} __attribute__ ((packed));
+
+/* CEMU_USB_MSGT_DT_SET_ATR */
+struct cardemu_usb_msg_set_atr {
+	uint8_t atr_len;
+	/* variable-length ATR data */
+	uint8_t atr[0];
+} __attribute__ ((packed));
+
+/* CEMU_USB_MSGT_DT_TX_DATA */
+struct cardemu_usb_msg_tx_data {
+	uint32_t flags;
+	uint16_t data_len;
+	/* variable-length TPDU data */
+	uint8_t data[0];
+} __attribute__ ((packed));
+
+/* CEMU_USB_MSGT_DO_RX_DATA */
+struct cardemu_usb_msg_rx_data {
+	uint32_t flags;
+	uint16_t data_len;
+	/* variable-length TPDU data */
+	uint8_t data[0];
+} __attribute__ ((packed));
+
+#define CEMU_STATUS_F_VCC_PRESENT	0x00000001
+#define CEMU_STATUS_F_CLK_ACTIVE	0x00000002
+#define CEMU_STATUS_F_RCEMU_ACTIVE	0x00000004
+#define CEMU_STATUS_F_CARD_INSERT	0x00000008
+#define CEMU_STATUS_F_RESET_ACTIVE	0x00000010
+
+/* CEMU_USB_MSGT_DO_STATUS */
+struct cardemu_usb_msg_status {
+	uint32_t flags;
+	/* phone-applied target voltage in mV */
+	uint16_t voltage_mv;
+	/* Fi/Di related information */
+	uint8_t fi;
+	uint8_t di;
+	uint8_t wi;
+	uint32_t waiting_time;
+} __attribute__ ((packed));
+
+/* CEMU_USB_MSGT_DO_PTS */
+struct cardemu_usb_msg_pts_info {
+	uint8_t pts_len;
+	/* PTS request as sent from reader */
+	uint8_t req[6];
+	/* PTS response as sent by card */
+	uint8_t resp[6];
+} __attribute__ ((packed));
+
+/* CEMU_USB_MSGT_DO_ERROR */
+struct cardemu_usb_msg_error {
+	uint8_t severity;
+	uint8_t subsystem;
+	uint16_t code;
+	uint8_t msg_len;
+	/* human-readable error message */
+	uint8_t msg[0];
+} __attribute__ ((packed));
+
+/***********************************************************************
+ * MODEM CONTROL
+ ***********************************************************************/
+
+/* SIMTRACE_MSGT_DT_MODEM_RESET */
+struct st_modem_reset {
+	/* 0: de-assert reset, 1: assert reset, 2: poulse reset */
+	uint8_t asserted;
+	/* if above is '2', duration of pulse in ms */
+	uint16_t pulse_duration_msec;
+} __attribute__((packed));
+
+/* SIMTRACE_MSGT_DT_MODEM_SIM_SELECT */
+struct st_modem_sim_select {
+	/* remote (1), local (0) */
+	uint8_t remote_sim;
+} __attribute__((packed));
+
+/* SIMTRACE_MSGT_BD_MODEM_STATUS */
+#define ST_MDM_STS_BIT_WWAN_LED		(1 << 0)
+#define ST_MDM_STS_BIT_CARD_INSERTED	(1 << 1)
+struct st_modem_status {
+	/* bit-field of supported status bits */
+	uint8_t supported_mask;
+	/* bit-field of current status bits */
+	uint8_t status_mask;
+	/* bit-field of changed status bits */
+	uint8_t changed_mask;
+} __attribute__((packed));
diff --git a/firmware/libcommon/source/card_emu.c b/firmware/libcommon/source/card_emu.c
index 6edf05e..ed3aa99 100644
--- a/firmware/libcommon/source/card_emu.c
+++ b/firmware/libcommon/source/card_emu.c
@@ -31,7 +31,7 @@
 #include "iso7816_fidi.h"
 #include "tc_etu.h"
 #include "card_emu.h"
-#include "cardemu_prot.h"
+#include "simtrace_prot.h"
 #include "usb_buf.h"
 #include "osmocom/core/linuxlist.h"
 #include "osmocom/core/msgb.h"
@@ -162,6 +162,37 @@
 static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
 static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
 
+/* update simtrace header msg_len and submit USB buffer */
+void usb_buf_upd_len_and_submit(struct msgb *msg)
+{
+	struct simtrace_msg_hdr *sh = msg->l1h;
+
+	sh->msg_len = msgb_length(msg);
+
+	usb_buf_submit(msg);
+}
+
+/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
+struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
+{
+	struct msgb *msg;
+	struct simtrace_msg_hdr *sh;
+
+	msg = usb_buf_alloc(ep);
+	if (!msg)
+		return NULL;
+
+	msg->l1h = msgb_put(msg, sizeof(*sh));
+	sh = (struct simtrace_msg_hdr *) msg->l1h;
+	memset(sh, 0, sizeof(*sh));
+	sh->msg_class = msg_class;
+	sh->msg_type = msg_type;
+	msg->l2h = msg->l1h + sizeof(*sh);
+
+	return msg;
+}
+
+/* Update cardemu_usb_msg_rx_data length + submit bufffer */
 static void flush_rx_buffer(struct card_handle *ch)
 {
 	struct msgb *msg;
@@ -175,12 +206,10 @@
 	ch->uart_rx_msg = NULL;
 
 	/* store length of data payload fild in header */
-	rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
-	msg->l2h = &rd->data;
-	rd->data_len = msgb_l2len(msg);
-	rd->hdr.msg_len = msgb_length(msg);
+	rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
+	rd->data_len = msgb_l2len(msg) - sizeof(*rd);
 
-	usb_buf_submit(msg);
+	usb_buf_upd_len_and_submit(msg);
 }
 
 /* convert a non-contiguous PTS request/responsei into a contiguous
@@ -223,19 +252,15 @@
 	struct msgb *msg;
 	struct cardemu_usb_msg_pts_info *ptsi;
 
-	msg = usb_buf_alloc(ch->in_ep);
+	msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
 	if (!msg)
 		return;
 
-	msg->l1h = msgb_put(msg, sizeof(*ptsi));
-	msg->l2h = msg->l1h + sizeof(ptsi->hdr);
-	ptsi = (struct cardemu_usb_msg_pts_info *) msg->l1h;
-	ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS;
-	ptsi->hdr.msg_len = sizeof(*ptsi);
+	ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
 	ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
 	serialize_pts(ptsi->resp, ch->pts.resp);
 
-	usb_buf_submit(msg);
+	usb_buf_upd_len_and_submit(msg);
 }
 
 static void emu_update_fidi(struct card_handle *ch)
@@ -504,24 +529,22 @@
 
 	/* ensure we have a buffer */
 	if (!ch->uart_rx_msg) {
-		msg = ch->uart_rx_msg = usb_buf_alloc(ch->in_ep);
+		msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
+							 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
 		if (!ch->uart_rx_msg) {
 			TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
 				    ch->num);
 			return;
 		}
-		msg->l1h = msgb_put(msg, sizeof(*rd));
-		rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
-		msg->l2h = msg->l1h + sizeof(rd->hdr);
-		cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
+		msgb_put(msg, sizeof(*rd));
 	} else
 		msg = ch->uart_rx_msg;
 
-	rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
+	rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
 	msgb_put_u8(msg, byte);
 
 	/* check if the buffer is full. If so, send it */
-	if (msgb_length(msg) >= sizeof(*rd) + num_data_bytes) {
+	if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
 		rd->flags |= CEMU_DATA_F_FINAL;
 		flush_rx_buffer(ch);
 		/* We need to transmit the SW now, */
@@ -604,18 +627,16 @@
 	}
 	TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
 	/* ensure we have a new buffer */
-	ch->uart_rx_msg = usb_buf_alloc(ch->in_ep);
+	ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
+					   SIMTRACE_MSGT_DO_CEMU_RX_DATA);
 	if (!ch->uart_rx_msg) {
 		TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
 		return;
 	}
 	msg = ch->uart_rx_msg;
-	msg->l1h = msgb_put(msg, sizeof(*rd));
-	rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
+	rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
 
 	/* initialize header */
-	msg->l2h = msg->l1h + sizeof(rd->hdr);
-	cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
 	rd->flags = CEMU_DATA_F_TPDU_HDR;
 
 	/* copy TPDU header to data field */
@@ -683,12 +704,14 @@
 
 		/* dequeue first at head */
 		ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
-		ch->uart_tx_msg->l1h = ch->uart_tx_msg->data;
+		ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
+		ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
 		msg = ch->uart_tx_msg;
-		msgb_pull(msg, sizeof(*td));
+		/* remove the header */
+		msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
 	}
 	msg = ch->uart_tx_msg;
-	td = (struct cardemu_usb_msg_tx_data *) msg->l1h;
+	td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
 
 	/* take the next pending byte out of the msgb */
 	byte = msgb_pull_u8(msg);
@@ -829,15 +852,12 @@
 	struct msgb *msg;
 	struct cardemu_usb_msg_status *sts;
 
-	msg = usb_buf_alloc(ch->in_ep);
+	msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
+				SIMTRACE_MSGT_BD_CEMU_STATUS);
 	if (!msg)
 		return;
 
-	msg->l1h = msgb_put(msg, sizeof(*sts));
-	msg->l2h = msg->l1h + sizeof(sts->hdr);
-	sts = (struct cardemu_usb_msg_status *) msg->l1h;
-	sts->hdr.msg_type = CEMU_USB_MSGT_DO_STATUS;
-	sts->hdr.msg_len = sizeof(*sts);
+	sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
 	sts->flags = 0;
 	if (ch->vcc_active)
 		sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
@@ -851,7 +871,7 @@
 	sts->wi = ch->wi;
 	sts->waiting_time = ch->waiting_time;
 
-	usb_buf_submit(msg);
+	usb_buf_upd_len_and_submit(msg);
 }
 
 /* hardware driver informs us that a card I/O signal has changed */
diff --git a/firmware/libcommon/source/mode_cardemu.c b/firmware/libcommon/source/mode_cardemu.c
index db4d120..ed18c11 100644
--- a/firmware/libcommon/source/mode_cardemu.c
+++ b/firmware/libcommon/source/mode_cardemu.c
@@ -10,7 +10,7 @@
 #include "osmocom/core/msgb.h"
 #include "llist_irqsafe.h"
 #include "usb_buf.h"
-#include "cardemu_prot.h"
+#include "simtrace_prot.h"
 
 #define TRACE_ENTRY()	TRACE_DEBUG("%s entering\r\n", __func__)
 
@@ -440,27 +440,42 @@
 }
 
 /* handle a single USB command as received from the USB host */
-static void dispatch_usb_command(struct msgb *msg, struct cardem_inst *ci)
+static void dispatch_usb_command_generic(struct msgb *msg, struct cardem_inst *ci)
 {
-	struct cardemu_usb_msg_hdr *hdr;
+	struct simtrace_msg_hdr *hdr;
+
+	hdr = (struct simtrace_msg_hdr *) msg->l1h;
+	switch (hdr->msg_type) {
+	case SIMTRACE_CMD_BD_BOARD_INFO:
+		break;
+	default:
+		break;
+	}
+	usb_buf_free(msg);
+}
+
+/* handle a single USB command as received from the USB host */
+static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci)
+{
+	struct simtrace_msg_hdr *hdr;
 	struct cardemu_usb_msg_set_atr *atr;
 	struct cardemu_usb_msg_cardinsert *cardins;
 	struct llist_head *queue;
 
-	hdr = (struct cardemu_usb_msg_hdr *) msg->l1h;
+	hdr = (struct simtrace_msg_hdr *) msg->l1h;
 	switch (hdr->msg_type) {
-	case CEMU_USB_MSGT_DT_TX_DATA:
+	case SIMTRACE_MSGT_DT_CEMU_TX_DATA:
 		queue = card_emu_get_uart_tx_queue(ci->ch);
 		llist_add_tail(&msg->list, queue);
 		card_emu_have_new_uart_tx(ci->ch);
 		break;
-	case CEMU_USB_MSGT_DT_SET_ATR:
-		atr = (struct cardemu_usb_msg_set_atr *) hdr;
+	case SIMTRACE_MSGT_DT_CEMU_SET_ATR:
+		atr = (struct cardemu_usb_msg_set_atr *) msg->l2h;
 		card_emu_set_atr(ci->ch, atr->atr, atr->atr_len);
 		usb_buf_free(msg);
 		break;
-	case CEMU_USB_MSGT_DT_CARDINSERT:
-		cardins = (struct cardemu_usb_msg_cardinsert *) hdr;
+	case SIMTRACE_MSGT_DT_CEMU_CARDINSERT:
+		cardins = (struct cardemu_usb_msg_cardinsert *) msg->l2h;
 		TRACE_INFO("%u: set card_insert to %s\r\n", ci->num,
 			   cardins->card_insert ? "INSERTED" : "REMOVED");
 		if (cardins->card_insert)
@@ -469,12 +484,60 @@
 			PIO_Clear(&ci->pin_insert);
 		usb_buf_free(msg);
 		break;
-	case CEMU_USB_MSGT_DT_GET_STATUS:
+	case SIMTRACE_MSGT_BD_CEMU_STATUS:
 		card_emu_report_status(ci->ch);
+		usb_buf_free(msg);
 		break;
-	case CEMU_USB_MSGT_DT_GET_STATS:
+	case SIMTRACE_MSGT_BD_CEMU_STATS:
 	default:
-		/* FIXME */
+		/* FIXME: Send Error */
+		usb_buf_free(msg);
+		break;
+	}
+}
+
+/* handle a single USB command as received from the USB host */
+static void dispatch_usb_command_modem(struct msgb *msg, struct cardem_inst *ci)
+{
+	struct simtrace_msg_hdr *hdr;
+
+	hdr = (struct simtrace_msg_hdr *) msg->l1h;
+	switch (hdr->msg_type) {
+	case SIMTRACE_MSGT_DT_MODEM_RESET:
+		break;
+	case SIMTRACE_MSGT_DT_MODEM_SIM_SELECT:
+		break;
+	case SIMTRACE_MSGT_BD_MODEM_STATUS:
+		break;
+	default:
+		break;
+	}
+	usb_buf_free(msg);
+}
+
+/* handle a single USB command as received from the USB host */
+static void dispatch_usb_command(struct msgb *msg, struct cardem_inst *ci)
+{
+	struct simtrace_msg_hdr *sh = msg->l1h;
+
+	if (msgb_length(msg) < sizeof(*sh)) {
+		/* FIXME: Error */
+		usb_buf_free(msg);
+		return;
+	}
+
+	switch (sh->msg_class) {
+	case SIMTRACE_MSGC_GENERIC:
+		dispatch_usb_command_generic(msg, ci);
+		break;
+	case SIMTRACE_MSGC_CARDEM:
+		dispatch_usb_command_cardem(msg, ci);
+		break;
+	case SIMTRACE_MSGC_MODEM:
+		dispatch_usb_command_modem(msg, ci);
+		break;
+	default:
+		/* FIXME: Send Error */
 		usb_buf_free(msg);
 		break;
 	}
@@ -483,12 +546,12 @@
 static void dispatch_received_msg(struct msgb *msg, struct cardem_inst *ci)
 {
 	struct msgb *segm;
-	struct cardemu_usb_msg_hdr *mh;
+	struct simtrace_msg_hdr *mh;
 
 	/* check if we have multiple concatenated commands in
 	 * one message.  USB endpoints are streams that don't
 	 * preserve the message boundaries */
-	mh = (struct cardemu_usb_msg_hdr *) msg->data;
+	mh = (struct simtrace_msg_hdr *) msg->data;
 	if (mh->msg_len == msgb_length(msg)) {
 		/* fast path: only one message in buffer */
 		dispatch_usb_command(msg, ci);
@@ -498,7 +561,7 @@
 	/* slow path: iterate over list of messages, allocating one new
 	 * reqe_ctx per segment */
 	while (1) {
-		mh = (struct cardemu_usb_msg_hdr *) msg->head;
+		mh = (struct simtrace_msg_hdr *) msg->data;
 
 		segm = usb_buf_alloc(ci->ep_out);
 		if (!segm) {
diff --git a/firmware/test/card_emu_tests.c b/firmware/test/card_emu_tests.c
index 75a8a99..3ea0678 100644
--- a/firmware/test/card_emu_tests.c
+++ b/firmware/test/card_emu_tests.c
@@ -5,7 +5,7 @@
 #include <stdlib.h>
 
 #include "card_emu.h"
-#include "cardemu_prot.h"
+#include "simtrace_prot.h"
 #include "tc_etu.h"
 #include "usb_buf.h"
 
@@ -134,8 +134,7 @@
 
 static void dump_rctx(struct msgb *msg)
 {
-	struct cardemu_usb_msg_hdr *mh =
-		(struct cardemu_usb_msg_hdr *) msg->l1h;
+	struct simtrace_msg_hdr *mh = (struct simtrace_msg_hdr *) msg->l1h;
 	struct cardemu_usb_msg_rx_data *rxd;
 	int i;
 #if 0
@@ -148,8 +147,8 @@
 	printf("%s\n", msgb_hexdump(msg));
 
 	switch (mh->msg_type) {
-	case CEMU_USB_MSGT_DO_RX_DATA:
-		rxd = (struct cardemu_usb_msg_rx_data *)mh;
+	case SIMTRACE_MSGT_DO_CEMU_RX_DATA:
+		rxd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
 		printf("    flags=%x, data=", rxd->flags);
 		for (i = 0; i < rxd->data_len; i++)
 			printf(" %02x", rxd->data[i]);
@@ -164,26 +163,25 @@
 	struct msgb *msg;
 	struct cardemu_usb_msg_tx_data *td;
 	struct cardemu_usb_msg_rx_data *rd;
-	struct cardemu_usb_msg_hdr *mh;
+	struct simtrace_msg_hdr *mh;
 
 	assert(queue);
 	msg = msgb_dequeue(queue);
 	assert(msg);
 	dump_rctx(msg);
 	assert(msg->l1h);
-	mh = (struct cardemu_usb_msg_hdr *) msg->l1h;
+	mh = (struct simtrace_msg_hdr *) msg->l1h;
 
 	/* verify the contents of the rctx */
 	switch (mh->msg_type) {
-	case CEMU_USB_MSGT_DO_RX_DATA:
-		rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
-		assert(rd->hdr.msg_type == CEMU_USB_MSGT_DO_RX_DATA);
+	case SIMTRACE_MSGT_DO_CEMU_RX_DATA:
+		rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
 		assert(rd->data_len == len);
 		assert(!memcmp(rd->data, data, len));
 		break;
 #if 0
 	case RCTX_S_UART_RX_PENDING:
-		rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
+		rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
 		assert(rd->data_len == len);
 		assert(!memcmp(rd->data, data, len));
 		break;
@@ -200,6 +198,7 @@
 {
 	struct llist_head *queue = usb_get_queue(PHONE_DATAIN);
 	struct msgb *msg;
+	struct simtrace_msg_hdr *mh;
 	struct cardemu_usb_msg_pts_info *ptsi;
 
 	assert(queue);
@@ -207,10 +206,11 @@
 	assert(msg);
 	dump_rctx(msg);
 	assert(msg->l1h);
+	mh = (struct simtrace_msg_hdr *) msg->l1h;
+	ptsi = (struct cardemu_usb_msg_pts_info *) msg->l2h;
 
-	ptsi = (struct cardemu_usb_msg_pts_info *) msg->l1h;
 	/* FIXME: verify */
-	assert(ptsi->hdr.msg_type == CEMU_USB_MSGT_DO_PTS);
+	assert(mh->msg_type == SIMTRACE_MSGT_DO_CEMU_PTS);
 	assert(!memcmp(ptsi->req, data, len));
 	assert(!memcmp(ptsi->resp, data, len));
 
@@ -234,27 +234,33 @@
 	get_and_verify_rctx(PHONE_DATAIN, tpdu_hdr, 5);
 }
 
-/* emulate a CEMU_USB_MSGT_DT_TX_DATA received from USB */
+/* emulate a SIMTRACE_MSGT_DT_CEMU_TX_DATA received from USB */
 static void host_to_device_data(struct card_handle *ch, const uint8_t *data, uint16_t len,
 				unsigned int flags)
 {
 	struct msgb *msg;
+	struct simtrace_msg_hdr *mh;
 	struct cardemu_usb_msg_tx_data *rd;
 	struct llist_head *queue;
 
 	/* allocate a free req_ctx */
 	msg = usb_buf_alloc(PHONE_DATAOUT);
 	assert(msg);
+	/* initialize the common header */
 	msg->l1h = msg->head;
+	mh = (struct simtrace_msg_hdr *) msgb_put(msg, sizeof(*mh));
+	mh->msg_class = SIMTRACE_MSGC_CARDEM;
+	mh->msg_type = SIMTRACE_MSGT_DT_CEMU_TX_DATA;
 
-	/* initialize the header */
-	rd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*rd) + len);
-	cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DT_TX_DATA);
+	/* initialize the tx_data message */
+	msg->l2h = msgb_put(msg, sizeof(*rd) + len);
+	rd = (struct cardemu_usb_msg_tx_data *) msg->l2h;
 	rd->flags = flags;
 	/* copy data and set length */
 	rd->data_len = len;
 	memcpy(rd->data, data, len);
-	rd->hdr.msg_len = sizeof(*rd) + len;
+
+	mh->msg_len = sizeof(*mh) + sizeof(*rd) + len;
 
 	/* hand the req_ctx to the UART transmit code */
 	queue = card_emu_get_uart_tx_queue(ch);
diff --git a/host/cardemu_prot.h b/host/cardemu_prot.h
deleted file mode 120000
index 0c10fef..0000000
--- a/host/cardemu_prot.h
+++ /dev/null
@@ -1 +0,0 @@
-../firmware/libcommon/include/cardemu_prot.h
\ No newline at end of file
diff --git a/host/simtrace2-remsim.c b/host/simtrace2-remsim.c
index 6b35e83..2a3636a 100644
--- a/host/simtrace2-remsim.c
+++ b/host/simtrace2-remsim.c
@@ -37,7 +37,7 @@
 
 #include "libusb_util.h"
 #include "simtrace.h"
-#include "cardemu_prot.h"
+#include "simtrace_prot.h"
 #include "apdu_dispatch.h"
 #include "simtrace2-discovery.h"
 
@@ -45,6 +45,7 @@
 #include <osmocom/core/gsmtap_util.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/core/socket.h>
+#include <osmocom/core/msgb.h>
 #include <osmocom/sim/class_tables.h>
 #include <osmocom/sim/sim.h>
 
@@ -92,6 +93,11 @@
 	return 0;
 }
 
+static struct msgb *st_msgb_alloc(void)
+{
+	return msgb_alloc_headroom(1024+32, 32, "SIMtrace");
+}
+
 #if 0
 static void apdu_out_cb(uint8_t *buf, unsigned int len, void *user_data)
 {
@@ -101,90 +107,117 @@
 #endif
 
 /*! \brief Transmit a given command to the SIMtrace2 device */
-static int tx_to_dev(struct cardem_inst *ci, uint8_t *buf, unsigned int len)
+static int tx_to_dev_msg(struct cardem_inst *ci, struct msgb *msg)
 {
-	struct cardemu_usb_msg_hdr *mh = (struct cardemu_usb_msg_hdr *) buf;
-	int xfer_len;
+	int rc;
 
-	mh->msg_len = len;
-
-	printf("<- %s\n", osmo_hexdump(buf, len));
+	printf("<- %s\n", msgb_hexdump(msg));
 
 	if (ci->udp_fd < 0) {
-		return libusb_bulk_transfer(ci->usb_devh, ci->usb_ep.out, buf, len,
-					    &xfer_len, 100000);
+		unsigned int xfer_len;
+
+		rc = libusb_bulk_transfer(ci->usb_devh, ci->usb_ep.out, msgb_data(msg),
+					  msgb_length(msg), &xfer_len, 100000);
 	} else {
-		return write(ci->udp_fd, buf, len);
+		rc = write(ci->udp_fd, msgb_data(msg), msgb_length(msg));
 	}
+
+	msgb_free(msg);
+	return rc;
+}
+
+static struct simtrace_msg_hdr *push_simtrace_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type)
+{
+	struct simtrace_msg_hdr *sh = msgb_push(msg, sizeof(*sh));
+
+	memset(sh, 0, sizeof(*sh));
+	sh->msg_class = msg_class;
+	sh->msg_type = msg_type;
+	sh->msg_len = msgb_length(msg);
 }
 
 /*! \brief Request the SIMtrace2 to generate a card-insert signal */
 static int request_card_insert(struct cardem_inst *ci, bool inserted)
 {
-	struct cardemu_usb_msg_cardinsert cins;
+	struct msgb *msg = st_msgb_alloc();
+	struct cardemu_usb_msg_cardinsert *cins;
 
-	memset(&cins, 0, sizeof(cins));
-	cins.hdr.msg_type = CEMU_USB_MSGT_DT_CARDINSERT;
+	cins = (struct cardemu_usb_msg_cardinsert *) msgb_put(msg, sizeof(*cins));
+	memset(cins, 0, sizeof(*cins));
 	if (inserted)
-		cins.card_insert = 1;
+		cins->card_insert = 1;
 
-	return tx_to_dev(ci, (uint8_t *)&cins, sizeof(cins));
+	push_simtrace_hdr(msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_CARDINSERT);
+
+	return tx_to_dev_msg(ci, msg);
 }
 
 /*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Rx */
 static int request_pb_and_rx(struct cardem_inst *ci, uint8_t pb, uint8_t le)
 {
+	struct msgb *msg = st_msgb_alloc();
 	struct cardemu_usb_msg_tx_data *txd;
-	uint8_t buf[sizeof(*txd) + 1];
-	txd = (struct cardemu_usb_msg_tx_data *) buf;
+	txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
 
 	printf("<= request_pb_and_rx(%02x, %d)\n", pb, le);
 
 	memset(txd, 0, sizeof(*txd));
 	txd->data_len = 1;
-	txd->hdr.msg_type = CEMU_USB_MSGT_DT_TX_DATA;
 	txd->flags = CEMU_DATA_F_PB_AND_RX;
-	txd->data[0] = pb;
+	/* one data byte */
+	msgb_put_u8(msg, pb);
 
-	return tx_to_dev(ci, (uint8_t *)txd, sizeof(*txd)+txd->data_len);
+	push_simtrace_hdr(msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
+
+	return tx_to_dev_msg(ci, msg);
 }
 
 /*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Tx */
 static int request_pb_and_tx(struct cardem_inst *ci, uint8_t pb, const uint8_t *data, uint8_t data_len_in)
 {
+	struct msgb *msg = st_msgb_alloc();
 	struct cardemu_usb_msg_tx_data *txd;
-	uint8_t buf[sizeof(*txd) + 1 + data_len_in];
-	txd = (struct cardemu_usb_msg_tx_data *) buf;
+	uint8_t *cur;
+
+	txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
 
 	printf("<= request_pb_and_tx(%02x, %s, %d)\n", pb, osmo_hexdump(data, data_len_in), data_len_in);
 
 	memset(txd, 0, sizeof(*txd));
-	txd->hdr.msg_type = CEMU_USB_MSGT_DT_TX_DATA;
 	txd->data_len = 1 + data_len_in;
 	txd->flags = CEMU_DATA_F_PB_AND_TX;
-	txd->data[0] = pb;
-	memcpy(txd->data+1, data, data_len_in);
+	/* procedure byte */
+	msgb_put_u8(msg, pb);
+	/* data */
+	cur = msgb_put(msg, data_len_in);
+	memcpy(cur, data, data_len_in);
 
-	return tx_to_dev(ci, buf, sizeof(*txd)+txd->data_len);
+	push_simtrace_hdr(msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
+
+	return tx_to_dev_msg(ci, msg);
 }
 
 /*! \brief Request the SIMtrace2 to send a Status Word */
 static int request_sw_tx(struct cardem_inst *ci, const uint8_t *sw)
 {
+	struct msgb *msg = st_msgb_alloc();
 	struct cardemu_usb_msg_tx_data *txd;
-	uint8_t buf[sizeof(*txd) + 2];
-	txd = (struct cardemu_usb_msg_tx_data *) buf;
+	uint8_t *cur;
+
+	txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
 
 	printf("<= request_sw_tx(%02x %02x)\n", sw[0], sw[1]);
 
 	memset(txd, 0, sizeof(*txd));
-	txd->hdr.msg_type = CEMU_USB_MSGT_DT_TX_DATA;
 	txd->data_len = 2;
 	txd->flags = CEMU_DATA_F_PB_AND_TX | CEMU_DATA_F_FINAL;
-	txd->data[0] = sw[0];
-	txd->data[1] = sw[1];
+	cur = msgb_put(msg, 2);
+	cur[0] = sw[0];
+	cur[1] = sw[1];
 
-	return tx_to_dev(ci, (uint8_t *)txd, sizeof(*txd)+txd->data_len);
+	push_simtrace_hdr(msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
+
+	return tx_to_dev_msg(ci, msg);
 }
 
 static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
@@ -200,18 +233,22 @@
 
 static int request_set_atr(struct cardem_inst *ci, const uint8_t *atr, unsigned int atr_len)
 {
+	struct msgb *msg = st_msgb_alloc();
 	struct cardemu_usb_msg_set_atr *satr;
-	uint8_t buf[sizeof(*satr) + atr_len];
-	satr = (struct cardemu_usb_msg_set_atr *) buf;
+	uint8_t *cur;
+
+	satr = (struct cardemu_usb_msg_set_atr *) msgb_put(msg, sizeof(*satr));
 
 	printf("<= request_set_atr(%s)\n", osmo_hexdump(atr, atr_len));
 
 	memset(satr, 0, sizeof(*satr));
-	satr->hdr.msg_type = CEMU_USB_MSGT_DT_SET_ATR;
 	satr->atr_len = atr_len;
-	memcpy(satr->atr, atr, atr_len);
+	cur = msgb_put(msg, atr_len);
+	memcpy(cur, atr, atr_len);
 
-	return tx_to_dev(ci, (uint8_t *)satr, sizeof(buf));
+	push_simtrace_hdr(msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_SET_ATR);
+
+	return tx_to_dev_msg(ci, msg);
 }
 
 /*! \brief Process a STATUS message from the SIMtrace2 */
@@ -300,25 +337,30 @@
 	return 0;
 }
 
+#if 0
+	case SIMTRACE_CMD_DO_ERROR
+		rc = process_do_error(ci, buf, len);
+		break;
+#endif
+
 /*! \brief Process an incoming message from the SIMtrace2 */
 static int process_usb_msg(struct cardem_inst *ci, uint8_t *buf, int len)
 {
-	struct cardemu_usb_msg_hdr *sh = (struct cardemu_usb_msg_hdr *)buf;
+	struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *)buf;
 	int rc;
 
 	printf("-> %s\n", osmo_hexdump(buf, len));
 
+	buf += sizeof(*sh);
+
 	switch (sh->msg_type) {
-	case CEMU_USB_MSGT_DO_STATUS:
+	case SIMTRACE_MSGT_BD_CEMU_STATUS:
 		rc = process_do_status(ci, buf, len);
 		break;
-	case CEMU_USB_MSGT_DO_PTS:
+	case SIMTRACE_MSGT_DO_CEMU_PTS:
 		rc = process_do_pts(ci, buf, len);
 		break;
-	case CEMU_USB_MSGT_DO_ERROR:
-		rc = process_do_error(ci, buf, len);
-		break;
-	case CEMU_USB_MSGT_DO_RX_DATA:
+	case SIMTRACE_MSGT_DO_CEMU_RX_DATA:
 		rc = process_do_rx_da(ci, buf, len);
 		break;
 	default:
diff --git a/host/simtrace_prot.h b/host/simtrace_prot.h
new file mode 120000
index 0000000..a9fffe1
--- /dev/null
+++ b/host/simtrace_prot.h
@@ -0,0 +1 @@
+../firmware/libcommon/include/simtrace_prot.h
\ No newline at end of file
diff --git a/host/usb2udp.c b/host/usb2udp.c
index e33e371..5e48b22 100644
--- a/host/usb2udp.c
+++ b/host/usb2udp.c
@@ -36,7 +36,7 @@
 #include <libusb.h>
 
 #include "simtrace.h"
-#include "cardemu_prot.h"
+#include "simtrace_prot.h"
 #include "apdu_dispatch.h"
 #include "simtrace2-discovery.h"