Change in osmo-ccid-firmware[master]: first attempt at timeout handling

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Hoernchen gerrit-no-reply at lists.osmocom.org
Tue Nov 26 18:39:17 UTC 2019


Hoernchen has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16253 )


Change subject: first attempt at timeout handling
......................................................................

first attempt at timeout handling

Change-Id: I96315fed5696ccd75318ebd88cb7725ed7568c07
---
M ccid_common/cuart.c
M ccid_common/cuart.h
M ccid_common/iso7816_fsm.c
3 files changed, 142 insertions(+), 30 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/53/16253/1

diff --git a/ccid_common/cuart.c b/ccid_common/cuart.c
index 1ae50c6..1d777f9 100644
--- a/ccid_common/cuart.c
+++ b/ccid_common/cuart.c
@@ -49,7 +49,12 @@
 {
 	int secs, usecs;
 
-	usecs = get_etu_in_us(cuart) * cuart->wtime_etu;
+	if(!cuart->current_wtime_byte)
+		return;
+
+	/* timemout is wtime * ETU + expected number of bytes * (12ETU+1 slack)ETU */
+	usecs = get_etu_in_us(cuart) * cuart->wtime_etu +
+			get_etu_in_us(cuart) * cuart->current_wtime_byte * (12+1);
 	if (usecs > 1000000) {
 		secs = usecs / 1000000;
 		usecs = usecs % 1000000;
@@ -108,6 +113,15 @@
 		cuart->rx_enabled = arg ? true : false;
 		if (!cuart->rx_enabled)
 			osmo_timer_del(&cuart->wtime_tmr);
+//		else
+//			card_uart_wtime_restart(cuart);
+		break;
+	case CUART_CTL_RX_TIMER_HINT:
+		cuart->current_wtime_byte = arg;
+		if(arg)
+			card_uart_wtime_restart(cuart);
+		else
+			osmo_timer_del(&cuart->wtime_tmr);
 		break;
 	default:
 		break;
@@ -158,6 +172,12 @@
 		if (cuart->rx_after_tx_compl)
 			card_uart_ctrl(cuart, CUART_CTL_RX, true);
 		break;
+//	case CUART_E_RX_COMPLETE:
+//		osmo_timer_del(&cuart->wtime_tmr);
+//		break;
+//	case CUART_E_RX_SINGLE:
+//		card_uart_wtime_restart(cuart);
+//		break;
 	default:
 		break;
 	}
diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index 40a4aa8..a16e0db 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -23,6 +23,7 @@
 
 enum card_uart_ctl {
 	CUART_CTL_RX,		/* enable/disable receiver */
+	CUART_CTL_RX_TIMER_HINT, /* tell cuart approximate number of rx bytes */
 	CUART_CTL_NO_RXTX,		/* enable/disable receiver */
 	CUART_CTL_POWER,	/* enable/disable ICC power */
 	CUART_CTL_CLOCK,	/* enable/disable ICC clock */
@@ -78,6 +79,8 @@
 
 	uint32_t wtime_etu;
 	struct osmo_timer_list wtime_tmr;
+	/* expected number of bytes, for timeout */
+	uint32_t current_wtime_byte;
 
 
 	/* driver-specific private data */
diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c
index a659fe4..4d2db15 100644
--- a/ccid_common/iso7816_fsm.c
+++ b/ccid_common/iso7816_fsm.c
@@ -68,14 +68,14 @@
  *  @note defined in ISO/IEC 7816-3:2006(E) section 9
  */
 enum pps_state {
-	PPS_S_TX_PPS_REQ,  /*!< tx pps request */
-	PPS_S_WAIT_PPSS, /*!< initial byte */
+	PPS_S_PPS_REQ_INIT,  /*!< tx pps request */
+	PPS_S_TX_PPS_REQ,
+	PPS_S_WAIT_PPSX, /*!< initial byte */
 	PPS_S_WAIT_PPS0, /*!< format byte */
 	PPS_S_WAIT_PPS1, /*!< first parameter byte */
 	PPS_S_WAIT_PPS2, /*!< second parameter byte */
 	PPS_S_WAIT_PPS3, /*!< third parameter byte */
 	PPS_S_WAIT_PCK, /*!< check byte */
-	PPS_S_WAIT_END, /*!< all done */
 	PPS_S_DONE
 };
 
@@ -219,9 +219,11 @@
 	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
 	OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
 
+	card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
+
 	/* go back to initial state in child FSMs */
 	osmo_fsm_inst_state_chg(ip->atr_fi, ATR_S_WAIT_TS, 0, 0);
-	osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_TX_PPS_REQ, 0, 0);
+	osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_PPS_REQ_INIT, 0, 0);
 	osmo_fsm_inst_state_chg(ip->tpdu_fi, TPDU_S_INIT, 0, 0);
 }
 
@@ -235,8 +237,13 @@
 	case ISO7816_E_RESET_REL_IND:
 		/* TOOD: this should happen before reset is released */
 		card_uart_ctrl(ip->uart, CUART_CTL_RX, true);
-		osmo_fsm_inst_state_chg_ms(fi, ISO7816_S_WAIT_ATR,
-					   fi_cycles2ms(fi, 40000), T_WAIT_ATR);
+
+		/* let's be reasonable here: the 40k cycle delay to ATR start is
+		 * ~1.4ms @ 2.5Mhz/6720 baud, 1ETU = 372 cycles -> 40k/372=107/12ETU ~ 9 byte
+		 * default timeout for rx is 9600 ETU, ATR might be missing the TCK
+		 * so it might time out, so just add this delay */
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 32+9);
+		osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_ATR, 0, 0);
 		break;
 	case ISO7816_E_POWER_UP_IND:
 		break;
@@ -308,6 +315,7 @@
 {
 	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
 	OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
+	card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
 	card_uart_ctrl(ip->uart, CUART_CTL_NO_RXTX, true);
 	/* reset the TPDU state machine */
 	osmo_fsm_inst_dispatch(ip->tpdu_fi, ISO7816_E_TPDU_CLEAR_REQ, NULL);
@@ -328,7 +336,7 @@
 	case ISO7816_E_XCEIVE_PPS_CMD:
 //		osmo_fsm_inst_state_chg(fi, ISO7816_S_IN_PPS_REQ, 0, 0);
 		osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_PPS_RSP, 0, 0);
-		osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_TX_PPS_REQ, 0, 0);
+		osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_PPS_REQ_INIT, 0, 0);
 		osmo_fsm_inst_dispatch(ip->pps_fi, event, data);
 		break;
 	default:
@@ -392,11 +400,13 @@
 
 static void iso7816_3_s_wait_pps_rsp_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
 	OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
 	switch (event) {
 	case ISO7816_E_TX_COMPL:
 		/* Rx of single byte is already enabled by previous card_uart_tx() call */
 		osmo_fsm_inst_state_chg(fi, ISO7816_S_IN_PPS_RSP, 0, 0);
+		osmo_fsm_inst_dispatch(ip->pps_fi, event, data);
 		break;
 	default:
 		OSMO_ASSERT(0);
@@ -436,6 +446,7 @@
 	[ISO7816_S_RESET] = {
 		.name = "RESET",
 		.in_event_mask =	S(ISO7816_E_RESET_REL_IND) |
+							S(ISO7816_E_POWER_UP_IND) |
 							S(ISO7816_E_PPS_FAILED_IND)|
 							S(ISO7816_E_TPDU_FAILED_IND),
 		.out_state_mask =	S(ISO7816_S_WAIT_ATR) |
@@ -752,6 +763,14 @@
 	}
 }
 
+static void atr_done_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+{
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
+
+	card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
+}
+
 static const struct osmo_fsm_state atr_states[] = {
 	[ATR_S_WAIT_TS] = {
 		.name = "WAIT_TS",
@@ -848,7 +867,7 @@
 		.name = "DONE",
 		.in_event_mask =	0,
 		.out_state_mask =	S(ATR_S_WAIT_TS),
-		//.action = atr_done_action,
+		.onenter = atr_done_onenter
 	},
 
 };
@@ -869,7 +888,7 @@
 	uint8_t pps0_recv;
 };
 
-static void pps_s_wait_ppss_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+static void pps_s_pps_req_init_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
 {
 	struct pps_fsm_priv *atp = fi->priv;
 
@@ -886,7 +905,7 @@
 	}
 }
 
-static void pps_s_tx_pps_req_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+static void pps_s_pps_req_init_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct pps_fsm_priv *atp = fi->priv;
 	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
@@ -897,7 +916,8 @@
 
 	switch (event) {
 	case ISO7816_E_XCEIVE_PPS_CMD:
-		osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPSS, 0, 0);
+		osmo_fsm_inst_state_chg(fi, PPS_S_TX_PPS_REQ, 0, 0);
+		card_uart_set_rx_threshold(ip->uart, 1);
 		card_uart_tx(ip->uart, msgb_data(data), msgb_length(data), true);
 		break;
 	default:
@@ -905,10 +925,29 @@
 	}
 }
 
+static void pps_s_tx_pps_req_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
+
+	switch (event) {
+	case ISO7816_E_TX_COMPL:
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 6);
+		osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPSX, 0, 0);
+		break;
+	default:
+		OSMO_ASSERT(0);
+	}
+}
+
+
+
+
 static void pps_wait_pX_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct pps_fsm_priv *atp = fi->priv;
-//	uint32_t guard_time_ms = atr_fi_gt_ms(fi);
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
 	uint8_t byte;
 
 	switch (event) {
@@ -917,7 +956,7 @@
 		LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);
 		msgb_put_u8(atp->rx_cmd, byte);
 		switch (fi->state) {
-		case PPS_S_WAIT_PPSS:
+		case PPS_S_WAIT_PPSX:
 			if (byte == 0xff)
 				osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS0, 0, 0);
 			break;
@@ -961,7 +1000,7 @@
 				uint8_t *pps_received = msgb_data(atp->rx_cmd);
 				uint8_t *pps_sent = msgb_data(atp->tx_cmd);
 
-				osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_END, 0, 0);
+				osmo_fsm_inst_state_chg(fi, PPS_S_DONE, 0, 0);
 
 				/* pps was successful if response equals request
 				 * rx buffer stays with the fsm, tx buffer gets handed back and freed
@@ -983,6 +1022,7 @@
 		}
 		break;
 	case ISO7816_E_WTIME_EXP:
+		osmo_fsm_inst_state_chg(fi, PPS_S_DONE, 0, 0);
 		/* FIXME: timeout handling if no pps supported ? */
 		osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_RX_ERR_IND, NULL);
 		break;
@@ -992,22 +1032,37 @@
 }
 
 
+static void pps_s_done_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+{
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
+
+	card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
+}
+
+
 static const struct osmo_fsm_state pps_states[] = {
-	[PPS_S_TX_PPS_REQ] = {
-		.name = "TX_PPS_REQ",
+	[PPS_S_PPS_REQ_INIT] = {
+		.name = "INIT",
 		.in_event_mask =	S(ISO7816_E_XCEIVE_PPS_CMD) |
 							S(ISO7816_E_WTIME_EXP),
-		.out_state_mask =	S(PPS_S_TX_PPS_REQ) |
-							S(PPS_S_WAIT_PPSS),
-		.action = pps_s_tx_pps_req_action,
-		.onenter = pps_s_wait_ppss_onenter,
+		.out_state_mask =	S(PPS_S_PPS_REQ_INIT) |
+							S(PPS_S_TX_PPS_REQ),
+		.action = pps_s_pps_req_init_action,
+		.onenter = pps_s_pps_req_init_onenter,
 	},
-	[PPS_S_WAIT_PPSS] = {
+	[PPS_S_TX_PPS_REQ] = {
+		.name = "TX_PPS_REQ",
+		.in_event_mask =	S(ISO7816_E_TX_COMPL),
+		.out_state_mask =	S(PPS_S_WAIT_PPSX),
+		.action = pps_s_tx_pps_req_action,
+	},
+	[PPS_S_WAIT_PPSX] = {
 		.name = "WAIT_PPSS",
 		.in_event_mask =	S(ISO7816_E_RX_SINGLE) |
 							S(ISO7816_E_WTIME_EXP),
 		.out_state_mask =	S(PPS_S_WAIT_PPS0) |
-							S(PPS_S_WAIT_PPSS),
+							S(PPS_S_WAIT_PPSX),
 		.action = pps_wait_pX_action,
 	},
 	[PPS_S_WAIT_PPS0] = {
@@ -1048,14 +1103,15 @@
 		.name = "WAIT_PCK",
 		.in_event_mask =	S(ISO7816_E_RX_SINGLE) |
 							S(ISO7816_E_WTIME_EXP),
-		.out_state_mask =	S(PPS_S_WAIT_END),
+		.out_state_mask =	S(PPS_S_DONE),
 		.action = pps_wait_pX_action,
 	},
-	[PPS_S_WAIT_END] = {
-		.name = "WAIT_END",
+	[PPS_S_DONE] = {
+		.name = "DONE",
 		.in_event_mask =	0,
-		.out_state_mask =	S(PPS_S_TX_PPS_REQ) |
-							S(PPS_S_WAIT_PPSS),
+		.out_state_mask =	S(PPS_S_PPS_REQ_INIT),
+		.action = NULL,
+		.onenter = pps_s_done_onenter,
 	},
 };
 
@@ -1141,11 +1197,14 @@
 #include <hal_gpio.h>
 static void tpdu_s_tx_hdr_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
 	OSMO_ASSERT(fi->fsm == &tpdu_fsm);
 	switch (event) {
 	case ISO7816_E_TX_COMPL:
 
-
+		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 		/* Rx of single byte is already enabled by previous card_uart_tx() call */
 		osmo_fsm_inst_state_chg(fi, TPDU_S_PROCEDURE, 0, 0);
 		break;
@@ -1170,11 +1229,15 @@
 		LOGPFSML(fi, LOGL_DEBUG, "Received 0x%02x from UART\n", byte);
 		if (byte == 0x60) {
 			/* NULL: wait for another procedure byte */
+			card_uart_set_rx_threshold(ip->uart, 1);
+			card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 			osmo_fsm_inst_state_chg(fi, TPDU_S_PROCEDURE, 0, 0);
 		} else if ((byte >= 0x60 && byte <= 0x6f) || (byte >= 0x90 && byte <= 0x9f)) {
 			//msgb_apdu_sw(tfp->apdu) = byte << 8;
 			msgb_put(tfp->tpdu, byte);
 			/* receive second SW byte (SW2) */
+			card_uart_set_rx_threshold(ip->uart, 1);
+			card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 			osmo_fsm_inst_state_chg(fi, TPDU_S_SW2, 0, 0);
 			break;
 		} else if (byte == tpduh->ins) {
@@ -1190,6 +1253,7 @@
 				osmo_fsm_inst_state_chg(fi, TPDU_S_TX_REMAINING, 0, 0);
 			} else {
 				card_uart_set_rx_threshold(ip->uart, tpduh->p3);
+				card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, tpduh->p3);
 				osmo_fsm_inst_state_chg(fi, TPDU_S_RX_REMAINING, 0, 0);
 			}
 		} else if (byte == (tpduh->ins ^ 0xFF)) {
@@ -1200,6 +1264,8 @@
 				card_uart_tx(ip->uart, msgb_l3(tfp->tpdu), 1, false);
 				osmo_fsm_inst_state_chg(fi, TPDU_S_TX_SINGLE, 0, 0);
 			} else {
+				card_uart_set_rx_threshold(ip->uart, 1);
+				card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 				osmo_fsm_inst_state_chg(fi, TPDU_S_RX_SINGLE, 0, 0);
 			}
 		} else
@@ -1219,6 +1285,7 @@
 	switch (event) {
 	case ISO7816_E_TX_COMPL:
 		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 		osmo_fsm_inst_state_chg(fi, TPDU_S_SW1, 0, 0);
 		break;
 	default:
@@ -1230,10 +1297,14 @@
 static void tpdu_s_tx_single_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct tpdu_fsm_priv *tfp = get_tpdu_fsm_priv(fi);
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
 
 	switch (event) {
 	case ISO7816_E_TX_COMPL:
 		tfp->tpdu->l3h += 1;
+		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 		if (msgb_l3len(tfp->tpdu))
 			osmo_fsm_inst_state_chg(fi, TPDU_S_PROCEDURE, 0, 0);
 		else
@@ -1264,6 +1335,7 @@
 				 msgb_l2len(tfp->tpdu));
 		}
 		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 		osmo_fsm_inst_state_chg(fi, TPDU_S_SW1, 0, 0);
 		break;
 	default:
@@ -1276,6 +1348,8 @@
 {
 	struct tpdu_fsm_priv *tfp = get_tpdu_fsm_priv(fi);
 	struct osim_apdu_cmd_hdr *tpduh = msgb_tpdu_hdr(tfp->tpdu);
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
 	uint8_t byte;
 
 	switch (event) {
@@ -1283,6 +1357,10 @@
 		byte = get_rx_byte_evt(fi->proc.parent, data);
 		LOGPFSML(fi, LOGL_DEBUG, "Received 0x%02x from UART\n", byte);
 		msgb_put_u8(tfp->tpdu, byte);
+
+		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
+
 		/* determine if number of expected bytes received */
 		if (msgb_l2len(tfp->tpdu) == tpduh->p3)
 			osmo_fsm_inst_state_chg(fi, TPDU_S_SW1, 0, 0);
@@ -1309,6 +1387,7 @@
 		//msgb_apdu_sw(tfp->apdu) = byte << 8;
 		msgb_put_u8(tfp->tpdu, byte);
 		card_uart_set_rx_threshold(ip->uart, 1);
+		card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 1);
 		osmo_fsm_inst_state_chg(fi, TPDU_S_SW2, 0, 0);
 		break;
 	default:
@@ -1352,7 +1431,7 @@
 	case ISO7816_E_TX_ERR_IND:
 		/* FIXME: handle this in some different way */
 		osmo_fsm_inst_state_chg(fi, TPDU_S_DONE, 0, 0);
-		osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_TPDU_DONE_IND, NULL);
+		osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_TPDU_FAILED_IND, NULL);
 		break;
 	case ISO7816_E_TPDU_CLEAR_REQ:
 		osmo_fsm_inst_state_chg(fi, TPDU_S_INIT, 0, 0);
@@ -1360,6 +1439,15 @@
 	}
 }
 
+
+static void tpdu_s_done_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+{
+	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
+
+	card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
+}
+
 static const struct osmo_fsm_state tpdu_states[] = {
 	[TPDU_S_INIT] = {
 		.name = "INIT",
@@ -1436,6 +1524,7 @@
 		.in_event_mask = 0,
 		.out_state_mask = S(TPDU_S_INIT),
 		.action = NULL,
+		.onenter = tpdu_s_done_onenter,
 	},
 };
 static struct osmo_fsm tpdu_fsm = {

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16253
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: I96315fed5696ccd75318ebd88cb7725ed7568c07
Gerrit-Change-Number: 16253
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191126/9229c36a/attachment.htm>


More information about the gerrit-log mailing list