mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-19 23:08:34 +03:00
Compare commits
10 Commits
laforge/to
...
laforge/ng
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
774330d413 | ||
|
|
9d0d20c253 | ||
|
|
f7b7f41d2f | ||
|
|
07f94342be | ||
|
|
d0c420055d | ||
|
|
3ef40d1ca6 | ||
|
|
dcfea28a4f | ||
|
|
264f615b65 | ||
|
|
017e10e9ef | ||
|
|
f0653533cc |
@@ -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_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_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_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
|
# which firmware does the SIMtrace USN interface subclass correspond
|
||||||
FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
|
FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
|
||||||
|
|||||||
68
contrib/simtrace.lua
Normal file
68
contrib/simtrace.lua
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
usb_simtrace_protocol = Proto("USB_simtrace", "USB simtrace protocol")
|
||||||
|
|
||||||
|
|
||||||
|
local control_commands = {
|
||||||
|
-- /* SIMTRACE_MSGC_GENERIC */
|
||||||
|
[0x0000] = "SIMTRACE_CMD_DO_ERROR",
|
||||||
|
[0x0001] = "SIMTRACE_CMD_BD_BOARD_INFO",
|
||||||
|
|
||||||
|
-- /* SIMTRACE_MSGC_CARDEM */
|
||||||
|
[0x0101] = "SIMTRACE_MSGT_DT_CEMU_TX_DATA",
|
||||||
|
[0x0102] = "SIMTRACE_MSGT_DT_CEMU_SET_ATR",
|
||||||
|
[0x0103] = "SIMTRACE_MSGT_BD_CEMU_STATS",
|
||||||
|
[0x0104] = "SIMTRACE_MSGT_BD_CEMU_STATUS",
|
||||||
|
[0x0105] = "SIMTRACE_MSGT_DT_CEMU_CARDINSERT",
|
||||||
|
[0x0106] = "SIMTRACE_MSGT_DO_CEMU_RX_DATA",
|
||||||
|
[0x0107] = "SIMTRACE_MSGT_DO_CEMU_PTS",
|
||||||
|
[0x0108] = "SIMTRACE_MSGT_BD_CEMU_CONFIG",
|
||||||
|
|
||||||
|
-- /* SIMTRACE_MSGC_MODEM */
|
||||||
|
[0x0201] = "SIMTRACE_MSGT_DT_MODEM_RESET",
|
||||||
|
[0x0202] = "SIMTRACE_MSGT_DT_MODEM_SIM_SELECT",
|
||||||
|
[0x0203] = "SIMTRACE_MSGT_BD_MODEM_STATUS",
|
||||||
|
|
||||||
|
-- /* SIMTRACE_MSGC_SNIFF */
|
||||||
|
[0x0300] = "SIMTRACE_MSGT_SNIFF_CHANGE",
|
||||||
|
[0x0301] = "SIMTRACE_MSGT_SNIFF_FIDI",
|
||||||
|
[0x0302] = "SIMTRACE_MSGT_SNIFF_ATR",
|
||||||
|
[0x0304] = "SIMTRACE_MSGT_SNIFF_TPDU",
|
||||||
|
[0x0303] = "SIMTRACE_MSGT_SNIFF_PPS"
|
||||||
|
}
|
||||||
|
|
||||||
|
local msgtype = ProtoField.uint16("usb_simtrace.msgtype", "Message Type", base.HEX_DEC, control_commands)
|
||||||
|
local seqnr = ProtoField.uint8("usb_simtrace.seqnr", "Sequence Number", base.HEX_DEC)
|
||||||
|
local slotnr = ProtoField.uint8("usb_simtrace.slotnr", "Slot Number", base.HEX_DEC)
|
||||||
|
local reserved = ProtoField.uint16("usb_simtrace.reserved", "reserved", base.HEX_DEC)
|
||||||
|
local payloadlen = ProtoField.uint16("usb_simtrace.length", "length", base.HEX_DEC)
|
||||||
|
local payload = ProtoField.bytes("usb_simtrace.payload", "Data")
|
||||||
|
|
||||||
|
usb_simtrace_protocol.fields = {
|
||||||
|
msgtype, seqnr, slotnr, reserved, payloadlen, payload
|
||||||
|
}
|
||||||
|
|
||||||
|
function usb_simtrace_protocol.dissector(buffer, pinfo, tree)
|
||||||
|
length = buffer:len()
|
||||||
|
if length == 0 then return end
|
||||||
|
|
||||||
|
pinfo.cols.protocol = usb_simtrace_protocol.name
|
||||||
|
|
||||||
|
local subtree = tree:add(usb_simtrace_protocol, buffer(), "USB simtrace Data")
|
||||||
|
local command = buffer(0,2):uint()
|
||||||
|
|
||||||
|
subtree:add(msgtype, command):set_generated()
|
||||||
|
subtree:add(seqnr, buffer(2,1))
|
||||||
|
subtree:add(slotnr, buffer(3,1))
|
||||||
|
subtree:add_le(payloadlen, buffer(6,2))
|
||||||
|
pinfo.cols.info = string.format("Cmd 0x%04X : %s", command, control_commands[command])
|
||||||
|
subtree:add(payload, buffer(8,length-8))
|
||||||
|
|
||||||
|
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_DFU 0x60e3 /* was 0x60e2 */
|
||||||
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
||||||
#define USB_PRODUCT_OCTSIMTEST 0x616d
|
#define USB_PRODUCT_OCTSIMTEST 0x616d
|
||||||
|
#define USB_PRODUCT_NGFF_CARDEM 0x616e
|
||||||
|
|
||||||
/* USB proprietary class */
|
/* USB proprietary class */
|
||||||
#define USB_CLASS_PROPRIETARY 0xff
|
#define USB_CLASS_PROPRIETARY 0xff
|
||||||
|
|||||||
@@ -461,7 +461,11 @@ static int card_vcc_adc_init(void)
|
|||||||
|
|
||||||
static void process_vcc_adc(struct cardem_inst *ci)
|
static void process_vcc_adc(struct cardem_inst *ci)
|
||||||
{
|
{
|
||||||
|
#ifdef octsimtest
|
||||||
|
if (ci->vcc_uv >= VCC_UV_THRESH_1V8)
|
||||||
|
#else
|
||||||
if (ci->vcc_uv >= VCC_UV_THRESH_3V)
|
if (ci->vcc_uv >= VCC_UV_THRESH_3V)
|
||||||
|
#endif
|
||||||
ci->vcc_active = true;
|
ci->vcc_active = true;
|
||||||
else
|
else
|
||||||
ci->vcc_active = false;
|
ci->vcc_active = false;
|
||||||
@@ -705,6 +709,7 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci
|
|||||||
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
|
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
|
||||||
cfg = (struct cardemu_usb_msg_config *) msg->l2h;
|
cfg = (struct cardemu_usb_msg_config *) msg->l2h;
|
||||||
card_emu_set_config(ci->ch, cfg, msgb_l2len(msg));
|
card_emu_set_config(ci->ch, cfg, msgb_l2len(msg));
|
||||||
|
usb_buf_free(msg);
|
||||||
break;
|
break;
|
||||||
case SIMTRACE_MSGT_BD_CEMU_STATS:
|
case SIMTRACE_MSGT_BD_CEMU_STATS:
|
||||||
default:
|
default:
|
||||||
|
|||||||
Binary file not shown.
@@ -16,6 +16,10 @@ ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4002", GROUP="plugdev"
|
|||||||
# sysmocom QMOD SAM3 (DFU and runtime)
|
# sysmocom QMOD SAM3 (DFU and runtime)
|
||||||
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4003", GROUP="plugdev"
|
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4003", GROUP="plugdev"
|
||||||
ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="4004", 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
|
# All done
|
||||||
LABEL="simtrace2_rules_end"
|
LABEL="simtrace2_rules_end"
|
||||||
|
|||||||
@@ -44,9 +44,13 @@
|
|||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
#include <osmocom/core/socket.h>
|
#include <osmocom/core/socket.h>
|
||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
|
#include <osmocom/core/logging.h>
|
||||||
#include <osmocom/sim/class_tables.h>
|
#include <osmocom/sim/class_tables.h>
|
||||||
#include <osmocom/sim/sim.h>
|
#include <osmocom/sim/sim.h>
|
||||||
|
|
||||||
|
#define LOGSLOT(slot, lvl, fmt, args...) \
|
||||||
|
LOGP(DLINP, lvl, "[%u] " fmt, (slot)->slot_nr, ## args)
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SIMTRACE core protocol
|
* SIMTRACE core protocol
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@@ -141,7 +145,6 @@ int osmo_st2_slot_tx_msg(struct osmo_st2_slot *slot, struct msgb *msg,
|
|||||||
OSMO_ASSERT(transp);
|
OSMO_ASSERT(transp);
|
||||||
|
|
||||||
st_push_hdr(msg, msg_class, msg_type, slot->slot_nr);
|
st_push_hdr(msg, msg_class, msg_type, slot->slot_nr);
|
||||||
printf("SIMtrace <- %s\n", msgb_hexdump(msg));
|
|
||||||
|
|
||||||
if (transp->udp_fd < 0) {
|
if (transp->udp_fd < 0) {
|
||||||
if (transp->usb_async)
|
if (transp->usb_async)
|
||||||
@@ -166,6 +169,8 @@ int osmo_st2_cardem_request_card_insert(struct osmo_st2_cardem_inst *ci, bool in
|
|||||||
struct msgb *msg = st_msgb_alloc();
|
struct msgb *msg = st_msgb_alloc();
|
||||||
struct cardemu_usb_msg_cardinsert *cins;
|
struct cardemu_usb_msg_cardinsert *cins;
|
||||||
|
|
||||||
|
LOGSLOT(ci->slot, LOGL_NOTICE, "<= %s(inserted=%d)\n", __func__, inserted);
|
||||||
|
|
||||||
cins = (struct cardemu_usb_msg_cardinsert *) msgb_put(msg, sizeof(*cins));
|
cins = (struct cardemu_usb_msg_cardinsert *) msgb_put(msg, sizeof(*cins));
|
||||||
memset(cins, 0, sizeof(*cins));
|
memset(cins, 0, sizeof(*cins));
|
||||||
if (inserted)
|
if (inserted)
|
||||||
@@ -181,7 +186,7 @@ int osmo_st2_cardem_request_pb_and_rx(struct osmo_st2_cardem_inst *ci, uint8_t p
|
|||||||
struct cardemu_usb_msg_tx_data *txd;
|
struct cardemu_usb_msg_tx_data *txd;
|
||||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||||
|
|
||||||
printf("<= %s(%02x, %d)\n", __func__, pb, le);
|
LOGSLOT(ci->slot, LOGL_DEBUG, "<= %s(pb=%02x, le=%u)\n", __func__, pb, le);
|
||||||
|
|
||||||
memset(txd, 0, sizeof(*txd));
|
memset(txd, 0, sizeof(*txd));
|
||||||
txd->data_len = 1;
|
txd->data_len = 1;
|
||||||
@@ -202,7 +207,7 @@ int osmo_st2_cardem_request_pb_and_tx(struct osmo_st2_cardem_inst *ci, uint8_t p
|
|||||||
|
|
||||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||||
|
|
||||||
printf("<= %s(%02x, %s, %d)\n", __func__, pb,
|
LOGSLOT(ci->slot, LOGL_DEBUG, "<= %s(pb=%02x, tx=%s, len=%d)\n", __func__, pb,
|
||||||
osmo_hexdump(data, data_len_in), data_len_in);
|
osmo_hexdump(data, data_len_in), data_len_in);
|
||||||
|
|
||||||
memset(txd, 0, sizeof(*txd));
|
memset(txd, 0, sizeof(*txd));
|
||||||
@@ -226,7 +231,7 @@ int osmo_st2_cardem_request_sw_tx(struct osmo_st2_cardem_inst *ci, const uint8_t
|
|||||||
|
|
||||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||||
|
|
||||||
printf("<= %s(%02x %02x)\n", __func__, sw[0], sw[1]);
|
LOGSLOT(ci->slot, LOGL_DEBUG, "<= %s(sw=%02x%02x)\n", __func__, sw[0], sw[1]);
|
||||||
|
|
||||||
memset(txd, 0, sizeof(*txd));
|
memset(txd, 0, sizeof(*txd));
|
||||||
txd->data_len = 2;
|
txd->data_len = 2;
|
||||||
@@ -246,7 +251,7 @@ int osmo_st2_cardem_request_set_atr(struct osmo_st2_cardem_inst *ci, const uint8
|
|||||||
|
|
||||||
satr = (struct cardemu_usb_msg_set_atr *) msgb_put(msg, sizeof(*satr));
|
satr = (struct cardemu_usb_msg_set_atr *) msgb_put(msg, sizeof(*satr));
|
||||||
|
|
||||||
printf("<= %s(%s)\n", __func__, osmo_hexdump(atr, atr_len));
|
LOGSLOT(ci->slot, LOGL_NOTICE, "<= %s(%s)\n", __func__, osmo_hexdump(atr, atr_len));
|
||||||
|
|
||||||
memset(satr, 0, sizeof(*satr));
|
memset(satr, 0, sizeof(*satr));
|
||||||
satr->atr_len = atr_len;
|
satr->atr_len = atr_len;
|
||||||
@@ -263,7 +268,7 @@ int osmo_st2_cardem_request_config(struct osmo_st2_cardem_inst *ci, uint32_t fea
|
|||||||
|
|
||||||
cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
|
cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
|
||||||
|
|
||||||
printf("<= %s(%08x)\n", __func__, features);
|
LOGSLOT(ci->slot, LOGL_NOTICE, "<= %s(features=%08x)\n", __func__, features);
|
||||||
|
|
||||||
memset(cfg, 0, sizeof(*cfg));
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
cfg->features = features;
|
cfg->features = features;
|
||||||
@@ -280,6 +285,9 @@ static int _modem_reset(struct osmo_st2_slot *slot, uint8_t asserted, uint16_t p
|
|||||||
struct msgb *msg = st_msgb_alloc();
|
struct msgb *msg = st_msgb_alloc();
|
||||||
struct st_modem_reset *sr ;
|
struct st_modem_reset *sr ;
|
||||||
|
|
||||||
|
LOGSLOT(slot, LOGL_NOTICE, "<= %s(asserted=%u, pulse_ms=%u)\n", __func__,
|
||||||
|
asserted, pulse_ms);
|
||||||
|
|
||||||
sr = (struct st_modem_reset *) msgb_put(msg, sizeof(*sr));
|
sr = (struct st_modem_reset *) msgb_put(msg, sizeof(*sr));
|
||||||
sr->asserted = asserted;
|
sr->asserted = asserted;
|
||||||
sr->pulse_duration_msec = pulse_ms;
|
sr->pulse_duration_msec = pulse_ms;
|
||||||
@@ -310,6 +318,8 @@ static int _modem_sim_select(struct osmo_st2_slot *slot, uint8_t remote_sim)
|
|||||||
struct msgb *msg = st_msgb_alloc();
|
struct msgb *msg = st_msgb_alloc();
|
||||||
struct st_modem_sim_select *ss;
|
struct st_modem_sim_select *ss;
|
||||||
|
|
||||||
|
LOGSLOT(slot, LOGL_NOTICE, "<= %s(remote_sim=%u)\n", __func__, remote_sim);
|
||||||
|
|
||||||
ss = (struct st_modem_sim_select *) msgb_put(msg, sizeof(*ss));
|
ss = (struct st_modem_sim_select *) msgb_put(msg, sizeof(*ss));
|
||||||
ss->remote_sim = remote_sim;
|
ss->remote_sim = remote_sim;
|
||||||
|
|
||||||
|
|||||||
@@ -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_QMOD_SAM3 },
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OCTSIMTEST },
|
||||||
|
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ AM_LDFLAGS=$(COVERAGE_LDFLAGS)
|
|||||||
LDADD= $(top_builddir)/lib/libosmo-simtrace2.la \
|
LDADD= $(top_builddir)/lib/libosmo-simtrace2.la \
|
||||||
$(LIBOSMOCORE_LIBS) $(LIBOSMOSIM_LIBS) $(LIBOSMOUSB_LIBS) $(LIBUSB_LIBS)
|
$(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_cardem_pcsc_SOURCES = simtrace2-cardem-pcsc.c
|
||||||
|
|
||||||
simtrace2_list_SOURCES = simtrace2_usb.c
|
simtrace2_list_SOURCES = simtrace2_usb.c
|
||||||
|
|
||||||
simtrace2_sniff_SOURCES = simtrace2-sniff.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;
|
||||||
|
}
|
||||||
@@ -25,13 +25,7 @@
|
|||||||
|
|
||||||
#include <osmocom/usb/libusb.h>
|
#include <osmocom/usb/libusb.h>
|
||||||
#include <osmocom/simtrace2/simtrace_usb.h>
|
#include <osmocom/simtrace2/simtrace_usb.h>
|
||||||
|
#include <osmocom/simtrace2/usb_util.h>
|
||||||
static const struct dev_id compatible_dev_ids[] = {
|
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OWHW_SAM3 },
|
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_QMOD_SAM3 },
|
|
||||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static int find_devices(void)
|
static int find_devices(void)
|
||||||
{
|
{
|
||||||
@@ -39,7 +33,7 @@ static int find_devices(void)
|
|||||||
int rc, i, num_interfaces;
|
int rc, i, num_interfaces;
|
||||||
|
|
||||||
/* scan for USB devices matching SIMtrace USB ID with proprietary class */
|
/* scan for USB devices matching SIMtrace USB ID with proprietary class */
|
||||||
rc = osmo_libusb_find_matching_interfaces(NULL, compatible_dev_ids,
|
rc = osmo_libusb_find_matching_interfaces(NULL, osmo_st2_compatible_dev_ids,
|
||||||
USB_CLASS_PROPRIETARY, -1, -1, ifm, ARRAY_SIZE(ifm));
|
USB_CLASS_PROPRIETARY, -1, -1, ifm, ARRAY_SIZE(ifm));
|
||||||
printf("USB matches: %d\n", rc);
|
printf("USB matches: %d\n", rc);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user