mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-17 13:48:32 +03:00
Compare commits
4 Commits
lynxis/pre
...
laforge/ng
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
774330d413 | ||
|
|
9d0d20c253 | ||
|
|
f7b7f41d2f | ||
|
|
07f94342be |
@@ -27,7 +27,9 @@ class Device(NamedTuple):
|
||||
DEVICE_SIMTRACE = Device(usb_vendor_id=0x1d50, usb_product_id=0x60e3, name="SIMtrace 2", url={"trace": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/simtrace-trace-dfu-latest.bin", "cardem": "https://osmocom.org/attachments/download/3868/simtrace-cardem-dfu.bin"})
|
||||
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"})
|
||||
DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD]
|
||||
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"})
|
||||
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"}
|
||||
|
||||
@@ -62,6 +62,7 @@ end
|
||||
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
|
||||
|
||||
107
firmware/libboard/ngff_cardem/include/board.h
Normal file
107
firmware/libboard/ngff_cardem/include/board.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* Osmocom ngff-cardem board definition
|
||||
*
|
||||
* (C) 2021 by Harald Welte <laforge@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_PB2, 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_PULLUP | 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 }
|
||||
|
||||
/* outputs controlling RESET input of modems */
|
||||
#define PIN_PERST1 {PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_PULLUP}
|
||||
#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 2500000
|
||||
|
||||
#define HAVE_CARDEM
|
||||
22
firmware/libboard/ngff_cardem/include/card_pres.h
Normal file
22
firmware/libboard/ngff_cardem/include/card_pres.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* card presence utilities
|
||||
*
|
||||
* (C) 2016-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
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
int is_card_present(int port);
|
||||
int card_present_init(void);
|
||||
20
firmware/libboard/ngff_cardem/include/wwan_led.h
Normal file
20
firmware/libboard/ngff_cardem/include/wwan_led.h
Normal file
@@ -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);
|
||||
21
firmware/libboard/ngff_cardem/include/wwan_perst.h
Normal file
21
firmware/libboard/ngff_cardem/include/wwan_perst.h
Normal file
@@ -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);
|
||||
1
firmware/libboard/ngff_cardem/product_string.txt
Normal file
1
firmware/libboard/ngff_cardem/product_string.txt
Normal file
@@ -0,0 +1 @@
|
||||
ngff-cardem
|
||||
152
firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
Normal file
152
firmware/libboard/ngff_cardem/source/board_ngff_cardem.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* sysmocom quad-modem sysmoQMOD application code
|
||||
*
|
||||
* (C) 2021 Harald Welte <laforge@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("\tU\tProceed to USB Initialization\n\r");
|
||||
printf("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
|
||||
printf("\t!\tSwitch Channel A from physical -> remote\n\r");
|
||||
printf("\t@\tSwitch Channel B 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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
76
firmware/libboard/ngff_cardem/source/card_pres.c
Normal file
76
firmware/libboard/ngff_cardem/source/card_pres.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/* card presence utilities
|
||||
*
|
||||
* (C) 2016-2021 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 <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];
|
||||
|
||||
/* Card present signals are low-active, as we have a switch
|
||||
* against GND and an internal-pull-up in the SAM3 */
|
||||
present = PIO_Get(pin) ? 0 : 1;
|
||||
|
||||
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;
|
||||
}
|
||||
90
firmware/libboard/ngff_cardem/source/sim_switch.c
Normal file
90
firmware/libboard/ngff_cardem/source/sim_switch.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Code to switch between local (physical) and remote (emulated) SIM
|
||||
*
|
||||
* (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
|
||||
*/
|
||||
#include "board.h"
|
||||
#include "trace.h"
|
||||
#include "led.h"
|
||||
#include "sim_switch.h"
|
||||
|
||||
#ifdef PIN_SIM_SWITCH1
|
||||
static const Pin pin_conn_usim1 = {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||
#endif
|
||||
#ifdef PIN_SIM_SWITCH2
|
||||
static const Pin pin_conn_usim2 = {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||
#endif
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
int sim_switch_use_physical(unsigned int nr, int physical)
|
||||
{
|
||||
const Pin *pin;
|
||||
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) {
|
||||
#ifdef PIN_SIM_SWITCH1
|
||||
case 0:
|
||||
pin = &pin_conn_usim1;
|
||||
led = LED_USIM1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef PIN_SIM_SWITCH2
|
||||
case 1:
|
||||
pin = &pin_conn_usim2;
|
||||
led = LED_USIM2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
TRACE_ERROR("Invalid SIM%u\n\r", nr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (physical) {
|
||||
TRACE_INFO("%u: Use local/physical SIM\r\n", nr);
|
||||
PIO_Clear(pin);
|
||||
led_blink(led, BLINK_ALWAYS_ON);
|
||||
} else {
|
||||
TRACE_INFO("%u: Use remote/emulated SIM\r\n", nr);
|
||||
PIO_Set(pin);
|
||||
led_blink(led, BLINK_ALWAYS_OFF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sim_switch_init(void)
|
||||
{
|
||||
int num_switch = 0;
|
||||
#ifdef PIN_SIM_SWITCH1
|
||||
PIO_Configure(&pin_conn_usim1, 1);
|
||||
num_switch++;
|
||||
#endif
|
||||
#ifdef PIN_SIM_SWITCH2
|
||||
PIO_Configure(&pin_conn_usim2, 1);
|
||||
num_switch++;
|
||||
#endif
|
||||
initialized = 1;
|
||||
return num_switch;
|
||||
}
|
||||
93
firmware/libboard/ngff_cardem/source/wwan_led.c
Normal file
93
firmware/libboard/ngff_cardem/source/wwan_led.c
Normal file
@@ -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 tiven 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;
|
||||
}
|
||||
127
firmware/libboard/ngff_cardem/source/wwan_perst.c
Normal file
127
firmware/libboard/ngff_cardem/source/wwan_perst.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,10 @@ ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4002", GROUP="plugdev"
|
||||
# sysmocom QMOD SAM3 (DFU and runtime)
|
||||
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4003", GROUP="plugdev"
|
||||
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"
|
||||
|
||||
@@ -33,5 +33,6 @@ const struct dev_id osmo_st2_compatible_dev_ids[] = {
|
||||
{ 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 }
|
||||
};
|
||||
|
||||
@@ -5,10 +5,12 @@ AM_LDFLAGS=$(COVERAGE_LDFLAGS)
|
||||
LDADD= $(top_builddir)/lib/libosmo-simtrace2.la \
|
||||
$(LIBOSMOCORE_LIBS) $(LIBOSMOSIM_LIBS) $(LIBOSMOUSB_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
bin_PROGRAMS = simtrace2-cardem-pcsc simtrace2-list simtrace2-sniff
|
||||
bin_PROGRAMS = simtrace2-cardem-pcsc simtrace2-list simtrace2-sniff simtrace2-tool
|
||||
|
||||
simtrace2_cardem_pcsc_SOURCES = simtrace2-cardem-pcsc.c
|
||||
|
||||
simtrace2_list_SOURCES = simtrace2_usb.c
|
||||
|
||||
simtrace2_sniff_SOURCES = simtrace2-sniff.c
|
||||
|
||||
simtrace2_tool_SOURCES = simtrace2-tool.c
|
||||
|
||||
338
host/src/simtrace2-tool.c
Normal file
338
host/src/simtrace2-tool.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/* simtrace2-tool - main program for the host PC to provide a remote SIM
|
||||
* using the SIMtrace 2 firmware in card emulation mode
|
||||
*
|
||||
* (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include <osmocom/usb/libusb.h>
|
||||
#include <osmocom/simtrace2/simtrace2_api.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include <osmocom/simtrace2/gsmtap.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
/***********************************************************************
|
||||
* Incoming Messages
|
||||
***********************************************************************/
|
||||
|
||||
static void print_welcome(void)
|
||||
{
|
||||
printf("simtrace2-tool\n"
|
||||
"(C) 2019 Harald Welte <laforge@gnumonks.org>\n");
|
||||
}
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
printf( "simtrace2-tool [OPTIONS] COMMAND\n\n");
|
||||
printf( "Options:\n"
|
||||
"\t-h\t--help\n"
|
||||
"\t-V\t--usb-vendor\tVENDOR_ID\n"
|
||||
"\t-P\t--usb-product\tPRODUCT_ID\n"
|
||||
"\t-C\t--usb-config\tCONFIG_ID\n"
|
||||
"\t-I\t--usb-interface\tINTERFACE_ID\n"
|
||||
"\t-S\t--usb-altsetting ALTSETTING_ID\n"
|
||||
"\t-A\t--usb-address\tADDRESS\n"
|
||||
"\t-H\t--usb-path\tPATH\n"
|
||||
"\n"
|
||||
);
|
||||
printf( "Commands:\n"
|
||||
"\tmodem reset (enable|disable|cycle)\n"
|
||||
"\tmodem sim-switch (local|remote)\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static const struct option opts[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "usb-vendor", 1, 0, 'V' },
|
||||
{ "usb-product", 1, 0, 'P' },
|
||||
{ "usb-config", 1, 0, 'C' },
|
||||
{ "usb-interface", 1, 0, 'I' },
|
||||
{ "usb-altsetting", 1, 0, 'S' },
|
||||
{ "usb-address", 1, 0, 'A' },
|
||||
{ "usb-path", 1, 0, 'H' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void run_mainloop(struct osmo_st2_cardem_inst *ci)
|
||||
{
|
||||
struct osmo_st2_transport *transp = ci->slot->transp;
|
||||
uint8_t buf[16*265];
|
||||
int xfer_len;
|
||||
int rc;
|
||||
|
||||
while (1) {
|
||||
/* read data from SIMtrace2 device */
|
||||
rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.in,
|
||||
buf, sizeof(buf), &xfer_len, 100);
|
||||
if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT &&
|
||||
rc != LIBUSB_ERROR_INTERRUPTED &&
|
||||
rc != LIBUSB_ERROR_IO) {
|
||||
fprintf(stderr, "BULK IN transfer error; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
/* break the loop if no new messages arrive within 100ms */
|
||||
if (rc == LIBUSB_ERROR_TIMEOUT)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static struct osmo_st2_transport _transp;
|
||||
|
||||
static struct osmo_st2_slot _slot = {
|
||||
.transp = &_transp,
|
||||
.slot_nr = 0,
|
||||
};
|
||||
|
||||
struct osmo_st2_cardem_inst _ci = {
|
||||
.slot = &_slot,
|
||||
};
|
||||
|
||||
struct osmo_st2_cardem_inst *ci = &_ci;
|
||||
|
||||
/* perform a modem reset */
|
||||
static int do_modem_reset(int argc, char **argv)
|
||||
{
|
||||
char *command;
|
||||
if (argc < 1)
|
||||
command = "cycle";
|
||||
else {
|
||||
command = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!strcmp(command, "enable")) {
|
||||
printf("Activating Modem RESET\n");
|
||||
return osmo_st2_modem_reset_active(ci->slot);
|
||||
} else if (!strcmp(command, "disable")) {
|
||||
printf("Deactivating Modem RESET\n");
|
||||
return osmo_st2_modem_reset_inactive(ci->slot);
|
||||
} else if (!strcmp(command, "cycle")) {
|
||||
printf("Pulsing Modem RESET (1s)\n");
|
||||
return osmo_st2_modem_reset_pulse(ci->slot, 1000);
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported modem reset command: '%s'\n", command);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* switch between local and remote (emulated) SIM */
|
||||
static int do_modem_sim_switch(int argc, char **argv)
|
||||
{
|
||||
char *command;
|
||||
if (argc < 1)
|
||||
return -EINVAL;
|
||||
command = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (!strcmp(command, "local")) {
|
||||
printf("Setting SIM=LOCAL; Modem reset recommended\n");
|
||||
return osmo_st2_modem_sim_select_local(ci->slot);
|
||||
} else if (!strcmp(command, "remote")) {
|
||||
printf("Setting SIM=REMOTE; Modem reset recommended\n");
|
||||
return osmo_st2_modem_sim_select_remote(ci->slot);
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported modem sim-switch command: '%s'\n", command);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_subsys_modem(int argc, char **argv)
|
||||
{
|
||||
char *command;
|
||||
int rc;
|
||||
|
||||
if (argc < 1)
|
||||
return -EINVAL;
|
||||
command = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (!strcmp(command, "reset")) {
|
||||
rc = do_modem_reset(argc, argv);
|
||||
} else if (!strcmp(command, "sim-switch")) {
|
||||
rc = do_modem_sim_switch(argc, argv);
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported command for subsystem modem: '%s'\n", command);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int do_command(int argc, char **argv)
|
||||
{
|
||||
char *subsys;
|
||||
int rc;
|
||||
|
||||
if (argc < 1)
|
||||
return -EINVAL;
|
||||
subsys = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (!strcmp(subsys, "modem"))
|
||||
rc = do_subsys_modem(argc, argv);
|
||||
else {
|
||||
fprintf(stderr, "Unsupported subsystem '%s'\n", subsys);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct osmo_st2_transport *transp = ci->slot->transp;
|
||||
int rc;
|
||||
int c, ret = 1;
|
||||
int if_num = 0, vendor_id = -1, product_id = -1;
|
||||
int config_id = -1, altsetting = 0, addr = -1;
|
||||
char *path = NULL;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "hV:P:C:I:S:A:H:", opts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
break;
|
||||
case 'V':
|
||||
vendor_id = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'P':
|
||||
product_id = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'C':
|
||||
config_id = atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
if_num = atoi(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
altsetting = atoi(optarg);
|
||||
break;
|
||||
case 'A':
|
||||
addr = atoi(optarg);
|
||||
break;
|
||||
case 'H':
|
||||
path = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vendor_id < 0 || product_id < 0)) {
|
||||
fprintf(stderr, "You have to specify the vendor and product ID\n");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
transp->udp_fd = -1;
|
||||
|
||||
rc = libusb_init(NULL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "libusb initialization failed\n");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
print_welcome();
|
||||
|
||||
do {
|
||||
if (transp->udp_fd < 0) {
|
||||
struct usb_interface_match _ifm, *ifm = &_ifm;
|
||||
ifm->vendor = vendor_id;
|
||||
ifm->product = product_id;
|
||||
ifm->configuration = config_id;
|
||||
ifm->interface = if_num;
|
||||
ifm->altsetting = altsetting;
|
||||
ifm->addr = addr;
|
||||
if (path)
|
||||
osmo_strlcpy(ifm->path, path, sizeof(ifm->path));
|
||||
transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm);
|
||||
if (!transp->usb_devh) {
|
||||
fprintf(stderr, "can't open USB device\n");
|
||||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = libusb_claim_interface(transp->usb_devh, if_num);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't claim interface %d; rc=%d\n", if_num, rc);
|
||||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = osmo_libusb_get_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out,
|
||||
&transp->usb_ep.in, &transp->usb_ep.irq_in);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);
|
||||
goto close_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind <= 0) {
|
||||
fprintf(stderr, "You have to specify a command to execute\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = do_command(argc-optind, argv+optind);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
break;
|
||||
case -EINVAL:
|
||||
fprintf(stderr, "Error: Invalid command/syntax\n");
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error executing command: %d\n", rc);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
run_mainloop(ci);
|
||||
ret = 0;
|
||||
|
||||
libusb_release_interface(transp->usb_devh, 0);
|
||||
close_exit:
|
||||
if (transp->usb_devh)
|
||||
libusb_close(transp->usb_devh);
|
||||
} while (0);
|
||||
|
||||
libusb_exit(NULL);
|
||||
do_exit:
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user