/* SIMtrace2 USB protocol * * (C) 2015-2017 by Harald Welte * (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon * * 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 #include /*********************************************************************** * 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, /* Reader/phone-car/SIM communication sniff */ SIMTRACE_MSGC_SNIFF, /* 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_SNIFF */ enum simtrace_msg_type_sniff { /* Status change (card inserted, reset, ...) */ SIMTRACE_MSGT_SNIFF_CHANGE = 0, /* Fi/Di baudrate change */ SIMTRACE_MSGT_SNIFF_FIDI, /* ATR data */ SIMTRACE_MSGT_SNIFF_ATR, /* PPS (request or response) data */ SIMTRACE_MSGT_SNIFF_PPS, /* TPDU data */ SIMTRACE_MSGT_SNIFF_TPDU, }; /* 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)); /*********************************************************************** * Capabilities ***********************************************************************/ /* 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 sysmocom 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: pulse 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)); /*********************************************************************** * SNIFF ***********************************************************************/ /* SIMTRACE_MSGT_SNIFF_CHANGE flags */ #define SNIFF_CHANGE_FLAG_CARD_INSERT (1<<0) #define SNIFF_CHANGE_FLAG_CARD_EJECT (1<<1) #define SNIFF_CHANGE_FLAG_RESET_ASSERT (1<<2) #define SNIFF_CHANGE_FLAG_RESET_DEASSERT (1<<3) #define SNIFF_CHANGE_FLAG_TIMEOUT_WT (1<<4) /* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU flags */ #define SNIFF_DATA_FLAG_ERROR_INCOMPLETE (1<<5) #define SNIFF_DATA_FLAG_ERROR_MALFORMED (1<<6) #define SNIFF_DATA_FLAG_ERROR_CHECKSUM (1<<7) /* SIMTRACE_MSGT_SNIFF_CHANGE */ struct sniff_change { /* SIMTRACE_MSGT_SNIFF_CHANGE flags */ uint32_t flags; } __attribute__ ((packed)); /* SIMTRACE_MSGT_SNIFF_FIDI */ struct sniff_fidi { /* Fi/Di values as encoded in TA1 */ uint8_t fidi; } __attribute__ ((packed)); /* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU */ struct sniff_data { /* data flags */ uint32_t flags; /* data length */ uint16_t length; /* data */ uint8_t data[0]; } __attribute__ ((packed));