ensure usb_msg_hdr contains raw message length

we want to ensure that the length of every (current or future) message
can be determined by looking at cardemu_usb_msg_hdr.msg_len, rather than
having a length that is relative to the respective specific command.
diff --git a/firmware/src_simtrace/card_emu.c b/firmware/src_simtrace/card_emu.c
index 8376943..8e9fef8 100644
--- a/firmware/src_simtrace/card_emu.c
+++ b/firmware/src_simtrace/card_emu.c
@@ -174,7 +174,8 @@
 
 	/* store length of data payload fild in header */
 	rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
-	rd->hdr.data_len = rctx->idx;
+	rd->data_len = rctx->idx;
+	rd->hdr.msg_len = sizeof(*rd) + rd->data_len;
 
 	llist_add_tail(&rctx->list, &ch->usb_tx_queue);
 	req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
@@ -229,7 +230,8 @@
 
 	ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data;
 	ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS;
-	ptsi->hdr.data_len = serialize_pts(ptsi->req, ch->pts.req);
+	ptsi->hdr.msg_len = sizeof(*ptsi);
+	ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
 	serialize_pts(ptsi->resp, ch->pts.resp);
 
 	llist_add_tail(&rctx->list, &ch->usb_tx_queue);
@@ -701,7 +703,7 @@
 	}
 
 	/* check if the buffer has now been fully transmitted */
-	if ((rctx->idx >= td->hdr.data_len) ||
+	if ((rctx->idx >= td->data_len) ||
 	    (td->data + rctx->idx >= rctx->data + rctx->tot_len)) {
 		if (td->flags & CEMU_DATA_F_PB_AND_RX) {
 			/* we have just sent the procedure byte and now
diff --git a/firmware/src_simtrace/cardemu_prot.h b/firmware/src_simtrace/cardemu_prot.h
index da49034..1a8c213 100644
--- a/firmware/src_simtrace/cardemu_prot.h
+++ b/firmware/src_simtrace/cardemu_prot.h
@@ -43,7 +43,8 @@
 struct cardemu_usb_msg_hdr {
 	uint8_t msg_type;	/* enum cardemu_usb_msg_type */
 	uint8_t seq_nr;		/* sequence number */
-	uint16_t data_len;	/* length of optional data field */
+	uint16_t msg_len;	/* length of message including hdr */
+	uint8_t data[0];
 } __attribute__ ((packed));
 
 /* indicates a TPDU header is present in this message */
@@ -64,7 +65,8 @@
 /* CEMU_USB_MSGT_DT_SET_ATR */
 struct cardemu_usb_msg_set_atr {
 	struct cardemu_usb_msg_hdr hdr;
-	/* variable-length ATR data (hdr.data_len) */
+	uint8_t atr_len;
+	/* variable-length ATR data */
 	uint8_t atr[0];
 } __attribute__ ((packed));
 
@@ -72,7 +74,8 @@
 struct cardemu_usb_msg_tx_data {
 	struct cardemu_usb_msg_hdr hdr;
 	uint32_t flags;
-	/* variable-length TPDU data (hdr.data_len) */
+	uint16_t data_len;
+	/* variable-length TPDU data */
 	uint8_t data[0];
 } __attribute__ ((packed));
 
@@ -80,7 +83,8 @@
 struct cardemu_usb_msg_rx_data {
 	struct cardemu_usb_msg_hdr hdr;
 	uint32_t flags;
-	/* variable-length TPDU data (hdr.data_len) */
+	uint16_t data_len;
+	/* variable-length TPDU data */
 	uint8_t data[0];
 } __attribute__ ((packed));
 
@@ -105,6 +109,7 @@
 /* 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 */
@@ -117,6 +122,7 @@
 	uint8_t severity;
 	uint8_t subsystem;
 	uint16_t code;
+	uint8_t msg_len;
 	/* human-readable error message */
 	uint8_t msg[0];
 } __attribute__ ((packed));
diff --git a/firmware/src_simtrace/mode_cardemu.c b/firmware/src_simtrace/mode_cardemu.c
index a26abe7..3651752 100644
--- a/firmware/src_simtrace/mode_cardemu.c
+++ b/firmware/src_simtrace/mode_cardemu.c
@@ -305,7 +305,7 @@
 		break;
 	case CEMU_USB_MSGT_DT_SET_ATR:
 		atr = (struct cardemu_usb_msg_set_atr *) hdr;
-		card_emu_set_atr(ci->ch, atr->atr, hdr->data_len);
+		card_emu_set_atr(ci->ch, atr->atr, atr->atr_len);
 		req_ctx_put(rctx);
 		break;
 	case CEMU_USB_MSGT_DT_CARDINSERT:
diff --git a/firmware/test/card_emu_tests.c b/firmware/test/card_emu_tests.c
index e071dfa..babb3ec 100644
--- a/firmware/test/card_emu_tests.c
+++ b/firmware/test/card_emu_tests.c
@@ -140,7 +140,7 @@
 	case CEMU_USB_MSGT_DO_RX_DATA:
 		rxd = (struct cardemu_usb_msg_rx_data *)mh;
 		printf("    flags=%x, data=", rxd->flags);
-		for (i = 0; i < mh->data_len; i++)
+		for (i = 0; i < rxd->data_len; i++)
 			printf(" %02x", rxd->data[i]);
 		printf("\n");
 		break;
@@ -162,13 +162,13 @@
 	case RCTX_S_USB_TX_PENDING:
 		td = (struct cardemu_usb_msg_tx_data *) rctx->data;
 		assert(td->hdr.msg_type == CEMU_USB_MSGT_DO_RX_DATA);
-		assert(td->hdr.data_len == len);
+		assert(td->data_len == len);
 		assert(!memcmp(td->data, data, len));
 		break;
 #if 0
 	case RCTX_S_UART_RX_PENDING:
 		rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
-		assert(rd->hdr.data_len == len);
+		assert(rd->data_len == len);
 		assert(!memcmp(rd->data, data, len));
 		break;
 #endif
@@ -229,8 +229,9 @@
 	cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DT_TX_DATA);
 	rd->flags = flags;
 	/* copy data and set length */
-	rd->hdr.data_len = len;
+	rd->data_len = len;
 	memcpy(rd->data, data, len);
+	rd->hdr.msg_len = sizeof(*rd) + len;
 
 	/* hand the req_ctx to the UART transmit code */
 	req_ctx_set_state(rctx, RCTX_S_UART_TX_PENDING);