Change in simtrace2[master]: introduce support for new ngff_cardem board

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/.

laforge gerrit-no-reply at lists.osmocom.org
Mon Aug 2 09:22:47 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/simtrace2/+/25082 )

Change subject: introduce support for new ngff_cardem board
......................................................................

introduce support for new ngff_cardem board

This adds support for the new ngff_cardem board, a board that
basically combines a ngff breakout board with a built-in SIMtrace2.

Cardem works, but depending on the modem it might need a adjusted ATR to
ensure a lower baud  rate is used by the modem, high rates might lead
to weird power cycling of the card after a few transfers.

Trace was also tested and appears to work as expected.

Change-Id: Ia96124fbe8a752c98e7fd4096d542a3b2b9bc255
---
M contrib/flash.py
M contrib/simtrace.lua
M firmware/apps/cardem/main.c
A firmware/libboard/ngff_cardem/include/board.h
A firmware/libboard/ngff_cardem/include/card_pres.h
A firmware/libboard/ngff_cardem/include/wwan_led.h
A firmware/libboard/ngff_cardem/include/wwan_perst.h
A firmware/libboard/ngff_cardem/product_string.txt
A firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
A firmware/libboard/ngff_cardem/source/card_pres.c
A firmware/libboard/ngff_cardem/source/sim_switch.c
A firmware/libboard/ngff_cardem/source/wwan_led.c
A firmware/libboard/ngff_cardem/source/wwan_perst.c
M firmware/libboard/simtrace/include/board.h
M firmware/libcommon/include/simtrace_usb.h
M firmware/libcommon/source/mode_cardemu.c
M host/contrib/99-simtrace2.rules
M host/lib/usb_util.c
M host/src/simtrace2-sniff.c
19 files changed, 798 insertions(+), 8 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/contrib/flash.py b/contrib/flash.py
index 21903bb..01fe7c9 100755
--- a/contrib/flash.py
+++ b/contrib/flash.py
@@ -28,7 +28,8 @@
 DEVICE_QMOD = Device(usb_vendor_id=0x1d50, usb_product_id=0x4004, name="sysmoQMOD (Quad Modem)", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/qmod-cardem-dfu-latest.bin"})
 DEVICE_OWHW = Device(usb_vendor_id=0x1d50, usb_product_id=0x4001, name="OWHW", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/owhw-cardem-dfu-latest.bin"})
 DEVICE_OCTSIMTEST = Device(usb_vendor_id=0x1d50, usb_product_id=0x616d, name="OCTSIMTEST", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/octsimtest-cardem-dfu-latest.bin"})
-DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD, DEVICE_OCTSIMTEST]
+DEVICE_NGFF_CARDEM = Device(usb_vendor_id=0x1d50, usb_product_id=0x616e, name="ngff-cardem", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/ngff_cardem-cardem-dfu-latest.bin"})
+DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD, DEVICE_OCTSIMTEST, DEVICE_NGFF_CARDEM]
 
 # which firmware does the SIMtrace USN interface subclass correspond
 FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
diff --git a/contrib/simtrace.lua b/contrib/simtrace.lua
index 68eb961..8298265 100644
--- a/contrib/simtrace.lua
+++ b/contrib/simtrace.lua
@@ -62,6 +62,7 @@
 function usb_simtrace_protocol.init()
 local usb_product_dissectors = DissectorTable.get("usb.product")
 usb_product_dissectors:add(0x1d50616d, usb_simtrace_protocol)
+usb_product_dissectors:add(0x1d50616e, usb_simtrace_protocol)
 
 -- DissectorTable.get("usb.bulk"):add(0xffff, usb_simtrace_protocol)
 end
diff --git a/firmware/apps/cardem/main.c b/firmware/apps/cardem/main.c
index a30a211..95967ba 100644
--- a/firmware/apps/cardem/main.c
+++ b/firmware/apps/cardem/main.c
@@ -71,8 +71,13 @@
 		.init = mode_cardemu_init,
 		.exit = mode_cardemu_exit,
 		.run = mode_cardemu_run,
+#if defined (ngff_cardem)
+		.usart0_irq = mode_cardemu_usart1_irq,
+		.usart1_irq = mode_cardemu_usart0_irq,
+#else
 		.usart0_irq = mode_cardemu_usart0_irq,
 		.usart1_irq = mode_cardemu_usart1_irq,
+#endif
 	},
 #endif
 #ifdef HAVE_MITM
diff --git a/firmware/libboard/ngff_cardem/include/board.h b/firmware/libboard/ngff_cardem/include/board.h
new file mode 100644
index 0000000..8be7b7f
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/board.h
@@ -0,0 +1,166 @@
+/* Osmocom ngff-cardem board definition
+ *
+ * (C) 2021 by Harald Welte <laforge at osmocom.org>
+ *
+ * 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
+ */
+#pragma once
+#include "board_common.h"
+#include "simtrace_usb.h"
+
+/** Name of the board */
+#define BOARD_NAME "NGFF-CARDEM"
+/** Board definition */
+#define ngff_cardem
+
+/** oscillator used as main clock source (in Hz) */
+#define BOARD_MAINOSC 12000000
+/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
+#define BOARD_MCK 58000000 // 12.000 * 29 / 6
+
+/** MCU pin connected to red LED */
+#define PIO_LED_RED     PIO_PA17
+/** MCU pin connected to green LED */
+#define PIO_LED_GREEN   PIO_PA18
+/** red LED pin definition */
+#define PIN_LED_RED     {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/** green LED pin definition */
+#define PIN_LED_GREEN   {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+/** LEDs pin definition */
+#define PINS_LEDS       PIN_LED_RED, PIN_LED_GREEN 
+/** index for red LED in LEDs pin definition array */
+#define LED_NUM_RED     0
+/** index for green LED in LEDs pin definition array */
+#define LED_NUM_GREEN   1
+/** the green LED is actually red and used as indication for USIM1 */
+#define LED_USIM1	LED_GREEN
+
+/* USIM 2 interface (USART) */
+#define PIN_USIM2_CLK		{PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_IO		{PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM2	PIN_USIM2_CLK, PIN_USIM2_IO
+
+/* USIM 2 interface (TC) */
+#define PIN_USIM2_IO_TC		{PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_CLK_TC	{PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM2		PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
+
+/* USIM 1 interface (USART) */
+#define PIN_USIM1_IO		{PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_USIM1_CLK		{PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM1	PIN_USIM1_CLK, PIN_USIM1_IO
+
+/* USIM 1 interface (TC) */
+#define PIN_USIM1_IO_TC		{PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM1_CLK_TC	{PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM1		PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
+
+#define PIN_USIM1_nRST		{PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM1_VCC		{PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PIN_USIM2_nRST		{PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+//#define PIN_USIM2_VCC		{PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PINS_USIM1		PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST
+#define PINS_USIM2		PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST
+
+/* from v3 and onwards only (!) */
+#define PIN_DET_USIM1_PRES	{PIO_PA8, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
+
+/* inputs reading the WWAN LED level */
+#define PIN_WWAN1		{PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
+#define PINS_WWAN_IN		{ PIN_WWAN1 }
+
+#define PIN_MODEM_EN {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define PIN_N_MODEM_PWR_ON {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+/* outputs controlling RESET input of modems */
+#define PIN_PERST1		{PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define PINS_PERST		{ PIN_PERST1 }
+
+#define PIN_VERSION_DET		{PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+
+/* GPIO towards SPDT switches between real SIM and SAM3 */
+//#define PIN_SIM_SWITCH1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+//#define PIN_SIM_SWITCH2 {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+#define BOARD_USB_BMATTRIBUTES	USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
+
+#define BOARD_USB_VENDOR_ID	USB_VENDOR_OPENMOKO
+#define BOARD_USB_PRODUCT_ID	USB_PRODUCT_NGFF_CARDEM
+#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_NGFF_CARDEM
+#define BOARD_USB_RELEASE	0x010
+
+#define DETECT_VCC_BY_ADC
+#define VCC_UV_THRESH_1V8	1500000
+#define VCC_UV_THRESH_3V	VCC_UV_THRESH_1V8
+
+#ifdef APPLICATION_cardem
+#define HAVE_CARDEM
+#define HAVE_BOARD_CARDINSERT
+struct cardem_inst;
+void board_set_card_insert(struct cardem_inst *ci, bool card_insert);
+#endif
+
+#ifdef APPLICATION_trace
+#define HAVE_SNIFFER
+#endif
+
+/* Card I/O data signal input/output (I/O_SIM in schematic) */
+#define PIN_SIM_IO             {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/* Card CLK clock input (CLK_SIM in schematic) */
+#define PIN_SIM_CLK            {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+/* Card RST reset signal input (use as input since the phone will drive it) */
+#define PIN_SIM_RST_SNIFF      {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
+/* Pins used to sniff phone-card communication */
+#define PINS_SIM_SNIFF          PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
+
+/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
+#define PIN_SIM_IO_INPUT       {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
+#define PIN_SIM_CLK_INPUT      {PIO_PA4B_TCLK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+/* Pins used to measure ETU timing (using timer counter) */ 
+#define PINS_TC                 PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
+
+//default state: NO uart connected, modem connected to physical sim, NO sim presence override, modem powers sim slot
+#define pin_conn_usim1_default {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_conn_usim2_default {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_conn_mdm_sim_default {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_conn_set_sim_det_default {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_en_st_sim_vdd_default {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_en_mdm_sim_vdd_default {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+//cardem state: uart2 (!) connected, NO modem connected to physical sim, sim presence override, NOTHING powers sim slot
+#define pin_conn_usim1_cem {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_conn_usim2_cem {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_conn_mdm_sim_cem {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_en_st_sim_vdd_cem {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_en_mdm_sim_vdd_cem {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+//trace state: uart2 (!) connected, modem connected to physical sim, st powers sim slot
+#define pin_conn_usim1_trace {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_conn_usim2_trace {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_conn_mdm_sim_trace {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define pin_conn_set_sim_det_trace {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_en_st_sim_vdd_trace {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_1, PIO_DEFAULT}
+#define pin_en_mdm_sim_vdd_trace {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+#define PIN_MODEM_EN_off {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+#define PINS_SIM_DEFAULT pin_conn_usim1_default, pin_conn_usim2_default, pin_conn_mdm_sim_default, pin_conn_set_sim_det_default, PIN_N_MODEM_PWR_ON, PIN_MODEM_EN, pin_en_st_sim_vdd_default, pin_en_mdm_sim_vdd_default
+#define PINS_SIM_CARDEM pin_conn_usim1_cem, pin_conn_usim2_cem, pin_conn_mdm_sim_cem, pin_en_mdm_sim_vdd_cem, pin_en_st_sim_vdd_cem// , pin_conn_set_sim_det_cem
+
+#define PINS_BUS_SNIFF pin_conn_usim1_trace, pin_conn_usim2_trace, pin_conn_mdm_sim_trace, pin_conn_set_sim_det_trace,PIN_MODEM_EN_off
+#define PINS_PWR_SNIFF PIN_N_MODEM_PWR_ON, PIN_MODEM_EN, pin_en_st_sim_vdd_trace, pin_en_mdm_sim_vdd_trace
diff --git a/firmware/libboard/ngff_cardem/include/card_pres.h b/firmware/libboard/ngff_cardem/include/card_pres.h
new file mode 100644
index 0000000..81f0613
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/card_pres.h
@@ -0,0 +1,22 @@
+/* card presence utilities
+ *
+ * (C) 2016-2017 by Harald Welte <hwelte at 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
+ */
+#pragma once
+
+int is_card_present(int port);
+int card_present_init(void);
diff --git a/firmware/libboard/ngff_cardem/include/wwan_led.h b/firmware/libboard/ngff_cardem/include/wwan_led.h
new file mode 100644
index 0000000..77887c7
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/wwan_led.h
@@ -0,0 +1,20 @@
+/* Code to read/track the status of the WWAN LEDs of attached modems
+ * 
+ * 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
+ */
+#pragma once
+
+int wwan_led_active(int wwan);
+int wwan_led_init(void);
diff --git a/firmware/libboard/ngff_cardem/include/wwan_perst.h b/firmware/libboard/ngff_cardem/include/wwan_perst.h
new file mode 100644
index 0000000..c934afc
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/include/wwan_perst.h
@@ -0,0 +1,21 @@
+/* Code to control the PERST lines of attached modems
+ *
+ * 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
+ */
+#pragma once
+
+int wwan_perst_set(int modem_nr, int active);
+int wwan_perst_do_reset_pulse(int modem_nr, unsigned int duration_ms);
+int wwan_perst_init(void);
diff --git a/firmware/libboard/ngff_cardem/product_string.txt b/firmware/libboard/ngff_cardem/product_string.txt
new file mode 100644
index 0000000..09a33c6
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/product_string.txt
@@ -0,0 +1 @@
+ngff-cardem
diff --git a/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c b/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
new file mode 100644
index 0000000..0ac9cd8
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
@@ -0,0 +1,159 @@
+/* sysmocom ngff-cardem application code
+ *
+ * (C) 2021 Harald Welte <laforge at osmocom.org>
+ *
+ * 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 "board.h"
+#include "simtrace.h"
+#include "utils.h"
+#include "led.h"
+#include "wwan_led.h"
+#include "wwan_perst.h"
+#include "sim_switch.h"
+#include "boardver_adc.h"
+#include "card_pres.h"
+#include <osmocom/core/timer.h>
+#include "usb_buf.h"
+
+/* array of generated USB Strings */
+extern unsigned char *usb_strings[];
+
+/* returns '1' in case we should break any endless loop */
+void board_exec_dbg_cmd(int ch)
+{
+	switch (ch) {
+	case '?':
+		printf("\t?\thelp\n\r");
+		printf("\tR\treset SAM3\n\r");
+		printf("\tl\tswitch off LED 1\n\r");
+		printf("\tL\tswitch on  LED 1\n\r");
+		printf("\tg\tswitch off LED 2\n\r");
+		printf("\tG\tswitch on  LED 2\n\r");
+		printf("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
+		printf("\t!\tSwitch Channel A from physical -> remote\n\r");
+		printf("\tt\t(pseudo)talloc report\n\r");
+		break;
+	case 'R':
+		printf("Asking NVIC to reset us\n\r");
+		USBD_Disconnect();
+		NVIC_SystemReset();
+		break;
+	case 'l':
+		led_blink(LED_GREEN, BLINK_ALWAYS_OFF);
+		printf("LED 1 switched off\n\r");
+		break;
+	case 'L':
+		led_blink(LED_GREEN, BLINK_ALWAYS_ON);
+		printf("LED 1 switched on\n\r");
+		break;
+	case 'g':
+		led_blink(LED_RED, BLINK_ALWAYS_OFF);
+		printf("LED 2 switched off\n\r");
+		break;
+	case 'G':
+		led_blink(LED_RED, BLINK_ALWAYS_ON);
+		printf("LED 2 switched on\n\r");
+		break;
+	case '1':
+		printf("Resetting Modem\n\r");
+		wwan_perst_do_reset_pulse(0, 300);
+		break;
+	case '!':
+		sim_switch_use_physical(0, 0);
+		break;
+	case 't':
+		talloc_report(NULL, stdout);
+		break;
+	default:
+		printf("Unknown command '%c'\n\r", ch);
+		break;
+	}
+}
+
+void board_main_top(void)
+{
+#ifndef APPLICATION_dfu
+	usb_buf_init();
+
+	wwan_led_init();
+	wwan_perst_init();
+	sim_switch_init();
+#endif
+
+	/* Obtain the circuit board version (currently just prints voltage) */
+	get_board_version_adc();
+#ifndef APPLICATION_dfu
+	/* Initialize checking for card insert/remove events */
+	card_present_init();
+#endif
+	wwan_perst_set(0, 0);
+}
+
+static int uart_has_loopback_jumper(void)
+{
+	unsigned int i;
+	const Pin uart_loopback_pins[] = {
+		{PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT},
+		{PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+	};
+
+	/* Configure UART pins as I/O */
+	PIO_Configure(uart_loopback_pins, PIO_LISTSIZE(uart_loopback_pins));
+
+	/* Send pattern over UART TX and check if it is received on RX
+	 * If the loop doesn't get interrupted, RxD always follows TxD and thus a
+	 * loopback jumper has been placed on RxD/TxD, and we will boot
+	 * into DFU unconditionally
+	 */
+	int has_loopback_jumper = 1;
+	for (i = 0; i < 10; i++) {
+		/* Set TxD high; abort if RxD doesn't go high either */
+		PIO_Set(&uart_loopback_pins[1]);
+		if (!PIO_Get(&uart_loopback_pins[0])) {
+			has_loopback_jumper = 0;
+			break;
+		}
+		/* Set TxD low, abort if RxD doesn't go low either */
+		PIO_Clear(&uart_loopback_pins[1]);
+		if (PIO_Get(&uart_loopback_pins[0])) {
+			has_loopback_jumper = 0;
+			break;
+		}
+	}
+
+	/* Put pins back to UART mode */
+	const Pin uart_pins[] = {PINS_UART};
+	PIO_Configure(uart_pins, PIO_LISTSIZE(uart_pins));
+
+	return has_loopback_jumper;
+}
+
+int board_override_enter_dfu(void)
+{
+	/* If the loopback jumper is set, we enter DFU mode */
+	if (uart_has_loopback_jumper())
+		return 1;
+
+	return 0;
+}
+
+ static const Pin deton = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
+ static const Pin detoff = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT};
+
+void board_set_card_insert(struct cardem_inst *ci, bool card_insert)
+{
+	PIO_Configure(card_insert ? &deton : &detoff, 1);
+}
\ No newline at end of file
diff --git a/firmware/libboard/ngff_cardem/source/card_pres.c b/firmware/libboard/ngff_cardem/source/card_pres.c
new file mode 100644
index 0000000..7d6c483
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/card_pres.c
@@ -0,0 +1,76 @@
+/* card presence utilities
+ *
+ * (C) 2016-2021 by Harald Welte <hwelte at 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 <osmocom/core/timer.h>
+#include "board.h"
+#include "utils.h"
+#include "card_pres.h"
+
+#define NUM_CARDPRES	1
+
+#define TIMER_INTERVAL_MS	500
+
+static const Pin pin_cardpres[NUM_CARDPRES] = { PIN_DET_USIM1_PRES };
+static int last_state[NUM_CARDPRES] = { -1 };
+static struct osmo_timer_list cardpres_timer;
+
+/* Determine if a SIM card is present in the given slot */
+int is_card_present(int port)
+{
+	const Pin *pin;
+	int present;
+
+	if (port < 0 || port >= NUM_CARDPRES)
+		return -1;
+	pin = &pin_cardpres[port];
+
+
+	/* high active here */
+	present = PIO_Get(pin);
+
+	return present;
+}
+
+static void cardpres_tmr_cb(void *data)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(pin_cardpres); i++) {
+		int state = is_card_present(i);
+		if (state != last_state[i]) {
+			TRACE_INFO("%u: Card Detect Status %d -> %d\r\n", i, last_state[i], state);
+			/* FIXME: report to USB host */
+			last_state[i] = state;
+		}
+	}
+
+	osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
+}
+
+int card_present_init(void)
+{
+	unsigned int i;
+
+	PIO_Configure(pin_cardpres, ARRAY_SIZE(pin_cardpres));
+
+	/* start timer */
+	cardpres_timer.cb = cardpres_tmr_cb;
+	osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
+
+	return 2;
+}
diff --git a/firmware/libboard/ngff_cardem/source/sim_switch.c b/firmware/libboard/ngff_cardem/source/sim_switch.c
new file mode 100644
index 0000000..eb2d305
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/sim_switch.c
@@ -0,0 +1,81 @@
+/* Code to switch between local (physical) and remote (emulated) SIM
+ *
+ * (C) 2015-2017 by Harald Welte <hwelte at 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 "board.h"
+#include "trace.h"
+#include "led.h"
+#include "sim_switch.h"
+
+//uart12bus	2-20e pa20
+//uart22bus	1-20e pa28
+//usim2bus	1-10e pa0  pivot
+//sim det	2-10e pa13
+
+static const Pin pins_default[]	= {PINS_SIM_DEFAULT};
+static const Pin pins_cem[]	= {PINS_SIM_CARDEM};
+
+static int initialized = 0;
+
+int sim_switch_use_physical(unsigned int nr, int physical)
+{
+	const Pin pin = PIN_MODEM_EN;// PIN_N_MODEM_PWR_ON;
+	enum led led;
+
+	if (!initialized) {
+		TRACE_ERROR("Somebody forgot to call sim_switch_init()\r\n");
+		sim_switch_init();
+	}
+
+	TRACE_INFO("Modem %d: %s SIM\n\r", nr,
+		   physical ? "physical" : "virtual");
+
+	switch (nr) {
+	case 0:
+		led = LED_USIM1;
+		break;
+
+	default:
+		TRACE_ERROR("Invalid SIM%u\n\r", nr);
+		return -1;
+	}
+
+	if (physical) {
+		TRACE_INFO("%u: Use local/physical SIM\r\n", nr);
+		PIO_Configure(pins_default, PIO_LISTSIZE(pins_default));
+		led_blink(led, BLINK_ALWAYS_ON);
+	} else {
+		TRACE_INFO("%u: Use remote/emulated SIM\r\n", nr);
+		PIO_Configure(pins_cem, PIO_LISTSIZE(pins_cem));
+		led_blink(led, BLINK_ALWAYS_OFF);
+	}
+
+	/* just power cycle the modem because this circumvents weird issues with unreliable signals */
+	PIO_Clear(&pin);
+	mdelay(200);
+	PIO_Set(&pin);
+
+
+	return 0;
+}
+
+int sim_switch_init(void)
+{
+	PIO_Configure(pins_default, PIO_LISTSIZE(pins_default));
+	initialized = 1;
+	return 1;
+}
diff --git a/firmware/libboard/ngff_cardem/source/wwan_led.c b/firmware/libboard/ngff_cardem/source/wwan_led.c
new file mode 100644
index 0000000..36eb0ec
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/wwan_led.c
@@ -0,0 +1,93 @@
+/* Code to read/track the status of the WWAN LEDs of attached modems
+ *
+ * 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
+ */
+/* Depending on the board this is running on,  it might be possible
+ * for the controller to read the status of the WWAN LED output lines of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
+ */
+#include "board.h"
+#include "wwan_led.h"
+
+#ifdef PIN_WWAN1
+static const Pin pin_wwan1 = PIN_WWAN1;
+
+static void wwan1_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(0);
+
+	TRACE_INFO("0: WWAN LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+#ifdef PIN_WWAN2
+static const Pin pin_wwan2 = PIN_WWAN2;
+
+static void wwan2_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(1);
+	TRACE_INFO("1: WWAN LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+/* determine if a given WWAN led is currently active or not */
+int wwan_led_active(int wwan)
+{
+	const Pin *pin;
+	int active;
+
+	switch (wwan) {
+#ifdef PIN_WWAN1
+	case 0:
+		pin = &pin_wwan1;
+		break;
+#endif
+#ifdef PIN_WWAN2
+	case 1:
+		pin = &pin_wwan2;
+		break;
+#endif
+	default:
+		return -1;
+	}
+
+	active = PIO_Get(pin) ? 0 : 1;
+	return active;
+}
+
+int wwan_led_init(void)
+{
+	int num_leds = 0;
+
+#ifdef PIN_WWAN1
+	PIO_Configure(&pin_wwan1, 1);
+	PIO_ConfigureIt(&pin_wwan1, wwan1_irqhandler);
+	PIO_EnableIt(&pin_wwan1);
+	num_leds++;
+#endif
+
+#ifdef PIN_WWAN2
+	PIO_Configure(&pin_wwan2, 1);
+	PIO_ConfigureIt(&pin_wwan2, wwan2_irqhandler);
+	PIO_EnableIt(&pin_wwan2);
+	num_leds++;
+#endif
+	return num_leds;
+}
diff --git a/firmware/libboard/ngff_cardem/source/wwan_perst.c b/firmware/libboard/ngff_cardem/source/wwan_perst.c
new file mode 100644
index 0000000..95a7c7b
--- /dev/null
+++ b/firmware/libboard/ngff_cardem/source/wwan_perst.c
@@ -0,0 +1,127 @@
+/* Code to control the PERST lines of attached modems
+ *
+ * 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
+ */
+/* Depending on the board this is running on,  it might be possible
+ * for the controller to set the status of the PERST input line of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
+ */
+#include "board.h"
+#include "trace.h"
+#include "wwan_perst.h"
+#include <osmocom/core/timer.h>
+
+struct wwan_perst {
+	uint8_t idx;
+	const Pin pin;
+	struct osmo_timer_list timer;
+};
+
+#ifdef PIN_PERST1
+static struct wwan_perst perst1 = {
+	.idx = 0,
+	.pin = PIN_PERST1,
+};
+#endif
+
+#ifdef PIN_PERST2
+static struct wwan_perst perst2 = {
+	.idx = 1,
+	.pin = PIN_PERST2,
+};
+#endif
+
+static int initialized = 0;
+
+static void perst_tmr_cb(void *data)
+{
+	struct wwan_perst *perst = data;
+	/* release the (low-active) reset */
+	TRACE_INFO("%u: De-asserting modem reset\r\n", perst->idx);
+	PIO_Clear(&perst->pin);
+}
+
+static struct wwan_perst *get_perst_for_modem(int modem_nr)
+{
+	if (!initialized) {
+		TRACE_ERROR("Somebody forgot to call wwan_perst_init()\r\n");
+		wwan_perst_init();
+	}
+
+	switch (modem_nr) {
+#ifdef PIN_PERST1
+	case 0:
+		return &perst1;
+#endif
+#ifdef PIN_PERST2
+	case 1:
+		return &perst2;
+#endif
+	default:
+		return NULL;
+	}
+}
+
+int wwan_perst_do_reset_pulse(int modem_nr, unsigned int duration_ms)
+{
+	struct wwan_perst *perst = get_perst_for_modem(modem_nr);
+	if (!perst)
+		return -1;
+
+	TRACE_INFO("%u: Asserting modem reset\r\n", modem_nr);
+	PIO_Set(&perst->pin);
+	osmo_timer_schedule(&perst->timer, duration_ms/1000, (duration_ms%1000)*1000);
+
+	return 0;
+}
+
+int wwan_perst_set(int modem_nr, int active)
+{
+	struct wwan_perst *perst = get_perst_for_modem(modem_nr);
+	if (!perst)
+		return -1;
+
+	osmo_timer_del(&perst->timer);
+	if (active) {
+		TRACE_INFO("%u: Asserting modem reset\r\n", modem_nr);
+		PIO_Set(&perst->pin);
+	} else {
+		TRACE_INFO("%u: De-asserting modem reset\r\n", modem_nr);
+		PIO_Clear(&perst->pin);
+	}
+
+	return 0;
+}
+
+int wwan_perst_init(void)
+{
+	int num_perst = 0;
+#ifdef PIN_PERST1
+	PIO_Configure(&perst1.pin, 1);
+	perst1.timer.cb = perst_tmr_cb;
+	perst1.timer.data = (void *) &perst1;
+	num_perst++;
+#endif
+
+#ifdef PIN_PERST2
+	PIO_Configure(&perst2.pin, 1);
+	perst2.timer.cb = perst_tmr_cb;
+	perst2.timer.data = (void *) &perst2;
+	num_perst++;
+#endif
+	initialized = 1;
+	return num_perst;
+}
diff --git a/firmware/libboard/simtrace/include/board.h b/firmware/libboard/simtrace/include/board.h
index 4b6eda2..be18f64 100644
--- a/firmware/libboard/simtrace/include/board.h
+++ b/firmware/libboard/simtrace/include/board.h
@@ -40,7 +40,7 @@
 /** green LED pin definition */
 #define PIN_LED_GREEN   {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
 /** LEDs pin definition */
-#define PINS_LEDS       PIN_LED_RED, PIN_LED_GREEN 
+#define PINS_LEDS       PIN_LED_RED, PIN_LED_GREEN
 /** index for red LED in LEDs pin definition array */
 #define LED_NUM_RED     0
 /** index for green LED in LEDs pin definition array */
diff --git a/firmware/libcommon/include/simtrace_usb.h b/firmware/libcommon/include/simtrace_usb.h
index a232ac5..7bf401c 100644
--- a/firmware/libcommon/include/simtrace_usb.h
+++ b/firmware/libcommon/include/simtrace_usb.h
@@ -26,6 +26,7 @@
 #define USB_PRODUCT_SIMTRACE2_DFU	0x60e3	/* was 0x60e2 */
 #define USB_PRODUCT_SIMTRACE2		0x60e3
 #define USB_PRODUCT_OCTSIMTEST		0x616d
+#define USB_PRODUCT_NGFF_CARDEM		0x616e
 
 /* USB proprietary class */
 #define USB_CLASS_PROPRIETARY			0xff
diff --git a/firmware/libcommon/source/mode_cardemu.c b/firmware/libcommon/source/mode_cardemu.c
index 2440ec5..4a0b862 100644
--- a/firmware/libcommon/source/mode_cardemu.c
+++ b/firmware/libcommon/source/mode_cardemu.c
@@ -39,9 +39,21 @@
 #endif
 
 /* UART pins */
+#if defined(ngff_cardem)
+static const Pin pins_usim1[]	= {PINS_USIM2};
+static const Pin pin_usim1_rst	= PIN_USIM2_nRST;
+#define FIRST_USART_BASE USART0
+#define FIRST_USART_ID ID_USART0
+#define FIRST_USART_IRQ USART0_IRQn
+#else
 static const Pin pins_usim1[]	= {PINS_USIM1};
 static const Pin pin_usim1_rst	= PIN_USIM1_nRST;
+#define FIRST_USART_BASE USART1
+#define FIRST_USART_ID ID_USART1
+#define FIRST_USART_IRQ USART1_IRQn
+#endif
 static const Pin pin_usim1_vcc	= PIN_USIM1_VCC;
+
 #ifdef PIN_USIM1_IO_DIR
 static const Pin pin_io_dir 	= PIN_USIM1_IO_DIR;
 #endif
@@ -85,8 +97,8 @@
 	{
 		.num = 0,
 		.usart_info = 	{
-			.base = USART1,
-			.id = ID_USART1,
+			.base = FIRST_USART_BASE,
+			.id = FIRST_USART_ID,
 			.state = USART_RCV
 		},
 		.ep_out = SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT,
@@ -569,7 +581,7 @@
 
 	/* configure USART as ISO-7816 slave (e.g. card) */
 	ISO7816_Init(&cardem_inst[0].usart_info, CLK_SLAVE);
-	NVIC_EnableIRQ(USART1_IRQn);
+	NVIC_EnableIRQ(FIRST_USART_IRQ);
 	PIO_ConfigureIt(&pin_usim1_rst, usim1_rst_irqhandler);
 	PIO_EnableIt(&pin_usim1_rst);
 
@@ -627,9 +639,9 @@
 	PIO_DisableIt(&pin_usim1_rst);
 	PIO_DisableIt(&pin_usim1_vcc);
 
-	NVIC_DisableIRQ(USART1_IRQn);
-	USART_SetTransmitterEnabled(USART1, 0);
-	USART_SetReceiverEnabled(USART1, 0);
+	NVIC_DisableIRQ(FIRST_USART_IRQ);
+	USART_SetTransmitterEnabled(FIRST_USART_BASE, 0);
+	USART_SetReceiverEnabled(FIRST_USART_BASE, 0);
 
 #ifdef CARDEMU_SECOND_UART
 	PIO_DisableIt(&pin_usim2_rst);
diff --git a/host/contrib/99-simtrace2.rules b/host/contrib/99-simtrace2.rules
index b576389..5ae04e2 100644
--- a/host/contrib/99-simtrace2.rules
+++ b/host/contrib/99-simtrace2.rules
@@ -18,6 +18,8 @@
 ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4004", GROUP="plugdev"
 # sysmocom OCTSIMTEST
 ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="616d", GROUP="plugdev"
+# ngff-cardem
+ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="616e", GROUP="plugdev"
 
 # All done
 LABEL="simtrace2_rules_end"
diff --git a/host/lib/usb_util.c b/host/lib/usb_util.c
index 4d3b2b9..872d185 100644
--- a/host/lib/usb_util.c
+++ b/host/lib/usb_util.c
@@ -33,5 +33,6 @@
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_QMOD_SAM3 },
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
+	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
 	{ 0, 0 }
 };
diff --git a/host/src/simtrace2-sniff.c b/host/src/simtrace2-sniff.c
index 47d9e77..c44029a 100644
--- a/host/src/simtrace2-sniff.c
+++ b/host/src/simtrace2-sniff.c
@@ -315,6 +315,7 @@
 /* Known USB device with SIMtrace firmware supporting sniffer */
 static const struct dev_id compatible_dev_ids[] = {
 	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
+	{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
 	{ 0, 0 }
 };
 

-- 
To view, visit https://gerrit.osmocom.org/c/simtrace2/+/25082
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: Ia96124fbe8a752c98e7fd4096d542a3b2b9bc255
Gerrit-Change-Number: 25082
Gerrit-PatchSet: 8
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210802/834d39d0/attachment.htm>


More information about the gerrit-log mailing list