78 Commits

Author SHA1 Message Date
Oliver Smith
b86831c55b debian: don't package simtrace2-firmware anymore
Don't attempt to build the firmware with the random default compiler
from the distribution anymore. With some GCC versions, the DFU loader
does not fit the partition anymore.

Related: OS#5260
Change-Id: I95a8472b458db203ad14efd57268ca922c75aeb1
2021-11-17 16:16:46 +01:00
Eric Wild
23125d05f7 jenkins: build bootloader updater
Change-Id: I8b2023921a67b0e8945d8f24e4c8076de3e12acf
2021-11-02 10:50:36 +00:00
Eric Wild
7ac85188f4 firmware: add missing usb strings to blupdate that prevented building it
Change-Id: I8d0d9bf98748d475427d9b0c78f2e0532ee4bca1
2021-11-02 09:54:55 +00:00
Eric Wild
23eb56319c add our default clang-format file
Change-Id: I77aab70400bdbb46cbdd83e428e2a28ebf29b8dd
2021-11-01 14:35:14 +01:00
Eric Wild
c85f52d5d5 firmware: drop cref printing
No one reads this, no one wants to know this.

Change-Id: Ie2281e207164f82d8ee29bd596a5593c22aaf198
2021-11-01 14:35:14 +01:00
Eric Wild
a079e2b4ee firmware: increase reset delay before usb reattach
The previous value was way too low and led to reenumeration issues when
switching from app to bl because the hosts are fairly lenient and
feature long delays until they accept disappearing devices as gone for
good instead of ignoring a presuambly flaky usb cable or connection.

Related: SYS5061
Change-Id: I9b8c8bf794ad5b94fc7ea2a01d1ebf4e36862c36
2021-11-01 14:35:14 +01:00
Eric Wild
f83d42ce51 firmware: remove usb pullup that dates back to simtrace1
All the parts are DNP and never existed on the simtrace2 with sam3; the
sam3 has internal pullups that are part of the usb peripheral.

Change-Id: I04a703a2eba6ff1dc64692c089213389d0c1066d
2021-11-01 14:35:14 +01:00
Eric Wild
a7e306f745 firmware: add bootloader update "app"
This bl updater can be flashed as app and will update the bootloader and
then
delete itself before resetting the sam3, so the device will end up in
the newly
updated dfu bootloader afterwards, without having to press the
bootloader button
or requring any other manual interaction, ready to receive a new
application image.

Building the blupdater requires a previously built dfu-flash bootloader
bin file that
will then be embedded into the app during building.

Related: OS#1704
Related: SYS5061
Change-Id: I53dea57bba790a2ab3245d9483e0ff1c8d19d5e3
2021-11-01 12:03:38 +00:00
Harald Welte
020edca678 cardem-pcsc: Fix return of uninitialized variable
Fixes: CID#240740
Change-Id: I97431f491f60e2a6537502ef88042907723b7de6
2021-10-25 08:12:08 +02:00
Eric Wild
17bfa5273f fix bootloader led config crash
This led to occasional crashes for targets with leds since it was
introduced 3 years ago
The interesting thing is that most of the time it didn't crash...

Change-Id: Ia6a1b1fc0e44a301b4fb1d9c9fdbc27d61dcab97
2021-10-20 20:03:06 +02:00
Eric Wild
a65fb1e319 clang build support
Supposed to be used with https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm
+ distro provided binutils-arm-none-eabi package, might provide better and more reliable
binary sizes, especially for the bootloader.

Just run USE_CLANG=1 make

Change-Id: I1a19f40d44797efad5c46121e73115ed738a095b
2021-10-20 20:03:06 +02:00
Eric Wild
af6ae8b8dd drop unused exidx sections when linking
clang might emit those even though they are neither needed or wanted,
so just get rid of them.

Change-Id: I159b4405cebe72af4d98b27f876c48835ffd6e2d
2021-10-20 20:03:06 +02:00
Eric Wild
90784220a5 add the ngff cardem to default build targets
Change-Id: Icec4966fe419eee9f7ace67e46e3d88738812b38
2021-10-20 20:03:06 +02:00
Harald Welte
651050922a simtrace2-tool: Initialize logging to avoid error on first log output
This avoids
 ERROR: osmo_log_info == NULL! You must call log_init() before using logging in log_check_level()

Change-Id: Id355ef33e10164f8e8eb40c2fd0b606bc8e9b6f7
2021-10-06 21:10:44 +02:00
Harald Welte
5b7a608277 simtrace2-cardem-pcsc: Remove double libusb initialization
This code already calls osmo_libusb_init further above in the top
of the main() function, so there's no use of calling libusb_init()
directly in the same function lines below.

Change-Id: I2e0c7446aaa644c5aae1059ce91ff9f729903cbc
2021-10-06 21:06:21 +02:00
Harald Welte
e304015b3c Use osmo_libusb_{init,exit}() instead of libusb_{init,exit}()
We use other osmo_libusb_* functions later in the code, so it is best
to initialize the library via libosmousb, and not directly.

Change-Id: I2fd981935e1420e529f5dd8a98edd347c317284c
2021-10-06 21:06:06 +02:00
Harald Welte
19ccc209c1 jenkins.sh: Build 'trace' firmware for ngff_cardem
Let's create and publish binary builds for 'trace' on BOARD=ngff_carde.

According to SYS#5525 this is verified working since two months ago, so
there's no reason to withhold the binary builds for it.

Change-Id: I8a98002ef5aa58e5a3d49627323fe11505508bc8
Related: SYS#5525
2021-10-06 21:01:14 +02:00
Eric Wild
5e82a2a1c6 Revert "firmware: data sections"
This reverts commit e6a76c7bf4.

Might or might not cause weird issues depending on gcc and binutils
versions, let's see if this helps.

Change-Id: I2f593fd5e0f1494aae6b9fcfb2160a6c9168f5b8
2021-10-04 18:05:45 +02:00
Eric Wild
301aec51f7 contrib/jenkins.sh: lower trace to make bl fit
We keep running out of rom space, so reduce tracing to nothing for alle
dfu targets, and let's hope newer gcc versions stop producing more
code...

Change-Id: I7d2947c84097035bed00ad489a175d614b4c388e
2021-10-04 15:07:44 +00:00
Eric Wild
1f75e3881c contrib: allow manually forcing bulk simtrace dissection
Change-Id: I5fcfe3c221b87b02e21c857ac51d0392c3b4de3c
2021-08-09 15:18:59 +02:00
Eric Wild
5beffa5d91 contrib/jenkins.sh: build ngff_Cardem dfu bootloader
It does fit with some compiler versions, while others overflow the bl region,
so just reduce the trace level a bit to make it fits all the time.

Change-Id: I168a847da8dfc585aaeef0030f95fc225a713147
2021-08-09 12:45:13 +02:00
Harald Welte
3092721729 contrib/jenkins.sh: Build APP=cardem for BOARD=ngff_cardem
This makes sure downloads.osmocom.org will get cardem images
for the new ngff_cardem board.

The dfu loader was not enabled as it currently overflows the ROM
region by 200 bytes, see OS#5210.

Change-Id: Id2b7925c823fb19f880e06a205764d2b19de4ad4
Related: OS#5210
2021-08-08 21:31:03 +02:00
Eric Wild
7ca68359f3 cardem: fix spurious NULL bytes during transfers
The "wait time extension timer" was apparently not being reset during
normal tx operations, which led to occasional NULL (0x60) bytes getting
injected into transfers, which in turn led to more tx bytes than what
the reader side expects...

The odd thing is that this was only noticeable with high baud rates,
probably due to the very long default WT of 9600 ETU, and even then only
because it led to weird ngff modem resets after benign transfers.

Change-Id: I15b0b83b7d93b8e5589f3640bd6eb2fc82f93394
Related: SYS#5553
2021-08-08 04:14:38 +02:00
Harald Welte
a951c4ae02 simtrace2.spec: Add simtrace2-tool binary to package
This fixes RPM build issues reported as

[   59s] error: Installed (but unpackaged) file(s) found:
[   59s]    /usr/bin/simtrace2-tool

Change-Id: I1fd5980a686652afb47cd1c30e12919de626aec7
2021-08-03 09:02:34 +02:00
Eric Wild
d1d504bfa5 firmware: trace for ngff
Change-Id: Iee1eedd93d72c02880fd59fb8588abe14d05e77b
2021-08-02 15:10:21 +00:00
Eric Wild
23a9771467 contrib: more cardem dissection
Change-Id: Ia74d3674f854b390c9745a1cb8d5756bd5d39540
2021-08-02 09:23:19 +00:00
Eric Wild
a755b53768 simtrace2-cardem: use local sim on exit
There is no obvious reason why the st should be stuck in cardem mode
without a working running util on the host side since there is no state
that is being kept, so switch back to using the local sim upon reset.

Change-Id: Ib622af0027d40b4e8afbb0fa0d3689f0dbfcac92
2021-08-02 09:23:19 +00:00
Eric Wild
1ad205e682 firmware: make the ngff beakout blink
..but only if the cardem sim is active

Change-Id: I65f1fbeb06690a143ef4c792728c9cb917a4ffde
2021-08-02 09:22:46 +00:00
Eric Wild
34317c1f32 firmware: proper makefile deps
Single threaded evaluation is (assumed to be!) left to right, depth
first - but with concurrent make using -j this breaks, because the
actual usb string header is generated after the attempt to concurrently
compile the code that needs it, since there is no explicit order among
the all: dependencies.

This is fixed by properly adding a dependency on that header.

Change-Id: I0bdf915deabeda861f6398e654764918e58a64c2
2021-08-02 09:22:46 +00:00
Eric Wild
e6a76c7bf4 firmware: data sections
Might or might not be compiler default, but why guess?

Change-Id: Id3da816611afea0858466949dcc47db5e5d5493a
2021-08-02 09:22:46 +00:00
Harald Welte
4fe93be725 introduce support for new ngff_cardem board
This adds support for the new ngff_cardem board, a board that
basically combines a ngff breakout board with a built-in SIMtrace2.

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

Trace was also tested and appears to work as expected.

Change-Id: Ia96124fbe8a752c98e7fd4096d542a3b2b9bc255
2021-08-02 09:22:46 +00:00
Harald Welte
51d87fbb66 Introduce simtrace2-tool
The simtrace-tool is a command line tool which can be used to e.g.
manually request a modem reset.

Change-Id: I3a8896ac2b3caef7590b51118359e5caed820a40
2021-08-02 09:22:46 +00:00
Oliver Smith
c7490b46cd gitreview: new file
Change-Id: I650fe7c930392d24042e65295fa49400478ffab9
2021-07-30 10:32:35 +02:00
Harald Welte
c85f39078c contrib/flash.py: Add OCTSIMTEST support
Change-Id: Id906d955f45a204ac0b00f56d8f5149c64c62f32
2021-07-09 11:46:16 +00:00
Harald Welte
06fe3b8295 99-simtrace2.rules: Add OCTSIMTEST
Change-Id: I226ee21e0937f851428578578f81075fa703dd54
2021-07-09 11:46:11 +00:00
Harald Welte
d0c420055d board_gpio.gnumeric: Add ngff-cardem pin-out
Change-Id: Ie1a7be85200e331232ad52aa0468c748ff053142
2021-07-01 23:28:52 +02:00
Harald Welte
3ef40d1ca6 simtrace2-list: Use osmo_st2_compatible_dev_ids[]
we shouldn't use a local copy of the device id list, which is already
outdated now that OCTSIMTEST support has been added to libosmo-st2

Change-Id: I2231006b94c33fe3b28ce37b0d54c67206751058
2021-06-30 08:17:58 +00:00
Harald Welte
dcfea28a4f don't printf() directly from library code, go via libosmocore logging
This allows us to use different log levels, and permits the user to use
other log targets.

Change-Id: I08ef7cfa5d8734882746a11ccd5f059d757401ae
2021-06-30 08:17:58 +00:00
Eric Wild
264f615b65 cardemu: support 1v8 for the tester
The tester has shifters, while the original simtrace relies upon the
reader restarting the powerup attempt with > 1v8 after not respondig due
to a lack of shifters and therefore 1v8 support.

Change-Id: I520aa26c6e0fb34568a4f632943efa59a0da831c
2021-06-26 02:54:20 +02:00
Eric Wild
017e10e9ef cardem: free the buf
This leak was probably hard to notice since config commands are usually
rarely sent.

Change-Id: I21411ef78a32a5258a7008272774cdb83119b413
2021-06-21 23:46:38 +02:00
Eric Wild
f0653533cc contrib: add a basic simtrace lua dissector for wireshark
See Help->About Wireshark->Folders tab,the usual place this should go is
~/.local/lib/wireshark/plugins
Hot reload possible after editing using Analyze->Reload Lua Plugins

Change-Id: I360ab522dabc3a378969df36efd3b48fc4cade3c
2021-06-21 17:38:53 +02:00
Harald Welte
f2e924c4aa firmware: octsimtest: ensure all card_insert GPIO are 0 after reset
Change-Id: I3c3744673ba53750cb66aa5023c8228edb006bfc
2021-06-06 11:46:49 +02:00
Harald Welte
efb47b3fae firmware: octsimtest: Add i/I command for setting card-insert via I2C GPIO
Change-Id: Ie1483ccf8465df0d640d55e50421fda910dced4a
2021-06-06 11:46:49 +02:00
Harald Welte
2b1d1e6d92 firmware: octsimtest: Fix disabling the card_insert signal
Back in I8c9b0c3d862a967832134b24252577739182da62 we added support
for enabling the card_insert signal, but not for explicit disable
of it.  Let's fix that.

Change-Id: I6f32bde60674119c9912e51059a53b5ee74d074a
2021-06-03 15:06:58 +02:00
Harald Welte
e2971dee2a firmware: octsimtest: use TRACE_* macros instead of direct printf
Change-Id: I41864bc2f64905a4f2ccb50769b1840e8a490c76
2021-06-03 14:37:45 +02:00
Harald Welte
731e199fc4 firmware: octsimtest: Support SIMTRACE_MSGT_DT_CEMU_CARDINSERT
The octsimtest board can control the card-insert contact of the OCTSIM
under test via an external I2C gpio multiplexer; let's add support for
that.

Change-Id: I8c9b0c3d862a967832134b24252577739182da62
2021-06-03 14:37:45 +02:00
Harald Welte
f69a60f255 firmware: cardem: re-factor CARDINSERT command processing
move it out of the general command dispatch switch statement
and into a separate function.

Change-Id: Ia40c3d9999be68248da0dcc69d298450ca6e4869
2021-06-03 14:37:45 +02:00
Harald Welte
dd5794c975 firmware: octsimtest: mcp23017 initializaiton
* driver should not have hard-coded understanding about I/O directions
* board code should pass the I/O direction to driver
* board code should use the correct I/O directions (A0..7, B0: output)

Change-Id: Id4a8e012a33cee01bb489e612e17920760b9be59
2021-06-03 14:37:45 +02:00
Harald Welte
d46f6bae2c firmware: octsimtest: Make slot mux configurable via USB
Change-Id: I4cdb250d2e1dbc5b8b0169f8b7c21e288b492e1d
2021-06-03 14:37:43 +02:00
Harald Welte
3561fc4c8b firmware: octsimtest: Fix IO_DIR pin definition
Change-Id: I776c9106bcd4ceb24a5d50ea05c6025dedb73822
2021-06-03 14:32:36 +02:00
Harald Welte
b69f5a85b3 contrib/jenkins.sh: Build 'cardem' app for 'octsimtest' board
Change-Id: Ia38bbb85c2828ab7307ffe688e50d7cdf70d6d39
2021-06-03 09:36:10 +02:00
Harald Welte
4996d7d634 octsimtest: Adjust VCC voltage thresholds (resistive VCC divider)
octsimtest has a resistive voltage divider in front of the VCC ADC
in order to also detect 5V.  We must make the thresholds board-specific
and adjust them for octsimtest.

Change-Id: I9e4adb4f349d2d838ea4100eb49271f3a0e7a2a5
2021-06-03 09:36:10 +02:00
Harald Welte
054d7ca499 cardem-pcsc: initialize libosmocore logging
Change-Id: I815d39190e944d9512ffc8e5f581515d7be9834f
2021-06-02 22:57:10 +02:00
Harald Welte
5b825beb41 octsimtest: Switch direction of I/O level shifter depending on uart tx / rx
Contrary to other hardware designs, octsimtest has a level-shifter in
the I/O line to support testing with 1.8, 3 and 5V.  This level shifter
is bi-directional, but the direction needs to be explicitly specified
via the SIM_IO_DIR signal attached to PA26.

Change-Id: I44171363b5bd69d6049b12c86f8143be83557cb2
2021-06-02 22:57:10 +02:00
Harald Welte
31d103b9f6 octsimtest: most code for support of this new board
* code for controlling the Card slot + frequencyt divider muxes
* put everything in place to build cardem application for it

Change-Id: I7e03e0c0f2999a1ce2dad966d98e22033fa58465
2021-06-02 22:56:12 +02:00
Harald Welte
73466e2b89 octsimtest: remove lots of unused #defines
The octsimtest board only supports cardem mode, not 'ccid'
nor 'sniffer'.  Remove related GPIO pin #defines from board.h

Change-Id: I43e8631d945ba183a1e5b1e37dd4565adb377154
2021-06-02 22:56:04 +02:00
Harald Welte
913c86b95d Add usb product ID of sysmoOCTSIMTEST
This is a custom board for production testing of the sysmoOCTSIM,
an 8-slot smart card reader.

Change-Id: I65839be50ac896c76f34755fb2800f836f6cdae4
2021-06-02 10:09:40 +02:00
Harald Welte
0516464620 assert: Use printf_sync() to ensure printing of assert / panic
Change-Id: Icc202e60445d9be1cdcd61176db5ed1704d583e7
2021-06-02 09:12:35 +02:00
Harald Welte
c1033c8611 simtrace2-cardem-pcsc: Reset the real card if reader resets cardem
When the cardem detects a reset from the phone/modem, pass this on
to the actual card via the PC/SC reader.  This is important to
reset the card state whenever requested by the stack/driver on the
phone/modem.

Change-Id: I7056476c5f81e8aa8f550afb86bf2380d1497ebb
Depends: libosmocore 20199da02d37a6d284915a27ec12641e79b8781c
2021-06-01 21:09:05 +02:00
Harald Welte
644c2131ca simtrace2-cardem-pcsc: Decode STATUS flags to strings
SIMtrace IRQ STATUS: flags=0x13, fi=9, di=6, wi=10 wtime=9600 (RESET VCC  CLK )

is more understandable than

SIMtrace IRQ STATUS: flags=0x13, fi=9, di=6, wi=10 wtime=9600

Change-Id: I5bbfa1d99ebee4b297d894a5f444dbe743c7ab70
2021-06-01 21:09:05 +02:00
Harald Welte
796501293d Revert "cardem: disable upload for simtrace2"
This reverts commit baa62777c8 which
deleted simtrace-cardem builds to prevent them from being published.

Change-Id: I63fd4bea2985fcc87f202d8b69a4f24661858185
2021-06-01 18:47:37 +02:00
Harald Welte
e33c2907bc jenkins.sh: build 'cardem' firmware also for simtrace board
Now that it is supported, we should also build + publish the related
binaries.

Change-Id: I9231503b865adc863959d74d98e7f24f83c293e9
2021-06-01 18:38:25 +02:00
Harald Welte
0f75d6ef1e simtrace board.h: Enable HAVE_CARDEM if we build the cardem firmware
likewise, enable HAVE_SNIFFER currently only if we build the sniffer
firmware.

It's been many years too long to finally get those all merged in one
firmware :(

Change-Id: Ib433f180746f75458a44f4988643465bd846b04b
2021-06-01 18:38:21 +02:00
Harald Welte
c690a1f130 st2-cardem-pcsc: Use ATR of real card by default
Before this patch, we would always use either a hard-coded default
ATR from the source code, or we would use one that the user specified
on the command line.

The more sane default is to pass-through the real ATR of the card.

Change-Id: I75bf618a6b0d983727de4c2f19b4b48ec3e12af8
Closes: OS#5107
Requires: libosmocore.git 22117a7164012d6d88fc202cd63df79c6068484d
2021-04-25 21:30:47 +02:00
Harald Welte
8e6ba005d4 st2-cardem-pcsc: Fix goto-in-while mess
There's some code that wasnts to goto within the while loop, and there's
some other code that wants to goto after the while loop.  Don't jump
from outside the while loop into the while loop.

Change-Id: Ic2a94ad034dd259f15712687443b569f0d18ff3f
2021-04-25 21:30:47 +02:00
Harald Welte
206d613b4d contrib/jenkins.sh: Switch from rita -> ftp.osmocom.org
We should use service-aliases and not the primary host name, as
that makes migration between machines hard.

Change-Id: I34b18457268ae6f8ae3a053c5424210074a4d52e
2021-04-22 11:21:12 +02:00
Harald Welte
7b681981ea card_emu: Fix computation of waiting time
As we store the waiting time (WT) in 'etu', we must adjust the formula
from ISO 7816-3.  The 'Fi' component in the formula only exists to
compute clock cycles from the etu, which we don't need here.

Without this patch, the waiting time would be way too large (by a factor
of 372 in the default case).

Change-Id: Ia21bc7303f9b38834b5b1753983ed2a99bfc7d95
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
e410842d8e card_emu: Fix USART timer, particularly in re-start situations
The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
752bc7f4b5 card_emu: Use USART timeout for waiting time
Instead of using the timer/counter peripheral to handle the waiting time
and corresponding timeout, the USART peripheral internal timeout
mechanism is used.

This is particularly important for the SIMtrace board since there
(contrary to other boards) the I/O signal is not wired to a TIO pin
of the timer/counter block, and hence Rx/Tx data cannot reset that
timer/counter.

As a result of this migration, cardem is now supported not only on
owhw + qmod, but also on the simtrace board.

The guts of this change have been lifted out of Change-Id
Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5 by Kevin Redon, which was
unfortunately touching various different topics at the same time and
hence was split up. Some improvements are the introduction of the
ENABLE_TX_TIMER_ONLY mode, which avoids the USART interrupt handler
getting hammered with TXRDY between release of RST and start of the ATR.

Change-Id: Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
7f421ef014 card_emu: explicitly initialize PTS and TPDU states
Those are already initialized at various transitions of the master
7816 FSM, but let's properly initialize them at start-up, too.

Change-Id: I81b2a8ef3284559164700d94717e4ccf008f53df
2021-04-08 21:28:37 +00:00
Harald Welte
a708ea1d99 card_emu: improve reset detection conditions
* enter ISO_S_WAIT_RST when RST is asserted
* enter ISO_S_WAIT_ATR only when we RST is released while in state ISO_S_WAIT_RST

Change-Id: I620333aa8d45561a8028b948955a27f667b58406
2021-04-08 21:28:37 +00:00
Harald Welte
c1ffc8a603 iso7816_fidi: Add iso7816_3_ prefix to symbols; fix terminology
Fi/Di are not the index into the table, but the contents of the table
as resolved by Fi_index / Di_index.  Let's clarify the terminology.

Change-Id: If364e08e7c9a3a9707e6d54b9267c6a7c088e415
2021-04-08 21:28:37 +00:00
Harald Welte
79f0ea73a2 card_emu: Clarify and differentiate F/Fi/F_index/Fi_index
The ISO7816 spec terms are well-defined, let's not abuse them. We used
to consider "Fi" as the "index into the table of F values", while the
spec actually considers Fi as the initial value for F.

Let's make sure we use the terms quite clearly:
* Fi and Di are the initial values for F and D
* F*_index and D*_index are the indexes into the ISO7816-3 Tables

Furthermore, let's track Fi separately from F, as e.g. the waiting
time definition only considers Fi as indicated in the ATR, despite
an actually different F value might have been negotiated via PTS
meanwhile.

Change-Id: Ieb2425e8380a81b79df7b2bd072902994e9c3ee7
Related: OS##1704
2021-04-08 21:28:37 +00:00
Harald Welte
9454a062b5 card_emu: Rename fi to Fi and di to Di
As we will soon introduce the distinction between Fi and F, we should
use uppercase letters, as lower-case 'f' is defined in ISO7816-3 as
the frequency, which is different from the upper-case 'F'.

Change-Id: Iaede621551520576e9b9af878fa46fbc88e59c2a
2021-04-08 21:28:37 +00:00
Kévin Redon
6b7f8d142f make sim switch board specific
the simtrace board uses a bus switch not used on qmod and owhw to
switch the SIM between physical and virtual

Change-Id: Ieaf2ed4761fc3e04f33f9aac5c04a768c9a6f71e
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
9c95162d5c card_emu: waiting_time is stored in etu, not clocks.
The comment didn't reflect the source.  I checked all users and
the code consistently stores the waiting time in units of 'etu'.

Change-Id: I2bc4a7c19cee5fb487ad639ee48ecaea706f6172
2021-04-08 21:28:37 +00:00
Oliver Smith
878fadd74f firmware: disable stack protector by default
Disable stack protector for all boards/apps by default, not only
qmod-dfu. Use 'make STACK_PROTECTOR=1' to enable.

This was recommened by Eric:
"I'd argue that we do not want this in general, since it adds canaries
to all functions that deal with buffers, and therefore impacts the
overall timing in a non determinstic way depending on inlining and
optimizations, while contributing nothing in non debug builds."

Related: OS#5081
Change-Id: I30ad97f231ea5b401def650bc9adc7e9f2770df0
2021-04-08 12:04:47 +02:00
Oliver Smith
9e0e0ddd5a firmware: qmod-dfu: disable stack protector
Prevent build failure on debian 9, ubuntu 20.04, 20.10, where
bin/qmod-dfu-flash.elf does not fit the ROM.

Fixes: OS#5081
Change-Id: I9fffe4c323094679062428f41a4246b1c1b30ca2
2021-04-07 15:23:55 +02:00
56 changed files with 2543 additions and 288 deletions

563
.clang-format Normal file
View File

@@ -0,0 +1,563 @@
# SPDX-License-Identifier: GPL-2.0
#
# clang-format configuration file. Intended for clang-format >= 4.
#
# For more information, see:
#
# Documentation/process/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
#AfterExternBlock: false # Unknown to clang-format-5.0
BeforeCatch: false
BeforeElse: false
IndentBraces: false
#SplitEmptyFunction: true # Unknown to clang-format-4.0
#SplitEmptyRecord: true # Unknown to clang-format-4.0
#SplitEmptyNamespace: true # Unknown to clang-format-4.0
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
#CompactNamespaces: false # Unknown to clang-format-4.0
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
#FixNamespaceComments: false # Unknown to clang-format-4.0
# Taken from:
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq
ForEachMacros:
- 'apei_estatus_for_each_section'
- 'ata_for_each_dev'
- 'ata_for_each_link'
- '__ata_qc_for_each'
- 'ata_qc_for_each'
- 'ata_qc_for_each_raw'
- 'ata_qc_for_each_with_internal'
- 'ax25_for_each'
- 'ax25_uid_for_each'
- '__bio_for_each_bvec'
- 'bio_for_each_bvec'
- 'bio_for_each_bvec_all'
- 'bio_for_each_integrity_vec'
- '__bio_for_each_segment'
- 'bio_for_each_segment'
- 'bio_for_each_segment_all'
- 'bio_list_for_each'
- 'bip_for_each_vec'
- 'bitmap_for_each_clear_region'
- 'bitmap_for_each_set_region'
- 'blkg_for_each_descendant_post'
- 'blkg_for_each_descendant_pre'
- 'blk_queue_for_each_rl'
- 'bond_for_each_slave'
- 'bond_for_each_slave_rcu'
- 'bpf_for_each_spilled_reg'
- 'btree_for_each_safe128'
- 'btree_for_each_safe32'
- 'btree_for_each_safe64'
- 'btree_for_each_safel'
- 'card_for_each_dev'
- 'cgroup_taskset_for_each'
- 'cgroup_taskset_for_each_leader'
- 'cpufreq_for_each_entry'
- 'cpufreq_for_each_entry_idx'
- 'cpufreq_for_each_valid_entry'
- 'cpufreq_for_each_valid_entry_idx'
- 'css_for_each_child'
- 'css_for_each_descendant_post'
- 'css_for_each_descendant_pre'
- 'device_for_each_child_node'
- 'displayid_iter_for_each'
- 'dma_fence_chain_for_each'
- 'do_for_each_ftrace_op'
- 'drm_atomic_crtc_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane_state'
- 'drm_atomic_for_each_plane_damage'
- 'drm_client_for_each_connector_iter'
- 'drm_client_for_each_modeset'
- 'drm_connector_for_each_possible_encoder'
- 'drm_for_each_bridge_in_chain'
- 'drm_for_each_connector_iter'
- 'drm_for_each_crtc'
- 'drm_for_each_crtc_reverse'
- 'drm_for_each_encoder'
- 'drm_for_each_encoder_mask'
- 'drm_for_each_fb'
- 'drm_for_each_legacy_plane'
- 'drm_for_each_plane'
- 'drm_for_each_plane_mask'
- 'drm_for_each_privobj'
- 'drm_mm_for_each_hole'
- 'drm_mm_for_each_node'
- 'drm_mm_for_each_node_in_range'
- 'drm_mm_for_each_node_safe'
- 'flow_action_for_each'
- 'for_each_acpi_dev_match'
- 'for_each_active_dev_scope'
- 'for_each_active_drhd_unit'
- 'for_each_active_iommu'
- 'for_each_aggr_pgid'
- 'for_each_available_child_of_node'
- 'for_each_bio'
- 'for_each_board_func_rsrc'
- 'for_each_bvec'
- 'for_each_card_auxs'
- 'for_each_card_auxs_safe'
- 'for_each_card_components'
- 'for_each_card_dapms'
- 'for_each_card_pre_auxs'
- 'for_each_card_prelinks'
- 'for_each_card_rtds'
- 'for_each_card_rtds_safe'
- 'for_each_card_widgets'
- 'for_each_card_widgets_safe'
- 'for_each_cgroup_storage_type'
- 'for_each_child_of_node'
- 'for_each_clear_bit'
- 'for_each_clear_bit_from'
- 'for_each_cmsghdr'
- 'for_each_compatible_node'
- 'for_each_component_dais'
- 'for_each_component_dais_safe'
- 'for_each_comp_order'
- 'for_each_console'
- 'for_each_cpu'
- 'for_each_cpu_and'
- 'for_each_cpu_not'
- 'for_each_cpu_wrap'
- 'for_each_dapm_widgets'
- 'for_each_dev_addr'
- 'for_each_dev_scope'
- 'for_each_dma_cap_mask'
- 'for_each_dpcm_be'
- 'for_each_dpcm_be_rollback'
- 'for_each_dpcm_be_safe'
- 'for_each_dpcm_fe'
- 'for_each_drhd_unit'
- 'for_each_dss_dev'
- 'for_each_dtpm_table'
- 'for_each_efi_memory_desc'
- 'for_each_efi_memory_desc_in_map'
- 'for_each_element'
- 'for_each_element_extid'
- 'for_each_element_id'
- 'for_each_endpoint_of_node'
- 'for_each_evictable_lru'
- 'for_each_fib6_node_rt_rcu'
- 'for_each_fib6_walker_rt'
- 'for_each_free_mem_pfn_range_in_zone'
- 'for_each_free_mem_pfn_range_in_zone_from'
- 'for_each_free_mem_range'
- 'for_each_free_mem_range_reverse'
- 'for_each_func_rsrc'
- 'for_each_hstate'
- 'for_each_if'
- 'for_each_iommu'
- 'for_each_ip_tunnel_rcu'
- 'for_each_irq_nr'
- 'for_each_link_codecs'
- 'for_each_link_cpus'
- 'for_each_link_platforms'
- 'for_each_lru'
- 'for_each_matching_node'
- 'for_each_matching_node_and_match'
- 'for_each_member'
- 'for_each_memcg_cache_index'
- 'for_each_mem_pfn_range'
- '__for_each_mem_range'
- 'for_each_mem_range'
- '__for_each_mem_range_rev'
- 'for_each_mem_range_rev'
- 'for_each_mem_region'
- 'for_each_migratetype_order'
- 'for_each_msi_entry'
- 'for_each_msi_entry_safe'
- 'for_each_msi_vector'
- 'for_each_net'
- 'for_each_net_continue_reverse'
- 'for_each_netdev'
- 'for_each_netdev_continue'
- 'for_each_netdev_continue_rcu'
- 'for_each_netdev_continue_reverse'
- 'for_each_netdev_feature'
- 'for_each_netdev_in_bond_rcu'
- 'for_each_netdev_rcu'
- 'for_each_netdev_reverse'
- 'for_each_netdev_safe'
- 'for_each_net_rcu'
- 'for_each_new_connector_in_state'
- 'for_each_new_crtc_in_state'
- 'for_each_new_mst_mgr_in_state'
- 'for_each_new_plane_in_state'
- 'for_each_new_private_obj_in_state'
- 'for_each_node'
- 'for_each_node_by_name'
- 'for_each_node_by_type'
- 'for_each_node_mask'
- 'for_each_node_state'
- 'for_each_node_with_cpus'
- 'for_each_node_with_property'
- 'for_each_nonreserved_multicast_dest_pgid'
- 'for_each_of_allnodes'
- 'for_each_of_allnodes_from'
- 'for_each_of_cpu_node'
- 'for_each_of_pci_range'
- 'for_each_old_connector_in_state'
- 'for_each_old_crtc_in_state'
- 'for_each_old_mst_mgr_in_state'
- 'for_each_oldnew_connector_in_state'
- 'for_each_oldnew_crtc_in_state'
- 'for_each_oldnew_mst_mgr_in_state'
- 'for_each_oldnew_plane_in_state'
- 'for_each_oldnew_plane_in_state_reverse'
- 'for_each_oldnew_private_obj_in_state'
- 'for_each_old_plane_in_state'
- 'for_each_old_private_obj_in_state'
- 'for_each_online_cpu'
- 'for_each_online_node'
- 'for_each_online_pgdat'
- 'for_each_pci_bridge'
- 'for_each_pci_dev'
- 'for_each_pci_msi_entry'
- 'for_each_pcm_streams'
- 'for_each_physmem_range'
- 'for_each_populated_zone'
- 'for_each_possible_cpu'
- 'for_each_present_cpu'
- 'for_each_prime_number'
- 'for_each_prime_number_from'
- 'for_each_process'
- 'for_each_process_thread'
- 'for_each_prop_codec_conf'
- 'for_each_prop_dai_codec'
- 'for_each_prop_dai_cpu'
- 'for_each_prop_dlc_codecs'
- 'for_each_prop_dlc_cpus'
- 'for_each_prop_dlc_platforms'
- 'for_each_property_of_node'
- 'for_each_registered_fb'
- 'for_each_requested_gpio'
- 'for_each_requested_gpio_in_range'
- 'for_each_reserved_mem_range'
- 'for_each_reserved_mem_region'
- 'for_each_rtd_codec_dais'
- 'for_each_rtd_components'
- 'for_each_rtd_cpu_dais'
- 'for_each_rtd_dais'
- 'for_each_set_bit'
- 'for_each_set_bit_from'
- 'for_each_set_clump8'
- 'for_each_sg'
- 'for_each_sg_dma_page'
- 'for_each_sg_page'
- 'for_each_sgtable_dma_page'
- 'for_each_sgtable_dma_sg'
- 'for_each_sgtable_page'
- 'for_each_sgtable_sg'
- 'for_each_sibling_event'
- 'for_each_subelement'
- 'for_each_subelement_extid'
- 'for_each_subelement_id'
- '__for_each_thread'
- 'for_each_thread'
- 'for_each_unicast_dest_pgid'
- 'for_each_vsi'
- 'for_each_wakeup_source'
- 'for_each_zone'
- 'for_each_zone_zonelist'
- 'for_each_zone_zonelist_nodemask'
- 'fwnode_for_each_available_child_node'
- 'fwnode_for_each_child_node'
- 'fwnode_graph_for_each_endpoint'
- 'gadget_for_each_ep'
- 'genradix_for_each'
- 'genradix_for_each_from'
- 'hash_for_each'
- 'hash_for_each_possible'
- 'hash_for_each_possible_rcu'
- 'hash_for_each_possible_rcu_notrace'
- 'hash_for_each_possible_safe'
- 'hash_for_each_rcu'
- 'hash_for_each_safe'
- 'hctx_for_each_ctx'
- 'hlist_bl_for_each_entry'
- 'hlist_bl_for_each_entry_rcu'
- 'hlist_bl_for_each_entry_safe'
- 'hlist_for_each'
- 'hlist_for_each_entry'
- 'hlist_for_each_entry_continue'
- 'hlist_for_each_entry_continue_rcu'
- 'hlist_for_each_entry_continue_rcu_bh'
- 'hlist_for_each_entry_from'
- 'hlist_for_each_entry_from_rcu'
- 'hlist_for_each_entry_rcu'
- 'hlist_for_each_entry_rcu_bh'
- 'hlist_for_each_entry_rcu_notrace'
- 'hlist_for_each_entry_safe'
- 'hlist_for_each_entry_srcu'
- '__hlist_for_each_rcu'
- 'hlist_for_each_safe'
- 'hlist_nulls_for_each_entry'
- 'hlist_nulls_for_each_entry_from'
- 'hlist_nulls_for_each_entry_rcu'
- 'hlist_nulls_for_each_entry_safe'
- 'i3c_bus_for_each_i2cdev'
- 'i3c_bus_for_each_i3cdev'
- 'ide_host_for_each_port'
- 'ide_port_for_each_dev'
- 'ide_port_for_each_present_dev'
- 'idr_for_each_entry'
- 'idr_for_each_entry_continue'
- 'idr_for_each_entry_continue_ul'
- 'idr_for_each_entry_ul'
- 'in_dev_for_each_ifa_rcu'
- 'in_dev_for_each_ifa_rtnl'
- 'inet_bind_bucket_for_each'
- 'inet_lhash2_for_each_icsk_rcu'
- 'key_for_each'
- 'key_for_each_safe'
- 'klp_for_each_func'
- 'klp_for_each_func_safe'
- 'klp_for_each_func_static'
- 'klp_for_each_object'
- 'klp_for_each_object_safe'
- 'klp_for_each_object_static'
- 'kunit_suite_for_each_test_case'
- 'kvm_for_each_memslot'
- 'kvm_for_each_vcpu'
- 'list_for_each'
- 'list_for_each_codec'
- 'list_for_each_codec_safe'
- 'list_for_each_continue'
- 'list_for_each_entry'
- 'list_for_each_entry_continue'
- 'list_for_each_entry_continue_rcu'
- 'list_for_each_entry_continue_reverse'
- 'list_for_each_entry_from'
- 'list_for_each_entry_from_rcu'
- 'list_for_each_entry_from_reverse'
- 'list_for_each_entry_lockless'
- 'list_for_each_entry_rcu'
- 'list_for_each_entry_reverse'
- 'list_for_each_entry_safe'
- 'list_for_each_entry_safe_continue'
- 'list_for_each_entry_safe_from'
- 'list_for_each_entry_safe_reverse'
- 'list_for_each_entry_srcu'
- 'list_for_each_prev'
- 'list_for_each_prev_safe'
- 'list_for_each_safe'
- 'llist_for_each'
- 'llist_for_each_entry'
- 'llist_for_each_entry_safe'
- 'llist_for_each_safe'
- 'mci_for_each_dimm'
- 'media_device_for_each_entity'
- 'media_device_for_each_intf'
- 'media_device_for_each_link'
- 'media_device_for_each_pad'
- 'nanddev_io_for_each_page'
- 'netdev_for_each_lower_dev'
- 'netdev_for_each_lower_private'
- 'netdev_for_each_lower_private_rcu'
- 'netdev_for_each_mc_addr'
- 'netdev_for_each_uc_addr'
- 'netdev_for_each_upper_dev_rcu'
- 'netdev_hw_addr_list_for_each'
- 'nft_rule_for_each_expr'
- 'nla_for_each_attr'
- 'nla_for_each_nested'
- 'nlmsg_for_each_attr'
- 'nlmsg_for_each_msg'
- 'nr_neigh_for_each'
- 'nr_neigh_for_each_safe'
- 'nr_node_for_each'
- 'nr_node_for_each_safe'
- 'of_for_each_phandle'
- 'of_property_for_each_string'
- 'of_property_for_each_u32'
- 'pci_bus_for_each_resource'
- 'pcl_for_each_chunk'
- 'pcl_for_each_segment'
- 'pcm_for_each_format'
- 'ping_portaddr_for_each_entry'
- 'plist_for_each'
- 'plist_for_each_continue'
- 'plist_for_each_entry'
- 'plist_for_each_entry_continue'
- 'plist_for_each_entry_safe'
- 'plist_for_each_safe'
- 'pnp_for_each_card'
- 'pnp_for_each_dev'
- 'protocol_for_each_card'
- 'protocol_for_each_dev'
- 'queue_for_each_hw_ctx'
- 'radix_tree_for_each_slot'
- 'radix_tree_for_each_tagged'
- 'rb_for_each'
- 'rbtree_postorder_for_each_entry_safe'
- 'rdma_for_each_block'
- 'rdma_for_each_port'
- 'rdma_umem_for_each_dma_block'
- 'resource_list_for_each_entry'
- 'resource_list_for_each_entry_safe'
- 'rhl_for_each_entry_rcu'
- 'rhl_for_each_rcu'
- 'rht_for_each'
- 'rht_for_each_entry'
- 'rht_for_each_entry_from'
- 'rht_for_each_entry_rcu'
- 'rht_for_each_entry_rcu_from'
- 'rht_for_each_entry_safe'
- 'rht_for_each_from'
- 'rht_for_each_rcu'
- 'rht_for_each_rcu_from'
- '__rq_for_each_bio'
- 'rq_for_each_bvec'
- 'rq_for_each_segment'
- 'scsi_for_each_prot_sg'
- 'scsi_for_each_sg'
- 'sctp_for_each_hentry'
- 'sctp_skb_for_each'
- 'shdma_for_each_chan'
- '__shost_for_each_device'
- 'shost_for_each_device'
- 'sk_for_each'
- 'sk_for_each_bound'
- 'sk_for_each_entry_offset_rcu'
- 'sk_for_each_from'
- 'sk_for_each_rcu'
- 'sk_for_each_safe'
- 'sk_nulls_for_each'
- 'sk_nulls_for_each_from'
- 'sk_nulls_for_each_rcu'
- 'snd_array_for_each'
- 'snd_pcm_group_for_each_entry'
- 'snd_soc_dapm_widget_for_each_path'
- 'snd_soc_dapm_widget_for_each_path_safe'
- 'snd_soc_dapm_widget_for_each_sink_path'
- 'snd_soc_dapm_widget_for_each_source_path'
- 'tb_property_for_each'
- 'tcf_exts_for_each_action'
- 'udp_portaddr_for_each_entry'
- 'udp_portaddr_for_each_entry_rcu'
- 'usb_hub_for_each_child'
- 'v4l2_device_for_each_subdev'
- 'v4l2_m2m_for_each_dst_buf'
- 'v4l2_m2m_for_each_dst_buf_safe'
- 'v4l2_m2m_for_each_src_buf'
- 'v4l2_m2m_for_each_src_buf_safe'
- 'virtio_device_for_each_vq'
- 'while_for_each_ftrace_op'
- 'xa_for_each'
- 'xa_for_each_marked'
- 'xa_for_each_range'
- 'xa_for_each_start'
- 'xas_for_each'
- 'xas_for_each_conflict'
- 'xas_for_each_marked'
- 'xbc_array_for_each_value'
- 'xbc_for_each_key_value'
- 'xbc_node_for_each_array_value'
- 'xbc_node_for_each_child'
- 'xbc_node_for_each_key_value'
- 'zorro_for_each_dev'
- 'for_each_line'
- 'for_each_non_empty_line'
#IncludeBlocks: Preserve # Unknown to clang-format-5.0
IncludeCategories:
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
#IndentPPDirectives: None # Unknown to clang-format-5.0
IndentWidth: 8
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
# Taken from git's rules
#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
#SortUsingDeclarations: false # Unknown to clang-format-4.0
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
SpaceBeforeParens: ControlStatements
#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 8
UseTab: Always
...

3
.gitreview Normal file
View File

@@ -0,0 +1,3 @@
[gerrit]
host=gerrit.osmocom.org
project=simtrace2

View File

@@ -8,13 +8,23 @@ fw-$(1)-$(2)-clean:
endef
$(eval $(call RULES,simtrace,dfu))
$(eval $(call RULES,simtrace,blupdate))
$(eval $(call RULES,simtrace,trace))
$(eval $(call RULES,simtrace,cardem))
$(eval $(call RULES,qmod,dfu))
$(eval $(call RULES,qmod,blupdate))
$(eval $(call RULES,qmod,cardem))
$(eval $(call RULES,ngff_cardem,dfu))
$(eval $(call RULES,ngff_cardem,blupdate))
$(eval $(call RULES,ngff_cardem,trace))
$(eval $(call RULES,ngff_cardem,cardem))
fw-clean: fw-simtrace-dfu-clean fw-simtrace-trace-clean fw-simtrace-cardem-clean fw-qmod-dfu-clean fw-qmod-cardem-clean
fw: fw-simtrace-dfu fw-simtrace-trace fw-simtrace-cardem fw-qmod-dfu fw-qmod-cardem
fw-clean: fw-simtrace-dfu-clean fw-simtrace-blupdate-clean fw-simtrace-trace-clean fw-simtrace-cardem-clean \
fw-qmod-dfu-clean fw-qmod-blupdate-clean fw-qmod-cardem-clean \
fw-ngff_cardem-dfu-clean fw-ngff_cardem-blupdate-clean fw-ngff_cardem-trace-clean fw-ngff_cardem-cardem-clean
fw: fw-simtrace-dfu fw-simtrace-blupdate fw-simtrace-trace fw-simtrace-cardem \
fw-qmod-dfu fw-qmod-blupdate fw-qmod-cardem \
fw-ngff_cardem-dfu fw-ngff_cardem-blupdate fw-ngff_cardem-trace fw-ngff_cardem-cardem
utils:
(cd host && \

View File

@@ -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"}

View File

@@ -28,9 +28,11 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
BUILDS=""
BUILDS+="simtrace/dfu simtrace/trace "
BUILDS+="qmod/dfu qmod/cardem "
BUILDS+="owhw/dfu owhw/cardem "
BUILDS+="simtrace/dfu simtrace/blupdate simtrace/trace simtrace/cardem "
BUILDS+="qmod/dfu qmod/blupdate qmod/cardem "
BUILDS+="owhw/dfu owhw/blupdate owhw/cardem "
BUILDS+="octsimtest/cardem "
BUILDS+="ngff_cardem/dfu ngff_cardem/blupdate ngff_cardem/cardem ngff_cardem/trace "
cd $TOPDIR/firmware
for build in $BUILDS; do
@@ -63,21 +65,19 @@ make dist
# make -C "$base/doc/manuals" publish
#fi
rm -rf $TOPDIR/firmware/bin/simtrace-cardem*
if [ "x$publish" = "x--publish" ]; then
echo
echo "=============== UPLOAD BUILD =============="
$TOPDIR/contrib/prepare_upload.sh
cat > "/build/known_hosts" <<EOF
[rita.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
[rita.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
[rita.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
[ftp.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
[ftp.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
[ftp.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
EOF
SSH_COMMAND="ssh -o 'UserKnownHostsFile=/build/known_hosts' -p 48"
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/latest/
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/all/
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/latest/
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/all/
fi
echo

92
contrib/simtrace.lua Normal file
View File

@@ -0,0 +1,92 @@
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")
local pb_and_rx = ProtoField.uint32("usb_simtrace.pb_and_rx", "pb_and_rx", base.HEX_DEC, NULL, 0x8)
local pb_and_tx = ProtoField.uint32("usb_simtrace.pb_and_tx", "pb_and_tx", base.HEX_DEC, NULL, 0x4)
local final = ProtoField.uint32("usb_simtrace.final", "final", base.HEX_DEC, NULL, 0x2)
local tpdu_hdr = ProtoField.uint32("usb_simtrace.tpdu_hdr", "tpdu_hdr", base.HEX_DEC, NULL, 0x1)
local rxtxdatalen = ProtoField.uint16("usb_simtrace.rxtxdatalen", "rx/tx data length", base.HEX_DEC)
local rxtxdata = ProtoField.bytes("usb_simtrace.rxtxdata", "rx/tx (data)")
usb_simtrace_protocol.fields = {
msgtype, seqnr, slotnr, reserved, payloadlen, payload, pb_and_rx, pb_and_tx, final, tpdu_hdr, rxtxdatalen, rxtxdata
}
function dissect_rxtx(payload_data,pinfo,tree)
local headerSubtree = tree:add(usb_simtrace_protocol, payload_data, "rx/tx data")
local len = payload_data(8+4,2):le_uint();
local cmd32 = payload_data(8+0,4):le_uint();
headerSubtree:add(pb_and_rx, cmd32)
headerSubtree:add(pb_and_tx, cmd32)
headerSubtree:add(final, cmd32)
headerSubtree:add(tpdu_hdr, cmd32)
headerSubtree:add(rxtxdatalen, len)
headerSubtree:add_le(rxtxdata, payload_data(8+6,len))
end
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])
local payload_data = buffer(8,length-8)
if(command == 0x0101 or command == 0x0106) then
return dissect_rxtx(buffer(),pinfo,subtree)
else
subtree:add(payload, payload_data)
end
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

14
debian/control vendored
View File

@@ -12,29 +12,17 @@ Build-Depends: debhelper (>= 9),
dh-autoreconf,
libosmocore-dev,
libpcsclite-dev,
libnewlib-arm-none-eabi,
libusb-1.0-0-dev,
gcc-arm-none-eabi
libusb-1.0-0-dev
Standards-Version: 3.9.8
Vcs-Git: git://git.osmocom.org/simtrace2.git
Vcs-Browser: http://git.osmocom.org/simtrace2/
Homepage: http://osmocom.org/projects/simtrace2/wiki
Package: simtrace2-firmware
Section: devel
Architecture: all
Recommends: dfu-util
Description: Firmware for SAM3 based SIMtrace2 USB Devices.
Open Source firmware for the Cortex-M3 microcontroller in the
"Osmocom SIMtrace2" USB-attached peripheral device. Will only work in
SAM3S-based SIMtrace2, not in its SAM7S-based predecessor SIMtrace!
Package: simtrace2-utils
Section: devel
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}, libosmo-simtrace2-0
Recommends: simtrace2-firmware
Description: Host utilities to communicate with SIMtrace2 USB Devices.
Package: libosmo-simtrace2-0

6
debian/rules vendored
View File

@@ -17,3 +17,9 @@ export DEB_LDFLAGS_MAINT_STRIP = -Wl,-Bsymbolic-functions
override_dh_autoreconf:
cd host && dh_autoreconf
override_dh_auto_build:
dh_auto_build -- utils
override_dh_auto_install:
dh_auto_build -- -C host

View File

@@ -1 +0,0 @@
usr/share/simtrace2/*.bin

View File

@@ -50,6 +50,7 @@ APP ?= dfu
# Defines which are the available memory targets for the SAM3S-EK board.
ifeq ($(APP), dfu)
MEMORIES ?= flash dfu
TRACE_LEVEL ?= 0
else
MEMORIES ?= dfu
endif
@@ -72,12 +73,20 @@ AT91LIB_USB_DFU_PATH = $(AT91LIB)/usb/device/dfu
# Tool suffix when cross-compiling
CROSS_COMPILE = arm-none-eabi-
LIBS = -Wl,--start-group -lgcc -Wl,--end-group -nostdlib
# Compilation tools
USE_CLANG ?= 0
ifneq ("$(USE_CLANG)","0")
# --target=thumbv7m-none-eabi
CC = clang
LD = ld.lld
SIZE = llvm-size
LIBS = -nostdlib
else
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
SIZE = $(CROSS_COMPILE)size
LIBS = -Wl,--start-group -lgcc -Wl,--end-group -nostdlib
endif
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
GDB = $(CROSS_COMPILE)gdb
@@ -138,7 +147,11 @@ ALLOW_PEER_ERASE?=0
#CFLAGS+=-DUSB_NO_DEBUG=1
# Optimization level, put in comment for debugging
ifneq ("$(USE_CLANG)","0")
OPTIMIZATION ?= -Oz
else
OPTIMIZATION ?= -Os
endif
# Flags
INCLUDES_USB = -I$(AT91LIB)/usb/include -I$(AT91LIB)
@@ -152,6 +165,11 @@ INCLUDES += -Ilibosmocore/include
INCLUDES += -Isrc_simtrace -Iinclude
INCLUDES += -Iapps/$(APP)
ifneq ("$(USE_CLANG)","0")
CFLAGS += -Wno-unknown-warning-option -Wno-empty-body -fno-exceptions -fno-unwind-tables --config armv7em_soft_nofp_nosys
else
CFLAGS += -Wno-suggest-attribute=noreturn --param max-inline-insns-single=500
endif
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wimplicit-int -Wformat=2
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs #-Wunused
@@ -164,22 +182,33 @@ CFLAGS += -Wredundant-decls -Wnested-externs #-Winline -Wlong-long
CFLAGS += -Wunreachable-code
#CFLAGS += -Wcast-align
#CFLAGS += -std=c11
CFLAGS += -Wmissing-noreturn
#CFLAGS += -Wmissing-noreturn
#CFLAGS += -Wconversion
CFLAGS += -Wno-unused-but-set-variable -Wno-unused-variable
CFLAGS += -Wno-suggest-attribute=noreturn
# -mlong-calls -Wall
#CFLAGS += -save-temps -fverbose-asm
#CFLAGS += -Wa,-a,-ad
CFLAGS += -D__ARM -fno-builtin
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
CFLAGS += -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DALLOW_PEER_ERASE=$(ALLOW_PEER_ERASE)
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
# Disable stack protector by default (OS#5081)
ifeq ($(STACK_PROTECTOR), 1)
CFLAGS += -fstack-protector
else
CFLAGS += -fno-stack-protector
endif
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--print-memory-usage -Wl,--no-undefined $(LIB)
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--no-undefined $(LIB)
ifeq ("$(USE_CLANG)","0")
LDFLAGS += -Wl,--warn-section-align -Wl,--print-memory-usage
endif
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
# Append BIN directories to output filename
@@ -189,7 +218,7 @@ OUTPUT := $(BIN)/$(OUTPUT)
# Rules
#-------------------------------------------------------------------------------
all: apps/$(APP)/usb_strings_generated.h $(BIN) $(OBJ) $(MEMORIES)
all: $(BIN) $(OBJ) $(MEMORIES)
combined: $(OUTPUT)-combined.bin
@@ -200,7 +229,7 @@ $(BIN)/$(BOARD)-dfu-flash-padded.bin: $(BIN)/$(BOARD)-dfu-flash.bin
$(OUTPUT)-combined.bin: $(BIN)/$(BOARD)-dfu-flash-padded.bin $(OUTPUT)-dfu.bin
cat $^ > $@
$(BIN) $(OBJ):
$(BIN) $(OBJ): apps/$(APP)/usb_strings_generated.h
mkdir -p $@
usbstring/usbstring: usbstring/usbstring.c
@@ -216,26 +245,48 @@ apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt.patched usbstri
define RULES
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
EXTRA_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(EXTRA_OBJECTS))
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
$(SILENT)$(CC) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
$(SILENT)$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
$(SILENT)$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
$(SILENT)$(SIZE) $$^ $(OUTPUT)-$$@.elf
build_$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1)) $$(EXTRA_OBJECTS_$(1))
$(SILENT)$(CC) $(CFLAGS) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$(1).ld" -Wl,-Map,$(OUTPUT)-$(1).map -o $(OUTPUT)-$(1).elf $$^ $(LIBS)
$(SILENT)$(NM) $(OUTPUT)-$(1).elf >$(OUTPUT)-$(1).elf.txt
$(SILENT)$(OBJCOPY) -O binary $(OUTPUT)-$(1).elf $(OUTPUT)-$(1).bin
$(SILENT)$(SIZE) $$^ $(OUTPUT)-$(1).elf
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
@echo [COMPILING $$<]
$(SILENT)$(CC) $(CFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -Wa,-ahlms=$(BIN)/$$*.lst -c -o $$@ $$<
$(SILENT)$(CC) $(CFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
@echo [ASSEMBLING $$@]
$(SILENT)@$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
$(SILENT)$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
debug_$(1): $(1)
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
endef
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
ALL_MEMORIES = dfu flash ram
$(foreach MEMORY, $(ALL_MEMORIES), $(eval $(call RULES,$(MEMORY))))
# files with those names do exist..
.PHONY: ram
.PHONY: dfu
.PHONY: flash
ram: build_ram
dfu: build_dfu
ifeq ($(APP), blupdate)
$(info updating updater section with padded bootloader file..)
$(SILENT)dd if=/dev/zero bs=16384 count=1 of=$(BIN)/$(BOARD)-dfu-flash-padded.bin
$(SILENT)dd if=$(BIN)/$(BOARD)-dfu-flash.bin conv=notrunc of=$(BIN)/$(BOARD)-dfu-flash-padded.bin
$(SILENT)$(OBJCOPY) --update-section .blupdate=bin/$(BOARD)-dfu-flash-padded.bin bin/$(BOARD)-blupdate-dfu.elf
$(SILENT)$(OBJCOPY) -O binary bin/$(BOARD)-blupdate-dfu.elf bin/$(BOARD)-blupdate-dfu.bin
endif
flash: build_flash
#alternate way of embedding: obj file
#ifeq ($(APP), dfu)
# $(info bootloader bin file to obj..)
# $(SILENT)$(OBJCOPY) --rename-section .data=.fwupdate -I binary -O elf32-littlearm bin/$(BOARD)-dfu-flash.bin $(OBJ)/flash_fwupdate.o
#endif
program:
openocd -f openocd/openocd.cfg -c "init" -c "halt" -c "flash write_bank 0 ./bin/project-flash.bin 0" -c "reset" -c "shutdown"

View File

@@ -0,0 +1,12 @@
C_FILES += $(C_LIBUSB_DFU)
# Trace level used for compilation
# (can be overridden by adding TRACE_LEVEL=#number to the command-line)
# TRACE_LEVEL_DEBUG 5
# TRACE_LEVEL_INFO 4
# TRACE_LEVEL_WARNING 3
# TRACE_LEVEL_ERROR 2
# TRACE_LEVEL_FATAL 1
# TRACE_LEVEL_NO_TRACE 0
TRACE_LEVEL ?= 3

View File

@@ -0,0 +1,134 @@
/* SIMtrace 2 firmware USB DFU bootloader
*
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2018-2019 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 "board.h"
#include "core_cm3.h"
#include "flashd.h"
#include "utils.h"
#include "usb/device/dfu/dfu.h"
#include "usb/common/dfu/usb_dfu.h"
#include "manifest.h"
#include "USBD_HAL.h"
#include <osmocom/core/timer.h>
/* actual section content must be replaced with the padded bootloader by running objcopy! */
const uint32_t bl_update_data[BOARD_DFU_BOOT_SIZE / sizeof(uint32_t)] __attribute__((section(".fwupdate"))) = { 0xFF };
unsigned int g_unique_id[4];
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
static bool watchdog_configured = false;
extern uint32_t _end;
extern uint32_t _srelocate;
extern uint32_t _etext;
void DFURT_SwitchToDFU(void)
{
}
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request)
{
}
int USBDFU_handle_dnload(uint8_t altif, unsigned int offset, uint8_t *data, unsigned int len)
{
return 0;
}
int USBDFU_handle_upload(uint8_t altif, unsigned int offset, uint8_t *data, unsigned int req_len)
{
return 0;
}
int USBDFU_OverrideEnterDFU(void)
{
return 0;
}
__attribute__((section(".ramfunc"), noinline)) static uint32_t flash_wait_ready()
{
Efc *efc = EFC;
uint32_t dwStatus;
do {
dwStatus = efc->EEFC_FSR;
} while ((dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));
}
__attribute__((section(".ramfunc"), noinline)) static void flash_cmd(uint32_t dwCommand, uint32_t dwArgument)
{
Efc *efc = EFC;
uint32_t dwStatus;
efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand);
}
__attribute__((section(".ramfunc"), noinline, noreturn)) static void erase_first_app_sector()
{
/* page 64 */
uint32_t first_app_page = (BOARD_DFU_BOOT_SIZE / IFLASH_PAGE_SIZE);
uint32_t *first_app_address = (uint32_t *)(IFLASH_ADDR + first_app_page * IFLASH_PAGE_SIZE + 0);
#if 1
/* overwrite first app sector so we don't keep booting this */
for (int i = 0; i < IFLASH_PAGE_SIZE / 4; i++)
first_app_address[i] = 0xffffffff;
flash_cmd(EFC_FCMD_EWP, first_app_page);
#else
/* why does erasing the whole flash with a protected bootloader not work at all? */
flash_cmd(EFC_FCMD_EA, 0);
#endif
flash_wait_ready();
for (;;)
NVIC_SystemReset();
}
#define MAX_USB_ITER BOARD_MCK / 72 // This should be around a second
extern int main(void)
{
uint8_t isUsbConnected = 0;
unsigned int i = 0;
uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
/* Enable watchdog for 2000ms, with no window */
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT | (WDT_GetPeriod(2000) << 16) |
WDT_GetPeriod(2000));
watchdog_configured = true;
EEFC_ReadUniqueID(g_unique_id);
printf("\n\r\n\r");
printf("bootloader updater %s for board %s\n\r"
"(C) 2010-2017 by Harald Welte, 2018-2019 by Kevin Redon\n\r",
manifest_revision, manifest_board);
/* clear g_dfu on power-up reset */
memset(g_dfu, 0, sizeof(*g_dfu));
TRACE_INFO("USB init...\n\r");
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
USBD_Disconnect();
/* Initialize the flash to be able to write it, using the IAP ROM code */
FLASHD_Initialize(BOARD_MCK, 1);
__disable_irq();
FLASHD_Unlock(IFLASH_ADDR, IFLASH_ADDR + IFLASH_SIZE - 1, 0, 0);
FLASHD_Write(IFLASH_ADDR, bl_update_data, BOARD_DFU_BOOT_SIZE);
erase_first_app_sector();
}

View File

@@ -0,0 +1,6 @@
sysmocom - s.f.m.c. GmbH
PRODUCT_STRING
bootloader updater
RAM
Flash (Application Partition)
Flash (Bootloader Partition)

View File

@@ -71,8 +71,13 @@ static const conf_func config_func_ptrs[] = {
.init = mode_cardemu_init,
.exit = mode_cardemu_exit,
.run = mode_cardemu_run,
#if defined (ngff_cardem)
.usart0_irq = mode_cardemu_usart1_irq,
.usart1_irq = mode_cardemu_usart0_irq,
#else
.usart0_irq = mode_cardemu_usart0_irq,
.usart1_irq = mode_cardemu_usart1_irq,
#endif
},
#endif
#ifdef HAVE_MITM

View File

@@ -271,7 +271,7 @@ extern int main(void)
#ifdef PINS_LEDS
/* Configure LED */
PIO_Configure(pinsLeds, sizeof(pinsLeds));
PIO_Configure(pinsLeds, PIO_LISTSIZE(pinsLeds));
PIO_Set(&pinsLeds[LED_NUM_RED]);
PIO_Clear(&pinsLeds[LED_NUM_GREEN]);
#endif
@@ -342,16 +342,7 @@ extern int main(void)
TRACE_INFO("USB init...\n\r");
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
USBD_Disconnect();
#ifdef PIN_USB_PULLUP
const Pin usb_dp_pullup = PIN_USB_PULLUP;
PIO_Configure(&usb_dp_pullup, 1);
PIO_Set(&usb_dp_pullup);
#endif
mdelay(50);
#ifdef PIN_USB_PULLUP
PIO_Clear(&usb_dp_pullup);
#endif
mdelay(500);
USBDFU_Initialize(&dfu_descriptors);
while (USBD_GetState() < USBD_STATE_CONFIGURED) {

View File

@@ -151,8 +151,7 @@ WEAK void HardFault_Handler( void )
" mrseq r0, msp \n"
" mrsne r0, psp \n"
//" ldr r1, [r0, #24] \n"
" b hard_fault_handler_c\n"
".syntax divided \n");
" b hard_fault_handler_c\n");
}
/**

View File

@@ -31,7 +31,8 @@ enum led_pattern {
BLINK_200O_F = 7,
BLINK_600O_F = 8,
BLINK_CUSTOM = 9,
BLINK_2F_O,
BLINK_2F_O = 10,
BLINK_5O_5F = 11,
_NUM_LED_BLINK
};

View File

@@ -96,13 +96,18 @@ SECTIONS
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
/DISCARD/ :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
*(.ARM.exidx)
}
.blupdate :
{
. = ALIGN(4);
_blupdate_start = .;
KEEP(*(.fwupdate .fwupdate.*));
_blupdate_end = .;
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;

View File

@@ -94,13 +94,10 @@ SECTIONS
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
/DISCARD/ :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
*(.ARM.exidx)
}
. = ALIGN(4);
_etext = .;

View File

@@ -58,6 +58,10 @@ static const struct blink_state bs_on[] = {
{ 0, 1 }
};
static const struct blink_state bs_5on_5off[] = {
{ 500, 1 }, { 500, 0 }
};
static const struct blink_state bs_3on_5off[] = {
{ 300, 1 }, { 500, 0 }
};
@@ -107,6 +111,10 @@ static const struct blink_pattern patterns[] = {
.states = bs_on,
.size = ARRAY_SIZE(bs_on),
},
[BLINK_5O_5F] = {
.states = bs_5on_5off,
.size = ARRAY_SIZE(bs_5on_5off),
},
[BLINK_3O_5F] = {
.states = bs_3on_5off,
.size = ARRAY_SIZE(bs_3on_5off),

View File

@@ -0,0 +1,166 @@
/* 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_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
#define PIN_USIM2_nRST {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
//#define PIN_USIM2_VCC {PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
#define PINS_USIM1 PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST
#define PINS_USIM2 PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST
/* from v3 and onwards only (!) */
#define PIN_DET_USIM1_PRES {PIO_PA8, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
/* inputs reading the WWAN LED level */
#define PIN_WWAN1 {PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
#define PINS_WWAN_IN { PIN_WWAN1 }
#define PIN_MODEM_EN {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define PIN_N_MODEM_PWR_ON {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* outputs controlling RESET input of modems */
#define PIN_PERST1 {PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define PINS_PERST { PIN_PERST1 }
#define PIN_VERSION_DET {PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
/* GPIO towards SPDT switches between real SIM and SAM3 */
//#define PIN_SIM_SWITCH1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
//#define PIN_SIM_SWITCH2 {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_NGFF_CARDEM
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_NGFF_CARDEM
#define BOARD_USB_RELEASE 0x010
#define DETECT_VCC_BY_ADC
#define VCC_UV_THRESH_1V8 1500000
#define VCC_UV_THRESH_3V VCC_UV_THRESH_1V8
#ifdef APPLICATION_cardem
#define HAVE_CARDEM
#define HAVE_BOARD_CARDINSERT
struct cardem_inst;
void board_set_card_insert(struct cardem_inst *ci, bool card_insert);
#endif
#ifdef APPLICATION_trace
#define HAVE_SNIFFER
#endif
/* Card I/O data signal input/output (I/O_SIM in schematic) */
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Card CLK clock input (CLK_SIM in schematic) */
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Card RST reset signal input (use as input since the phone will drive it) */
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
/* Pins used to sniff phone-card communication */
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
#define PIN_SIM_CLK_INPUT {PIO_PA4B_TCLK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pins used to measure ETU timing (using timer counter) */
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
//default state: NO uart connected, modem connected to physical sim, NO sim presence override, modem powers sim slot
#define pin_conn_usim1_default {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_conn_usim2_default {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_conn_mdm_sim_default {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_conn_set_sim_det_default {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_en_st_sim_vdd_default {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_en_mdm_sim_vdd_default {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
//cardem state: uart2 (!) connected, NO modem connected to physical sim, sim presence override, NOTHING powers sim slot
#define pin_conn_usim1_cem {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_conn_usim2_cem {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_conn_mdm_sim_cem {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_en_st_sim_vdd_cem {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_en_mdm_sim_vdd_cem {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
//trace state: uart2 (!) connected, modem connected to physical sim, st powers sim slot
#define pin_conn_usim1_trace {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_conn_usim2_trace {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_conn_mdm_sim_trace {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define pin_conn_set_sim_det_trace {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_en_st_sim_vdd_trace {PIO_PB2, PIOB, ID_PIOB, PIO_OUTPUT_1, PIO_DEFAULT}
#define pin_en_mdm_sim_vdd_trace {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define PIN_MODEM_EN_off {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#define PINS_SIM_DEFAULT pin_conn_usim1_default, pin_conn_usim2_default, pin_conn_mdm_sim_default, pin_conn_set_sim_det_default, PIN_N_MODEM_PWR_ON, PIN_MODEM_EN, pin_en_st_sim_vdd_default, pin_en_mdm_sim_vdd_default
#define PINS_SIM_CARDEM pin_conn_usim1_cem, pin_conn_usim2_cem, pin_conn_mdm_sim_cem, pin_en_mdm_sim_vdd_cem, pin_en_st_sim_vdd_cem// , pin_conn_set_sim_det_cem
#define PINS_BUS_SNIFF pin_conn_usim1_trace, pin_conn_usim2_trace, pin_conn_mdm_sim_trace, pin_conn_set_sim_det_trace,PIN_MODEM_EN_off
#define PINS_PWR_SNIFF PIN_N_MODEM_PWR_ON, PIN_MODEM_EN, pin_en_st_sim_vdd_trace, pin_en_mdm_sim_vdd_trace

View 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);

View 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);

View 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);

View File

@@ -0,0 +1 @@
ngff-cardem

View File

@@ -0,0 +1,159 @@
/* sysmocom ngff-cardem 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("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
printf("\t!\tSwitch Channel A from physical -> remote\n\r");
printf("\tt\t(pseudo)talloc report\n\r");
break;
case 'R':
printf("Asking NVIC to reset us\n\r");
USBD_Disconnect();
NVIC_SystemReset();
break;
case 'l':
led_blink(LED_GREEN, BLINK_ALWAYS_OFF);
printf("LED 1 switched off\n\r");
break;
case 'L':
led_blink(LED_GREEN, BLINK_ALWAYS_ON);
printf("LED 1 switched on\n\r");
break;
case 'g':
led_blink(LED_RED, BLINK_ALWAYS_OFF);
printf("LED 2 switched off\n\r");
break;
case 'G':
led_blink(LED_RED, BLINK_ALWAYS_ON);
printf("LED 2 switched on\n\r");
break;
case '1':
printf("Resetting Modem\n\r");
wwan_perst_do_reset_pulse(0, 300);
break;
case '!':
sim_switch_use_physical(0, 0);
break;
case 't':
talloc_report(NULL, stdout);
break;
default:
printf("Unknown command '%c'\n\r", ch);
break;
}
}
void board_main_top(void)
{
#ifndef APPLICATION_dfu
usb_buf_init();
wwan_led_init();
wwan_perst_init();
sim_switch_init();
#endif
/* Obtain the circuit board version (currently just prints voltage) */
get_board_version_adc();
#ifndef APPLICATION_dfu
/* Initialize checking for card insert/remove events */
card_present_init();
#endif
wwan_perst_set(0, 0);
}
static int uart_has_loopback_jumper(void)
{
unsigned int i;
const Pin uart_loopback_pins[] = {
{PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT},
{PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
};
/* Configure UART pins as I/O */
PIO_Configure(uart_loopback_pins, PIO_LISTSIZE(uart_loopback_pins));
/* Send pattern over UART TX and check if it is received on RX
* If the loop doesn't get interrupted, RxD always follows TxD and thus a
* loopback jumper has been placed on RxD/TxD, and we will boot
* into DFU unconditionally
*/
int has_loopback_jumper = 1;
for (i = 0; i < 10; i++) {
/* Set TxD high; abort if RxD doesn't go high either */
PIO_Set(&uart_loopback_pins[1]);
if (!PIO_Get(&uart_loopback_pins[0])) {
has_loopback_jumper = 0;
break;
}
/* Set TxD low, abort if RxD doesn't go low either */
PIO_Clear(&uart_loopback_pins[1]);
if (PIO_Get(&uart_loopback_pins[0])) {
has_loopback_jumper = 0;
break;
}
}
/* Put pins back to UART mode */
const Pin uart_pins[] = {PINS_UART};
PIO_Configure(uart_pins, PIO_LISTSIZE(uart_pins));
return has_loopback_jumper;
}
int board_override_enter_dfu(void)
{
/* If the loopback jumper is set, we enter DFU mode */
if (uart_has_loopback_jumper())
return 1;
return 0;
}
static const Pin deton = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
static const Pin detoff = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT};
void board_set_card_insert(struct cardem_inst *ci, bool card_insert)
{
PIO_Configure(card_insert ? &deton : &detoff, 1);
}

View 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];
/* high active here */
present = PIO_Get(pin);
return present;
}
static void cardpres_tmr_cb(void *data)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(pin_cardpres); i++) {
int state = is_card_present(i);
if (state != last_state[i]) {
TRACE_INFO("%u: Card Detect Status %d -> %d\r\n", i, last_state[i], state);
/* FIXME: report to USB host */
last_state[i] = state;
}
}
osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
}
int card_present_init(void)
{
unsigned int i;
PIO_Configure(pin_cardpres, ARRAY_SIZE(pin_cardpres));
/* start timer */
cardpres_timer.cb = cardpres_tmr_cb;
osmo_timer_schedule(&cardpres_timer, 0, TIMER_INTERVAL_MS*1000);
return 2;
}

View File

@@ -0,0 +1,81 @@
/* 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"
//uart12bus 2-20e pa20
//uart22bus 1-20e pa28
//usim2bus 1-10e pa0 pivot
//sim det 2-10e pa13
static const Pin pins_default[] = {PINS_SIM_DEFAULT};
static const Pin pins_cem[] = {PINS_SIM_CARDEM};
static int initialized = 0;
int sim_switch_use_physical(unsigned int nr, int physical)
{
const Pin pin = PIN_MODEM_EN;// PIN_N_MODEM_PWR_ON;
enum led led;
if (!initialized) {
TRACE_ERROR("Somebody forgot to call sim_switch_init()\r\n");
sim_switch_init();
}
TRACE_INFO("Modem %d: %s SIM\n\r", nr,
physical ? "physical" : "virtual");
switch (nr) {
case 0:
led = LED_USIM1;
break;
default:
TRACE_ERROR("Invalid SIM%u\n\r", nr);
return -1;
}
if (physical) {
TRACE_INFO("%u: Use local/physical SIM\r\n", nr);
PIO_Configure(pins_default, PIO_LISTSIZE(pins_default));
led_blink(led, BLINK_ALWAYS_ON);
} else {
TRACE_INFO("%u: Use remote/emulated SIM\r\n", nr);
PIO_Configure(pins_cem, PIO_LISTSIZE(pins_cem));
led_blink(led, BLINK_5O_5F);
}
/* just power cycle the modem because this circumvents weird issues with unreliable signals */
PIO_Clear(&pin);
mdelay(200);
PIO_Set(&pin);
return 0;
}
int sim_switch_init(void)
{
PIO_Configure(pins_default, PIO_LISTSIZE(pins_default));
initialized = 1;
return 1;
}

View 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 given WWAN led is currently active or not */
int wwan_led_active(int wwan)
{
const Pin *pin;
int active;
switch (wwan) {
#ifdef PIN_WWAN1
case 0:
pin = &pin_wwan1;
break;
#endif
#ifdef PIN_WWAN2
case 1:
pin = &pin_wwan2;
break;
#endif
default:
return -1;
}
active = PIO_Get(pin) ? 0 : 1;
return active;
}
int wwan_led_init(void)
{
int num_leds = 0;
#ifdef PIN_WWAN1
PIO_Configure(&pin_wwan1, 1);
PIO_ConfigureIt(&pin_wwan1, wwan1_irqhandler);
PIO_EnableIt(&pin_wwan1);
num_leds++;
#endif
#ifdef PIN_WWAN2
PIO_Configure(&pin_wwan2, 1);
PIO_ConfigureIt(&pin_wwan2, wwan2_irqhandler);
PIO_EnableIt(&pin_wwan2);
num_leds++;
#endif
return num_leds;
}

View 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;
}

View File

@@ -50,81 +50,28 @@
/* Button to force bootloader start (shorted to ground when pressed */
#define PIN_BOOTLOADER_SW {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
//FIXME SIM_PWEN_PIN collides with PA5/bootloader_sw on octsimtest
/* Enable powering the card using the second 3.3 V output of the LDO (active high) */
#define SIM_PWEN_PIN {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Enable powering the SIM card */
#define PWR_PINS SIM_PWEN_PIN
// FIXME PA8 is 32khz xtal on octsimtest
/* Card presence pin */
#define SW_SIM PIO_PA11
/* Pull card presence pin high (shorted to ground in card slot when card is present) */
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
/** Smart card connection **/
//FIXME
/* Card RST reset signal input (active low; RST_SIM in schematic) */
#define PIN_SIM_RST {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Card I/O data signal input/output (I/O_SIM in schematic) */
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Card CLK clock input (CLK_SIM in schematic) */
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
//FIXME PIO_PA4B_TCLK0 PA4 is LED on octsimtest
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
#define PIN_SIM_CLK_INPUT {PIO_PA14, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pins used to measure ETU timing (using timer counter) */
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
/** Phone connection **/
/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_EDGE | PIO_DEGLITCH }
/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
#define PIN_PHONE_IO {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Phone CLK clock input (CLK_PHONE in schematic) */
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Pin used to switch level shifter in I/O line between rx (0) and tx (1) */
#define PIN_USIM1_IO_DIR {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Pin used for phone USIM slot 1 communication */
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST, PIN_USIM1_IO_DIR
/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
#define PIN_PHONE_IO_INPUT {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
#define PIN_PHONE_CLK_INPUT {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/** Default pin configuration **/
/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
/** Sniffer configuration **/
/* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
/* Card RST reset signal input (use as input since the phone will drive it) */
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
/* Pins used to sniff phone-card communication */
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
/* Disable power converter 4.5-6V to 3.3V (active high) */
#define PIN_SIM_PWEN_SNIFF {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
#define PIN_VCC_FWD_SNIFF {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Use phone VCC to power card */
#define PINS_PWR_SNIFF PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
/** CCID configuration */
/* Card RST reset signal input (active low; RST_SIM in schematic) */
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* ISO7816-communication related pins */
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
/** External SPI flash interface **/
/* SPI MISO pin definition */
@@ -140,30 +87,36 @@
/* SPI flash write protect pin (active low, pulled low) */
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/** Pin configuration to control USB pull-up on D+
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
*/
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/** USB definitions */
/* OpenMoko SIMtrace 2 USB vendor ID */
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_OCTSIMTEST
/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_OCTSIMTEST
/* USB release number (bcdDevice, shown as 0.00) */
#define BOARD_USB_RELEASE 0x000
/* Indicate SIMtrace is bus power in USB attributes */
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
#define DETECT_VCC_BY_ADC
/* we have a resistive voltage divider of 47 + 30 kOhms to also detect 5V supply power */
#define VCC_UV_THRESH_1V8 (1500000*47)/(47+30)
#define VCC_UV_THRESH_3V (2500000*47)/(47+30)
#define HAVE_SLOT_MUX
#define HAVE_BOARD_CARDINSERT
struct cardem_inst;
void board_set_card_insert(struct cardem_inst *ci, bool card_insert);
/** Supported modes */
/* SIMtrace board supports sniffer mode */
//#define HAVE_SNIFFER
/* SIMtrace board supports CCID mode */
//#define HAVE_CCID
/* SIMtrace board supports card emulation mode */
//#define HAVE_CARDEM
#define HAVE_CARDEM
/* SIMtrace board supports man-in-the-middle mode */
//#define HAVE_MITM
/* octsimtest board supports gpio_test mode */

View File

@@ -18,8 +18,10 @@
#define MCP23017_ADDRESS 0x20
int mcp23017_init(uint8_t slave);
int mcp23017_init(uint8_t slave, uint8_t iodira, uint8_t iodirb);
int mcp23017_test(uint8_t slave);
int mcp23017_toggle(uint8_t slave);
int mcp23017_set_output_a(uint8_t slave, uint8_t val);
int mcp23017_set_output_b(uint8_t slave, uint8_t val);
//int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
//int mcp23017_read_byte(uint8_t slave, uint8_t addr);

View File

@@ -0,0 +1,17 @@
#pragma once
void mux_init(void);
int mux_set_slot(uint8_t s);
int mux_get_slot(void);
void mux_set_freq(uint8_t s);
/* this reflects the wiring between U5 and U4 */
#define MUX_FREQ_DIV_2 0
#define MUX_FREQ_DIV_4 1
#define MUX_FREQ_DIV_16 2
#define MUX_FREQ_DIV_32 3
#define MUX_FREQ_DIV_32 3
#define MUX_FREQ_DIV_128 4
#define MUX_FREQ_DIV_512 5
#define MUX_FREQ_DIV_2048 6
#define MUX_FREQ_DIV_4096 7

View File

@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdbool.h>
#include "board.h"
#include "simtrace.h"
#include "utils.h"
@@ -25,16 +26,29 @@
#include "usb_buf.h"
#include "i2c.h"
#include "mcp23017.h"
#include "mux.h"
static bool mcp2317_present = false;
void board_exec_dbg_cmd(int ch)
{
switch (ch) {
case '?':
printf("\t?\thelp\n\r");
printf("\t0-8\tselect physical SIM slot\n\r");
printf("\tR\treset SAM3\n\r");
printf("\tm\trun mcp23017 test\n\r");
printf("\tR\ttoggle MSB of gpio on mcp23017\n\r");
printf("\ti\tset card insert via I2C\n\r");
printf("\tI\tdisable card insert\n\r");
break;
case '0': mux_set_slot(0); break;
case '1': mux_set_slot(1); break;
case '2': mux_set_slot(2); break;
case '3': mux_set_slot(3); break;
case '4': mux_set_slot(4); break;
case '5': mux_set_slot(5); break;
case '6': mux_set_slot(6); break;
case '7': mux_set_slot(7); break;
case 'R':
printf("Asking NVIC to reset us\n\r");
USBD_Disconnect();
@@ -43,8 +57,13 @@ void board_exec_dbg_cmd(int ch)
case 'm':
mcp23017_test(MCP23017_ADDRESS);
break;
case 't':
mcp23017_toggle(MCP23017_ADDRESS);
case 'i':
printf("Setting card insert (slot=%u)\r\n", mux_get_slot());
mcp23017_set_output_a(MCP23017_ADDRESS, (1 << mux_get_slot()));
break;
case 'I':
printf("Releasing card insert (slot=%u)\r\n", mux_get_slot());
mcp23017_set_output_a(MCP23017_ADDRESS, 0);
break;
default:
printf("Unknown command '%c'\n\r", ch);
@@ -57,9 +76,13 @@ void board_main_top(void)
#ifndef APPLICATION_dfu
usb_buf_init();
mux_init();
i2c_pin_init();
if (!mcp23017_init(MCP23017_ADDRESS))
printf("mcp23017 not found!\n\r");
/* PORT A: all outputs, Port B0 output, B1..B7 unused */
if (mcp23017_init(MCP23017_ADDRESS, 0x00, 0xfe) == 0) {
mcp2317_present = true;
mcp23017_set_output_a(MCP23017_ADDRESS, 0);
}
/* Initialize checking for card insert/remove events */
//card_present_init();
#endif
@@ -79,3 +102,23 @@ int board_override_enter_dfu(void)
} else
return 0;
}
void board_set_card_insert(struct cardem_inst *ci, bool card_insert)
{
int s = mux_get_slot();
/* A0 .. A7 of the MCP are each connected to the gate of a FET which closes
* the sim-present signal of the respective slot */
if (mcp2317_present) {
if (card_insert) {
/* we must enable card-presence of the active slot and disable it on all others */
mcp23017_set_output_a(MCP23017_ADDRESS, (1 << s));
} else {
/* we disable all card insert signals */
mcp23017_set_output_a(MCP23017_ADDRESS, 0);
}
} else {
TRACE_WARNING("No MCP23017 present; cannot set CARD_INSERT\r\n");
}
}

View File

@@ -92,19 +92,25 @@ out_stop:
return 0;
}
int mcp23017_init(uint8_t slave)
int mcp23017_init(uint8_t slave, uint8_t iodira, uint8_t iodirb)
{
printf("mcp23017_init\n\r");
TRACE_DEBUG("mcp23017_init\n\r");
// all gpio input
if (mcp23017_write_byte(slave, MCP23017_IODIRA, 0xff))
return false;
if (mcp23017_write_byte(slave, MCP23017_IODIRA, iodira))
goto out_err;
// msb of portb output, rest input
if (mcp23017_write_byte(slave, MCP23017_IODIRB, 0x7f))
return false;
if (mcp23017_write_byte(slave, MCP23017_IODIRB, iodirb))
goto out_err;
if (mcp23017_write_byte(slave, MCP23017_IOCONA, 0x20)) //disable SEQOP (autoinc addressing)
return false;
printf("mcp23017 found\n\r");
return true;
goto out_err;
TRACE_DEBUG("mcp23017 found\n\r");
return 0;
out_err:
TRACE_WARNING("mcp23017 NOT found!\n\r");
return -1;
}
int mcp23017_test(uint8_t slave)
@@ -120,6 +126,16 @@ int mcp23017_test(uint8_t slave)
return 0;
}
int mcp23017_set_output_a(uint8_t slave, uint8_t val)
{
return mcp23017_write_byte(slave, MCP23017_OLATA, val);
}
int mcp23017_set_output_b(uint8_t slave, uint8_t val)
{
return mcp23017_write_byte(slave, MCP23017_OLATB, val);
}
int mcp23017_toggle(uint8_t slave)
{
// example writing MSB of gpio

View File

@@ -0,0 +1,113 @@
/* sysmoOCTSIMTEST support for multiplexers
*
* (C) 2021 by Harald Welte <laforge@gnumonks.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 "mux.h"
#include <stdbool.h>
#include <errno.h>
/* 3-bit S0..S2 signal for slot selection */
static const Pin pin_in_sel[3] = {
{ PIO_PA1, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
{ PIO_PA2, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
{ PIO_PA3, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
};
/* 3-bit S0..S2 signal for frequency divider selection */
static const Pin pin_freq_sel[3] = {
{ PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
{ PIO_PA17, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
{ PIO_PA18, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT },
};
/* low-active output enable for all muxes */
static const Pin pin_oe = { PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT };
static uint8_t g_mux_slot = 0;
/* initialize the external 1:8 multiplexers */
void mux_init(void)
{
PIO_Configure(&pin_oe, PIO_LISTSIZE(pin_oe));
PIO_Configure(pin_in_sel, PIO_LISTSIZE(pin_in_sel));
PIO_Configure(pin_freq_sel, PIO_LISTSIZE(pin_freq_sel));
mux_set_slot(0);
}
/* set the slot selection mux */
int mux_set_slot(uint8_t s)
{
TRACE_INFO("%s(%u)\r\n", __func__, s);
if (s > 7)
return -EINVAL;
/* !OE = H: disconnect input and output of muxes */
PIO_Set(&pin_oe);
if (s & 1)
PIO_Set(&pin_in_sel[0]);
else
PIO_Clear(&pin_in_sel[0]);
if (s & 2)
PIO_Set(&pin_in_sel[1]);
else
PIO_Clear(&pin_in_sel[1]);
if (s & 4)
PIO_Set(&pin_in_sel[2]);
else
PIO_Clear(&pin_in_sel[2]);
/* !OE = L: (re-)enable the output of muxes */
PIO_Clear(&pin_oe);
g_mux_slot = s;
return s;
}
int mux_get_slot(void)
{
return g_mux_slot;
}
/* set the frequency divider mux */
void mux_set_freq(uint8_t s)
{
TRACE_INFO("%s(%u)\r\n", __func__, s);
/* no need for 'break before make' here, this would also affect
* the SIM card I/O signals which we don't want to disturb */
if (s & 1)
PIO_Set(&pin_freq_sel[0]);
else
PIO_Clear(&pin_freq_sel[0]);
if (s & 2)
PIO_Set(&pin_freq_sel[1]);
else
PIO_Clear(&pin_freq_sel[1]);
if (s & 4)
PIO_Set(&pin_freq_sel[2]);
else
PIO_Clear(&pin_freq_sel[2]);
/* !OE = L: ensure enable the output of muxes */
PIO_Clear(&pin_oe);
}

View File

@@ -0,0 +1,37 @@
/* Code to switch between local (physical) and remote (emulated) SIM
*
* (C) 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 "board.h"
#include "trace.h"
#include "sim_switch.h"
int sim_switch_use_physical(unsigned int nr, int physical)
{
if (physical) {
TRACE_ERROR("%u: Use local/physical SIM - UNSUPPORTED!\r\n", nr);
} else {
TRACE_INFO("%u: Use remote/emulated SIM\r\n", nr);
}
return 0;
}
int sim_switch_init(void)
{
return 1; // SIMtrace hardware has only one switchable interface
}

View File

@@ -109,6 +109,9 @@
#define BOARD_USB_RELEASE 0x010
#define CARDEMU_SECOND_UART
#define DETECT_VCC_BY_ADC
#define VCC_UV_THRESH_1V8 1500000
#define VCC_UV_THRESH_3V 2500000
#define HAVE_CARDEM

View File

@@ -135,11 +135,6 @@
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
#endif
/** Pin configuration to control USB pull-up on D+
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
*/
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/** USB definitions */
/* OpenMoko SIMtrace 2 USB vendor ID */
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO

View File

@@ -40,7 +40,7 @@
/** green LED pin definition */
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/** LEDs pin definition */
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
/** index for red LED in LEDs pin definition array */
#define LED_NUM_RED 0
/** index for green LED in LEDs pin definition array */
@@ -134,11 +134,6 @@
/* SPI flash write protect pin (active low, pulled low) */
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/** Pin configuration to control USB pull-up on D+
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
*/
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/** USB definitions */
/* OpenMoko SIMtrace 2 USB vendor ID */
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
@@ -153,10 +148,14 @@
/** Supported modes */
/* SIMtrace board supports sniffer mode */
#ifdef APPLICATION_trace
#define HAVE_SNIFFER
#endif
/* SIMtrace board supports CCID mode */
//#define HAVE_CCID
/* SIMtrace board supports card emulation mode */
//#define HAVE_CARDEM
#ifdef APPLICATION_cardem
#define HAVE_CARDEM
#endif
/* SIMtrace board supports man-in-the-middle mode */
//#define HAVE_MITM

View File

@@ -269,6 +269,8 @@ struct cardemu_usb_msg_error {
struct cardemu_usb_msg_config {
/* bit-mask of CEMU_FEAT_F flags */
uint32_t features;
/* the selected slot number (if an external mux is present) */
uint8_t slot_mux_nr;
} __attribute__ ((packed));
/***********************************************************************

View File

@@ -25,6 +25,8 @@
#define USB_PRODUCT_QMOD_SAM3 0x4004
#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

View File

@@ -33,6 +33,9 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#ifdef HAVE_SLOT_MUX
#include "mux.h"
#endif
#define NUM_SLOTS 2
@@ -919,6 +922,7 @@ static int tx_byte_tpdu(struct card_handle *ch)
byte = msgb_pull_u8(msg);
card_emu_uart_tx(ch->uart_chan, byte);
card_emu_uart_reset_wt(ch->uart_chan);
/* this must happen _after_ the byte has been transmitted */
switch (ch->tpdu.state) {
@@ -1079,6 +1083,12 @@ static void card_emu_report_config(struct card_handle *ch)
cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
cfg->features = ch->features;
#ifdef HAVE_SLOT_MUX
cfg->slot_mux_nr = mux_get_slot();
#else
cfg->slot_mux_nr = 0;
#endif
usb_buf_upd_len_and_submit(msg);
}
@@ -1241,6 +1251,12 @@ int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_con
if (scfg_len >= sizeof(uint32_t))
ch->features = (scfg->features & SUPPORTED_FEATURES);
#ifdef HAVE_SLOT_MUX
if (scfg_len >= sizeof(uint32_t)+sizeof(uint8_t)) {
mux_set_slot(scfg->slot_mux_nr);
}
#endif
/* send back a report of our current configuration */
card_emu_report_config(ch);

View File

@@ -39,10 +39,26 @@ static const Pin pins_cardsim[] = PINS_CARDSIM;
#endif
/* UART pins */
#if defined(ngff_cardem)
static const Pin pins_usim1[] = {PINS_USIM2};
static const Pin pin_usim1_rst = PIN_USIM2_nRST;
#define FIRST_USART_BASE USART0
#define FIRST_USART_ID ID_USART0
#define FIRST_USART_IRQ USART0_IRQn
#else
static const Pin pins_usim1[] = {PINS_USIM1};
static const Pin pin_usim1_rst = PIN_USIM1_nRST;
#define FIRST_USART_BASE USART1
#define FIRST_USART_ID ID_USART1
#define FIRST_USART_IRQ USART1_IRQn
#endif
static const Pin pin_usim1_vcc = PIN_USIM1_VCC;
#ifdef PIN_USIM1_IO_DIR
static const Pin pin_io_dir = PIN_USIM1_IO_DIR;
#endif
#ifdef CARDEMU_SECOND_UART
static const Pin pins_usim2[] = {PINS_USIM2};
static const Pin pin_usim2_rst = PIN_USIM2_nRST;
@@ -70,7 +86,6 @@ struct cardem_inst {
const Pin pin_insert;
#ifdef DETECT_VCC_BY_ADC
uint32_t vcc_uv;
uint32_t vcc_uv_last;
#endif
bool vcc_active;
bool vcc_active_last;
@@ -82,8 +97,8 @@ struct cardem_inst cardem_inst[] = {
{
.num = 0,
.usart_info = {
.base = USART1,
.id = ID_USART1,
.base = FIRST_USART_BASE,
.id = FIRST_USART_ID,
.state = USART_RCV
},
.ep_out = SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT,
@@ -143,12 +158,27 @@ void card_emu_uart_wait_tx_idle(uint8_t uart_chan)
wait_tx_idle(usart);
}
static void card_emu_uart_set_direction(uint8_t uart_chan, bool tx)
{
/* only on some boards (octsimtest) we hae an external level
* shifter that requires us to switch the direction between RX and TX */
#ifdef PIN_USIM1_IO_DIR
if (uart_chan == 0) {
if (tx)
PIO_Set(&pin_io_dir);
else
PIO_Clear(&pin_io_dir);
}
#endif
}
/* call-back from card_emu.c to enable/disable transmit and/or receive */
void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
{
Usart *usart = get_usart_by_chan(uart_chan);
switch (rxtx) {
case ENABLE_TX:
card_emu_uart_set_direction(uart_chan, true);
USART_DisableIt(usart, ~(US_IER_TXRDY | US_IER_TIMEOUT));
/* as irritating as it is, we actually want to keep the
* receiver enabled during transmit */
@@ -174,6 +204,7 @@ void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
* transmitter enabled during receive */
USART_SetTransmitterEnabled(usart, 1);
wait_tx_idle(usart);
card_emu_uart_set_direction(uart_chan, false);;
usart->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
USART_EnableIt(usart, US_IER_RXRDY);
USART_SetReceiverEnabled(usart, 1);
@@ -234,7 +265,6 @@ static uint16_t compute_next_timeout(struct cardem_inst *ci)
* \param[in] inst_num Instance number, range 0..1 (some boards only '0' permitted) */
static void usart_irq_rx(uint8_t inst_num)
{
OSMO_ASSERT(inst_num < ARRAY_SIZE(cardem_inst));
Usart *usart = get_usart_by_chan(inst_num);
struct cardem_inst *ci = &cardem_inst[inst_num];
uint32_t csr;
@@ -390,6 +420,9 @@ void card_emu_uart_interrupt(uint8_t uart_chan)
***********************************************************************/
#ifdef DETECT_VCC_BY_ADC
#if !defined(VCC_UV_THRESH_1V8) || !defined(VCC_UV_THRESH_3V)
#error "You must define VCC_UV_THRESH_{1V1,3V} if you use ADC VCC detection"
#endif
static volatile int adc_triggered = 0;
static int adc_sam3s_reva_errata = 0;
@@ -438,19 +471,16 @@ static int card_vcc_adc_init(void)
return 0;
}
#define VCC_UV_THRESH_1V8 1500000
#define VCC_UV_THRESH_3V 2500000
static void process_vcc_adc(struct cardem_inst *ci)
{
if (ci->vcc_uv >= VCC_UV_THRESH_3V &&
ci->vcc_uv_last < VCC_UV_THRESH_3V) {
#ifdef octsimtest
if (ci->vcc_uv >= VCC_UV_THRESH_1V8)
#else
if (ci->vcc_uv >= VCC_UV_THRESH_3V)
#endif
ci->vcc_active = true;
} else if (ci->vcc_uv < VCC_UV_THRESH_3V &&
ci->vcc_uv_last >= VCC_UV_THRESH_3V) {
else
ci->vcc_active = false;
}
ci->vcc_uv_last = ci->vcc_uv;
}
void ADC_IrqHandler(void)
@@ -551,7 +581,7 @@ void mode_cardemu_init(void)
/* configure USART as ISO-7816 slave (e.g. card) */
ISO7816_Init(&cardem_inst[0].usart_info, CLK_SLAVE);
NVIC_EnableIRQ(USART1_IRQn);
NVIC_EnableIRQ(FIRST_USART_IRQ);
PIO_ConfigureIt(&pin_usim1_rst, usim1_rst_irqhandler);
PIO_EnableIt(&pin_usim1_rst);
@@ -609,9 +639,9 @@ void mode_cardemu_exit(void)
PIO_DisableIt(&pin_usim1_rst);
PIO_DisableIt(&pin_usim1_vcc);
NVIC_DisableIRQ(USART1_IRQn);
USART_SetTransmitterEnabled(USART1, 0);
USART_SetReceiverEnabled(USART1, 0);
NVIC_DisableIRQ(FIRST_USART_IRQ);
USART_SetTransmitterEnabled(FIRST_USART_BASE, 0);
USART_SetReceiverEnabled(FIRST_USART_BASE, 0);
#ifdef CARDEMU_SECOND_UART
PIO_DisableIt(&pin_usim2_rst);
@@ -638,6 +668,26 @@ static void dispatch_usb_command_generic(struct msgb *msg, struct cardem_inst *c
usb_buf_free(msg);
}
static void process_card_insert(struct cardem_inst *ci, bool card_insert)
{
TRACE_INFO("%u: set card_insert to %s\r\n", ci->num, card_insert ? "INSERTED" : "REMOVED");
#ifdef HAVE_BOARD_CARDINSERT
board_set_card_insert(ci, card_insert);
#else
if (!ci->pin_insert.pio) {
TRACE_INFO("%u: skipping unsupported card_insert to %s\r\n",
ci->num, card_insert ? "INSERTED" : "REMOVED");
return;
}
if (card_insert)
PIO_Set(&ci->pin_insert);
else
PIO_Clear(&ci->pin_insert);
#endif
}
/* handle a single USB command as received from the USB host */
static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci)
{
@@ -661,18 +711,7 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci
break;
case SIMTRACE_MSGT_DT_CEMU_CARDINSERT:
cardins = (struct cardemu_usb_msg_cardinsert *) msg->l2h;
if (!ci->pin_insert.pio) {
TRACE_INFO("%u: skipping unsupported card_insert to %s\r\n",
ci->num, cardins->card_insert ? "INSERTED" : "REMOVED");
usb_buf_free(msg);
break;
}
TRACE_INFO("%u: set card_insert to %s\r\n", ci->num,
cardins->card_insert ? "INSERTED" : "REMOVED");
if (cardins->card_insert)
PIO_Set(&ci->pin_insert);
else
PIO_Clear(&ci->pin_insert);
process_card_insert(ci, cardins->card_insert);
usb_buf_free(msg);
break;
case SIMTRACE_MSGT_BD_CEMU_STATUS:
@@ -682,6 +721,7 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
cfg = (struct cardemu_usb_msg_config *) msg->l2h;
card_emu_set_config(ci->ch, cfg, msgb_l2len(msg));
usb_buf_free(msg);
break;
case SIMTRACE_MSGT_BD_CEMU_STATS:
default:

View File

@@ -689,16 +689,8 @@ void SIMtrace_USB_Initialize(void)
{
unsigned int i;
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
#ifdef PIN_USB_PULLUP
const Pin usb_dp_pullup = PIN_USB_PULLUP;
PIO_Configure(&usb_dp_pullup, 1);
PIO_Set(&usb_dp_pullup);
#endif
USBD_HAL_Suspend();
mdelay(20);
#ifdef PIN_USB_PULLUP
PIO_Clear(&usb_dp_pullup);
#endif
mdelay(500);
USBD_HAL_Activate();
// Get std USB driver

View File

@@ -13,6 +13,20 @@
#define PHONE_INT 2
#define PHONE_DATAOUT 3
/* stub for stdio */
signed int printf_sync(const char *pFormat, ...)
{
va_list ap;
signed int result;
va_start(ap, pFormat);
result = vprintf(pFormat, ap);
va_end(ap);
return result;
}
/***********************************************************************
* stub functions required by card_emu.c
***********************************************************************/
@@ -50,6 +64,9 @@ void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
case ENABLE_TX:
rts = "TX";
break;
case ENABLE_TX_TIMER_ONLY:
rts = "TX-TIMER-ONLY";
break;
case ENABLE_RX:
rts = "RX";
break;
@@ -66,29 +83,14 @@ void card_emu_uart_interrupt(uint8_t uart_chan)
printf("uart_interrupt(uart_chan=%u)\n", uart_chan);
}
void tc_etu_set_wtime(uint8_t tc_chan, uint16_t wtime)
void card_emu_uart_update_wt(uint8_t uart_chan, uint32_t wt)
{
printf("tc_etu_set_wtime(tc_chan=%u, wtime=%u)\n", tc_chan, wtime);
printf("%s(uart_chan=%u, wtime=%u)\n", __func__, uart_chan, wt);
}
void tc_etu_set_etu(uint8_t tc_chan, uint16_t etu)
void card_emu_uart_reset_wt(uint8_t uart_chan)
{
printf("tc_etu_set_etu(tc_chan=%u, etu=%u)\n", tc_chan, etu);
}
void tc_etu_init(uint8_t chan_nr, void *handle)
{
printf("tc_etu_init(tc_chan=%u)\n", chan_nr);
}
void tc_etu_enable(uint8_t chan_nr)
{
printf("tc_etu_enable(tc_chan=%u)\n", chan_nr);
}
void tc_etu_disable(uint8_t chan_nr)
{
printf("tc_etu_disable(tc_chan=%u)\n", chan_nr);
printf("%s(uart_chan=%u\n", __func__, uart_chan);
}
@@ -136,7 +138,7 @@ static void io_start_card(struct card_handle *ch)
/* release from reset and verify th ATR */
card_emu_io_statechg(ch, CARD_IO_RST, 0);
/* simulate waiting time before ATR expired */
tc_etu_wtime_expired(ch);
card_emu_wtime_expired(ch);
verify_atr(ch);
}
@@ -408,7 +410,7 @@ int main(int argc, char **argv)
struct card_handle *ch;
unsigned int i;
ch = card_emu_init(0, 23, 42, PHONE_DATAIN, PHONE_INT, false, true, false);
ch = card_emu_init(0, 42, PHONE_DATAIN, PHONE_INT, false, true, false);
assert(ch);
usb_buf_init();

Binary file not shown.

View File

@@ -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"

View File

@@ -84,6 +84,7 @@ find %{buildroot} -type f -name "*.la" -delete -print
%{_bindir}/simtrace2-cardem-pcsc
%{_bindir}/simtrace2-list
%{_bindir}/simtrace2-sniff
%{_bindir}/simtrace2-tool
%{_udevrulesdir}/99-simtrace2.rules
%files -n libosmo-simtrace2-0

View File

@@ -44,9 +44,13 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/sim/class_tables.h>
#include <osmocom/sim/sim.h>
#define LOGSLOT(slot, lvl, fmt, args...) \
LOGP(DLINP, lvl, "[%u] " fmt, (slot)->slot_nr, ## args)
/***********************************************************************
* SIMTRACE core protocol
***********************************************************************/
@@ -141,7 +145,6 @@ int osmo_st2_slot_tx_msg(struct osmo_st2_slot *slot, struct msgb *msg,
OSMO_ASSERT(transp);
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->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 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));
memset(cins, 0, sizeof(*cins));
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;
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));
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));
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);
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));
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));
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));
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));
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));
printf("<= %s(%08x)\n", __func__, features);
LOGSLOT(ci->slot, LOGL_NOTICE, "<= %s(features=%08x)\n", __func__, features);
memset(cfg, 0, sizeof(*cfg));
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 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->asserted = asserted;
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 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->remote_sim = remote_sim;

View File

@@ -32,5 +32,7 @@ const struct dev_id osmo_st2_compatible_dev_ids[] = {
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OWHW_SAM3 },
{ 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 }
};

View File

@@ -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

View File

@@ -1,7 +1,7 @@
/* simtrace2-cardem-pcsc - main program for the host PC to provide a remote SIM
* using the SIMtrace 2 firmware in card emulation mode
*
* (C) 2016-2020 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2016-2021 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
@@ -48,32 +48,13 @@
#include <osmocom/core/socket.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/select.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <osmocom/sim/class_tables.h>
#include <osmocom/sim/sim.h>
#define ATR_MAX_LEN 33
#define LOGCI(ci, lvl, fmt, args ...) printf(fmt, ## args)
/* reasonable ATR offering all protocols and voltages
* smartphones might not care, but other readers do
*
* TS = 0x3B Direct Convention
* T0 = 0x80 Y(1): b1000, K: 0 (historical bytes)
* TD(1) = 0x80 Y(i+1) = b1000, Protocol T=0
* ----
* TD(2) = 0x81 Y(i+1) = b1000, Protocol T=1
* ----
* TD(3) = 0x1F Y(i+1) = b0001, Protocol T=15
* ----
* TA(4) = 0xC7 Clock stop: no preference - Class accepted by the card: (3G) A 5V B 3V C 1.8V
* ----
* Historical bytes
* TCK = 0x59 correct checksum
*/
#define DEFAULT_ATR_STR "3B8080811FC759"
static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
{
uint8_t csum = 0;
@@ -85,6 +66,37 @@ static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
atr[atr_len-1] = csum;
}
static void cemu_flags2str(char *out, unsigned int out_len, uint32_t flags)
{
snprintf(out, out_len, "%s%s%s%s%s",
flags & CEMU_STATUS_F_RESET_ACTIVE ? "RESET " : "",
flags & CEMU_STATUS_F_VCC_PRESENT ? "VCC " : "",
flags & CEMU_STATUS_F_CLK_ACTIVE ? "CLK " : "",
flags & CEMU_STATUS_F_CARD_INSERT ? "CARD_PRES " : "",
flags & CEMU_STATUS_F_RCEMU_ACTIVE ? "RCEMU " : "");
}
static uint32_t last_flags = 0;
static void update_flags(struct osmo_st2_cardem_inst *ci, uint32_t flags)
{
struct osim_card_hdl *card = ci->chan->card;
if ((flags & CEMU_STATUS_F_VCC_PRESENT) && (flags & CEMU_STATUS_F_CLK_ACTIVE) &&
!(flags & CEMU_STATUS_F_RESET_ACTIVE)) {
if (last_flags & CEMU_STATUS_F_RESET_ACTIVE) {
/* a reset has just ended, forward it to the real card */
bool cold_reset = true;
if (last_flags & CEMU_STATUS_F_VCC_PRESENT)
cold_reset = false;
LOGCI(ci, LOGL_NOTICE, "%s Resetting card in reader...\n",
cold_reset ? "Cold" : "Warm");
osim_card_reset(card, cold_reset);
}
}
last_flags = flags;
}
/***********************************************************************
* Incoming Messages
***********************************************************************/
@@ -92,12 +104,15 @@ static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
/*! \brief Process a STATUS message from the SIMtrace2 */
static int process_do_status(struct osmo_st2_cardem_inst *ci, uint8_t *buf, int len)
{
struct cardemu_usb_msg_status *status;
status = (struct cardemu_usb_msg_status *) buf;
struct cardemu_usb_msg_status *status = (struct cardemu_usb_msg_status *) buf;
char fbuf[80];
printf("=> STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u\n",
cemu_flags2str(fbuf, sizeof(fbuf), status->flags);
printf("=> STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u (%s)\n",
status->flags, status->fi, status->di, status->wi,
status->waiting_time);
status->waiting_time, fbuf);
update_flags(ci, status->flags);
return 0;
}
@@ -184,6 +199,7 @@ static int process_usb_msg(struct osmo_st2_cardem_inst *ci, uint8_t *buf, int le
break;
case SIMTRACE_MSGT_BD_CEMU_CONFIG:
/* firmware confirms configuration change; ignore */
rc = 0;
break;
default:
printf("unknown simtrace msg type 0x%02x\n", sh->msg_type);
@@ -198,10 +214,14 @@ static int process_usb_msg(struct osmo_st2_cardem_inst *ci, uint8_t *buf, int le
static int process_irq_status(struct osmo_st2_cardem_inst *ci, const uint8_t *buf, int len)
{
const struct cardemu_usb_msg_status *status = (struct cardemu_usb_msg_status *) buf;
char fbuf[80];
LOGCI(ci, LOGL_INFO, "SIMtrace IRQ STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u\n",
cemu_flags2str(fbuf, sizeof(fbuf), status->flags);
LOGCI(ci, LOGL_INFO, "SIMtrace IRQ STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u (%s)\n",
status->flags, status->fi, status->di, status->wi,
status->waiting_time);
status->waiting_time, fbuf);
update_flags(ci, status->flags);
return 0;
}
@@ -401,6 +421,7 @@ static void signal_handler(int signal)
switch (signal) {
case SIGINT:
osmo_st2_cardem_request_card_insert(ci, false);
osmo_st2_modem_sim_select_local(ci->slot);
exit(0);
break;
default:
@@ -408,6 +429,8 @@ static void signal_handler(int signal)
}
}
static struct log_info log_info = {};
int main(int argc, char **argv)
{
struct osmo_st2_transport *transp = ci->slot->transp;
@@ -415,9 +438,9 @@ int main(int argc, char **argv)
int rc;
int c, ret = 1;
int skip_atr = 0;
char *atr = DEFAULT_ATR_STR;
uint8_t real_atr[ATR_MAX_LEN];
int atr_len;
char *atr = NULL;
uint8_t override_atr[OSIM_MAX_ATR_LEN];
int override_atr_len = 0;
int keep_running = 0;
int if_num = 0, vendor_id = -1, product_id = -1;
int config_id = -1, altsetting = 0, addr = -1;
@@ -434,6 +457,8 @@ int main(int argc, char **argv)
return rc;
}
osmo_init_logging2(NULL, &log_info);
while (1) {
int option_index = 0;
@@ -484,11 +509,13 @@ int main(int argc, char **argv)
}
}
atr_len = osmo_hexparse(atr,real_atr,ATR_MAX_LEN);
if (atr_len < 2) {
fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex "
"digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n");
goto do_exit;
if (atr) {
override_atr_len = osmo_hexparse(atr, override_atr, sizeof(override_atr));
if (override_atr_len < 2) {
fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex "
"digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n");
goto do_exit;
}
}
if (vendor_id < 0 || product_id < 0) {
@@ -498,12 +525,6 @@ int main(int argc, char **argv)
ci->card_prof = &osim_uicc_sim_cic_profile;
rc = libusb_init(NULL);
if (rc < 0) {
fprintf(stderr, "libusb initialization failed\n");
goto do_exit;
}
rc = osmo_st2_gsmtap_init(gsmtap_host);
if (rc < 0) {
perror("unable to open GSMTAP");
@@ -545,20 +566,20 @@ int main(int argc, char **argv)
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;
goto close;
}
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;
goto close;
}
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;
goto close;
}
allocate_and_submit_irq(ci);
@@ -576,8 +597,14 @@ int main(int argc, char **argv)
if (!skip_atr) {
/* set the ATR */
atr_update_csum(real_atr, atr_len);
osmo_st2_cardem_request_set_atr(ci, real_atr, atr_len);
if (override_atr_len) {
/* user has specified an override-ATR */
atr_update_csum(override_atr, override_atr_len);
osmo_st2_cardem_request_set_atr(ci, override_atr, override_atr_len);
} else {
/* use the real ATR of the card */
osmo_st2_cardem_request_set_atr(ci, card->atr, card->atr_len);
}
}
/* select remote (forwarded) SIM */
@@ -587,14 +614,21 @@ int main(int argc, char **argv)
ret = 0;
libusb_release_interface(transp->usb_devh, 0);
close_exit:
if (transp->usb_devh)
close:
if (transp->usb_devh) {
libusb_close(transp->usb_devh);
transp->usb_devh = NULL;
}
if (keep_running)
sleep(1);
} while (keep_running);
libusb_exit(NULL);
close_exit:
if (transp->usb_devh)
libusb_close(transp->usb_devh);
osmo_libusb_exit(NULL);
do_exit:
return ret;
}

View File

@@ -315,6 +315,7 @@ static const struct option opts[] = {
/* Known USB device with SIMtrace firmware supporting sniffer */
static const struct dev_id compatible_dev_ids[] = {
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_NGFF_CARDEM },
{ 0, 0 }
};
@@ -378,7 +379,7 @@ int main(int argc, char **argv)
}
/* Scan for available SIMtrace USB devices supporting sniffing */
rc = libusb_init(NULL);
rc = osmo_libusb_init(NULL);
if (rc < 0) {
fprintf(stderr, "libusb initialization failed\n");
goto do_exit;
@@ -504,7 +505,7 @@ close_exit:
sleep(1);
} while (keep_running);
libusb_exit(NULL);
osmo_libusb_exit(NULL);
do_exit:
return ret;
}

337
host/src/simtrace2-tool.c Normal file
View File

@@ -0,0 +1,337 @@
/* 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>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.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;
}
static struct log_info log_info = {};
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;
osmo_init_logging2(NULL, &log_info);
rc = osmo_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 = 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);
osmo_libusb_exit(NULL);
do_exit:
return ret;
}

View File

@@ -25,13 +25,7 @@
#include <osmocom/usb/libusb.h>
#include <osmocom/simtrace2/simtrace_usb.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 }
};
#include <osmocom/simtrace2/usb_util.h>
static int find_devices(void)
{
@@ -39,7 +33,7 @@ static int find_devices(void)
int rc, i, num_interfaces;
/* 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));
printf("USB matches: %d\n", rc);
if (rc < 0)
@@ -83,7 +77,7 @@ static int find_devices(void)
int main(int argc, char **argv)
{
libusb_init(NULL);
osmo_libusb_init(NULL);
find_devices();
return 0;
}