mirror of https://gerrit.osmocom.org/simtrace2
host: use autotools and split shared code to libosmo-simtrace2
Change-Id: I57e77f927ee9e169cc794c5dc6b128a2d590201b
This commit is contained in:
parent
331fa5a237
commit
964cda309d
|
@ -50,9 +50,15 @@ make clean
|
|||
echo
|
||||
echo "=============== HOST START =============="
|
||||
cd $TOPDIR/host
|
||||
make clean
|
||||
make
|
||||
make clean
|
||||
autoreconf --install --force
|
||||
./configure --enable-sanitize --enable-werror
|
||||
$MAKE $PARALLEL_MAKE
|
||||
#$MAKE distcheck || cat-testlogs.sh
|
||||
make dist
|
||||
|
||||
#if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||
# make -C "$base/doc/manuals" publish
|
||||
#fi
|
||||
|
||||
if [ "x$publish" = "x--publish" ]; then
|
||||
echo
|
||||
|
@ -68,6 +74,10 @@ EOF
|
|||
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/
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=============== HOST CLEAN =============="
|
||||
$MAKE maintainer-clean
|
||||
|
||||
echo
|
||||
echo "=============== FIRMWARE CLEAN =============="
|
||||
cd $TOPDIR/firmware/
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
#configure
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.lineno
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
|
||||
#libtool
|
||||
ltmain.sh
|
||||
libtool
|
||||
.libs
|
||||
|
||||
.tarball-version
|
||||
.version
|
||||
|
||||
*.pc
|
|
@ -0,0 +1,14 @@
|
|||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = include lib src contrib #tests examples doc
|
||||
|
||||
EXTRA_DIST = .version git-version-gen
|
||||
|
||||
@RELMAKE@
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
echo $(VERSION) > $(distdir)/.tarball-version
|
|
@ -5,7 +5,7 @@ APPS=simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list simtrace2-sniff
|
|||
|
||||
all: $(APPS)
|
||||
|
||||
simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o libusb_util.o
|
||||
simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o simtrace2_api.o libusb_util.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS) `pkg-config --libs libosmosim libpcsclite`
|
||||
|
||||
simtrace2-remsim-usb2udp: usb2udp.o simtrace2-discovery.o
|
|
@ -0,0 +1,102 @@
|
|||
AC_INIT([simtrace2],
|
||||
m4_esyscmd([./git-version-gen .tarball-version]),
|
||||
[simtrace@lists.osmocom.org])
|
||||
|
||||
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl include release helper
|
||||
RELMAKE='-include osmo-release.mk'
|
||||
AC_SUBST([RELMAKE])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
LT_INIT([pic-only])
|
||||
|
||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||
AC_MSG_WARN([You need to install pkg-config])
|
||||
fi
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
CPPFLAGS="$CPPFLAGS -Wall"
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sanitize],
|
||||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
||||
# The following test is taken from WebKit's webkit.m4
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden "
|
||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
SYMBOL_VISIBILITY="-fvisibility=hidden"],
|
||||
AC_MSG_RESULT([no]))
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_SUBST(SYMBOL_VISIBILITY)
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.0.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOSIM, libosmosim >= 1.0.0)
|
||||
PKG_CHECK_MODULES(LIBUSB, libusb-1.0)
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sanitize],
|
||||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(werror,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-werror],
|
||||
[Turn all compiler warnings into errors, with exceptions:
|
||||
a) deprecation (allow upstream to mark deprecation without breaking builds);
|
||||
b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
|
||||
]
|
||||
)],
|
||||
[werror=$enableval], [werror="no"])
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([CFLAGS="$CFLAGS"])
|
||||
AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
|
||||
|
||||
AC_OUTPUT(
|
||||
libosmo-simtrace2.pc
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
lib/Makefile
|
||||
contrib/Makefile
|
||||
Makefile)
|
|
@ -0,0 +1 @@
|
|||
EXTRA_DIST = 99-simtrace2.rules
|
|
@ -0,0 +1,151 @@
|
|||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2010-01-28.01
|
||||
|
||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
|
||||
# It may be run two ways:
|
||||
# - from a git repository in which the "git describe" command below
|
||||
# produces useful output (thus requiring at least one signed tag)
|
||||
# - from a non-git-repo directory containing a .tarball-version file, which
|
||||
# presumes this script is invoked like "./git-version-gen .tarball-version".
|
||||
|
||||
# In order to use intra-version strings in your project, you will need two
|
||||
# separate generated version string files:
|
||||
#
|
||||
# .tarball-version - present only in a distribution tarball, and not in
|
||||
# a checked-out repository. Created with contents that were learned at
|
||||
# the last time autoconf was run, and used by git-version-gen. Must not
|
||||
# be present in either $(srcdir) or $(builddir) for git-version-gen to
|
||||
# give accurate answers during normal development with a checked out tree,
|
||||
# but must be present in a tarball when there is no version control system.
|
||||
# Therefore, it cannot be used in any dependencies. GNUmakefile has
|
||||
# hooks to force a reconfigure at distribution time to get the value
|
||||
# correct, without penalizing normal development with extra reconfigures.
|
||||
#
|
||||
# .version - present in a checked-out repository and in a distribution
|
||||
# tarball. Usable in dependencies, particularly for files that don't
|
||||
# want to depend on config.h but do want to track version changes.
|
||||
# Delete this file prior to any autoconf run where you want to rebuild
|
||||
# files to pick up a version string change; and leave it stale to
|
||||
# minimize rebuild time after unrelated changes to configure sources.
|
||||
#
|
||||
# It is probably wise to add these two files to .gitignore, so that you
|
||||
# don't accidentally commit either generated file.
|
||||
#
|
||||
# Use the following line in your configure.ac, so that $(VERSION) will
|
||||
# automatically be up-to-date each time configure is run (and note that
|
||||
# since configure.ac no longer includes a version string, Makefile rules
|
||||
# should not depend on configure.ac for version updates).
|
||||
#
|
||||
# AC_INIT([GNU project],
|
||||
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
# [bug-project@example])
|
||||
#
|
||||
# Then use the following lines in your Makefile.am, so that .version
|
||||
# will be present for dependencies, and so that .tarball-version will
|
||||
# exist in distribution tarballs.
|
||||
#
|
||||
# BUILT_SOURCES = $(top_srcdir)/.version
|
||||
# $(top_srcdir)/.version:
|
||||
# echo $(VERSION) > $@-t && mv $@-t $@
|
||||
# dist-hook:
|
||||
# echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
case $# in
|
||||
1) ;;
|
||||
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
|
||||
esac
|
||||
|
||||
tarball_version_file=$1
|
||||
nl='
|
||||
'
|
||||
|
||||
# First see if there is a tarball-only version file.
|
||||
# then try "git describe", then default.
|
||||
if test -f $tarball_version_file
|
||||
then
|
||||
v=`cat $tarball_version_file` || exit 1
|
||||
case $v in
|
||||
*$nl*) v= ;; # reject multi-line output
|
||||
[0-9]*) ;;
|
||||
*) v= ;;
|
||||
esac
|
||||
test -z "$v" \
|
||||
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
|
||||
fi
|
||||
|
||||
if test -n "$v"
|
||||
then
|
||||
: # use $v
|
||||
elif
|
||||
v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|
||||
|| git describe --abbrev=4 HEAD 2>/dev/null` \
|
||||
&& case $v in
|
||||
[0-9]*) ;;
|
||||
v[0-9]*) ;;
|
||||
*) (exit 1) ;;
|
||||
esac
|
||||
then
|
||||
# Is this a new git that lists number of commits since the last
|
||||
# tag or the previous older version that did not?
|
||||
# Newer: v6.10-77-g0f8faeb
|
||||
# Older: v6.10-g0f8faeb
|
||||
case $v in
|
||||
*-*-*) : git describe is okay three part flavor ;;
|
||||
*-*)
|
||||
: git describe is older two part flavor
|
||||
# Recreate the number of commits and rewrite such that the
|
||||
# result is the same as if we were using the newer version
|
||||
# of git describe.
|
||||
vtag=`echo "$v" | sed 's/-.*//'`
|
||||
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
|
||||
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
|
||||
;;
|
||||
esac
|
||||
|
||||
# Change the first '-' to a '.', so version-comparing tools work properly.
|
||||
# Remove the "g" in git describe's output string, to save a byte.
|
||||
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
|
||||
else
|
||||
v=UNKNOWN
|
||||
fi
|
||||
|
||||
v=`echo "$v" |sed 's/^v//'`
|
||||
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
git status > /dev/null 2>&1
|
||||
|
||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
|
||||
case "$dirty" in
|
||||
'') ;;
|
||||
*) # Append the suffix only if there isn't one already.
|
||||
case $v in
|
||||
*-dirty) ;;
|
||||
*) v="$v-dirty" ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d '\012'
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -0,0 +1,7 @@
|
|||
nobase_include_HEADERS = \
|
||||
osmocom/simtrace2/apdu_dispatch.h \
|
||||
osmocom/simtrace2/libusb_util.h \
|
||||
osmocom/simtrace2/simtrace2_api.h \
|
||||
osmocom/simtrace2/simtrace_usb.h \
|
||||
osmocom/simtrace2/simtrace_prot.h \
|
||||
osmocom/simtrace2/gsmtap.h
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
|
||||
int osmo_st2_gsmtap_init(const char *gsmtap_host);
|
||||
int osmo_st2_gsmtap_send_apdu(uint8_t sub_type, const uint8_t *apdu, unsigned int len);
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/sim/sim.h>
|
||||
|
||||
/* transport to a SIMtrace device */
|
||||
struct st_transport {
|
||||
/* USB */
|
||||
struct libusb_device_handle *usb_devh;
|
||||
struct {
|
||||
uint8_t in;
|
||||
uint8_t out;
|
||||
uint8_t irq_in;
|
||||
} usb_ep;
|
||||
|
||||
/* UDP */
|
||||
int udp_fd;
|
||||
};
|
||||
|
||||
/* a SIMtrace slot; communicates over a transport */
|
||||
struct st_slot {
|
||||
/* transport through which the slot can be reached */
|
||||
struct st_transport *transp;
|
||||
/* number of the slot within the transport */
|
||||
uint8_t slot_nr;
|
||||
};
|
||||
|
||||
/* One istance of card emulation */
|
||||
struct cardem_inst {
|
||||
/* slot on which this card emulation instance runs */
|
||||
struct st_slot *slot;
|
||||
/* libosmosim SIM card profile */
|
||||
const struct osim_cla_ins_card_profile *card_prof;
|
||||
/* libosmosim SIM card channel */
|
||||
struct osim_chan_hdl *chan;
|
||||
};
|
||||
|
||||
|
||||
int cardem_request_card_insert(struct cardem_inst *ci, bool inserted);
|
||||
int cardem_request_pb_and_rx(struct cardem_inst *ci, uint8_t pb, uint8_t le);
|
||||
int cardem_request_pb_and_tx(struct cardem_inst *ci, uint8_t pb,
|
||||
const uint8_t *data, uint16_t data_len_in);
|
||||
int cardem_request_sw_tx(struct cardem_inst *ci, const uint8_t *sw);
|
||||
int cardem_request_set_atr(struct cardem_inst *ci, const uint8_t *atr, unsigned int atr_len);
|
||||
|
||||
|
||||
int st_modem_reset_pulse(struct st_slot *slot, uint16_t duration_ms);
|
||||
int st_modem_reset_active(struct st_slot *slot);
|
||||
int st_modem_reset_inactive(struct st_slot *slot);
|
||||
int st_modem_sim_select_local(struct st_slot *slot);
|
||||
int st_modem_sim_select_remote(struct st_slot *slot);
|
||||
int st_modem_get_status(struct st_slot *slot);
|
|
@ -0,0 +1 @@
|
|||
../../../../firmware/libcommon/include/simtrace_prot.h
|
|
@ -0,0 +1 @@
|
|||
../../../../firmware/libcommon/include/simtrace_usb.h
|
|
@ -0,0 +1,19 @@
|
|||
# This is _NOT_ the library release version, it's an API version.
|
||||
# Please read chapter "Library interface versions" of the libtool documentation
|
||||
# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
|
||||
ST2_LIBVERSION=0:0:0
|
||||
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS= -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOSIM_CFLAGS) $(LIBUSB_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(COVERAGE_LDFLAGS)
|
||||
COMMONLIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOSIM_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
lib_LTLIBRARIES = libosmo-simtrace2.la
|
||||
|
||||
libosmo_simtrace2_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(ST2_LIBVERSION)
|
||||
libosmo_simtrace2_la_LIBADD = $(COMMONLIBS)
|
||||
libosmo_simtrace2_la_SOURCES = \
|
||||
apdu_dispatch.c \
|
||||
gsmtap.c \
|
||||
libusb_util.c \
|
||||
simtrace2_api.c
|
|
@ -27,7 +27,7 @@
|
|||
#include <osmocom/sim/sim.h>
|
||||
#include <osmocom/sim/class_tables.h>
|
||||
|
||||
#include "apdu_dispatch.h"
|
||||
#include <osmocom/simtrace2/apdu_dispatch.h>
|
||||
|
||||
/*! \brief Has the command-data phase been completed yet? */
|
||||
static inline bool is_dc_complete(struct apdu_context *ac)
|
|
@ -0,0 +1,57 @@
|
|||
#include <osmocom/simtrace2/gsmtap.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* global GSMTAP instance */
|
||||
static struct gsmtap_inst *g_gti;
|
||||
|
||||
int osmo_st2_gsmtap_init(const char *gsmtap_host)
|
||||
{
|
||||
if (g_gti)
|
||||
return -EEXIST;
|
||||
|
||||
g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
|
||||
if (!g_gti) {
|
||||
perror("unable to open GSMTAP");
|
||||
return -EIO;
|
||||
}
|
||||
gsmtap_source_add_sink(g_gti);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmo_st2_gsmtap_send_apdu(uint8_t sub_type, const uint8_t *apdu, unsigned int len)
|
||||
{
|
||||
struct gsmtap_hdr *gh;
|
||||
unsigned int gross_len = len + sizeof(*gh);
|
||||
uint8_t *buf = malloc(gross_len);
|
||||
int rc;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(buf, 0, sizeof(*gh));
|
||||
gh = (struct gsmtap_hdr *) buf;
|
||||
gh->version = GSMTAP_VERSION;
|
||||
gh->hdr_len = sizeof(*gh)/4;
|
||||
gh->type = GSMTAP_TYPE_SIM;
|
||||
gh->sub_type = sub_type;
|
||||
|
||||
memcpy(buf + sizeof(*gh), apdu, len);
|
||||
|
||||
rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
|
||||
if (rc < 0) {
|
||||
perror("write gsmtap");
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* libusb utilities
|
||||
*
|
||||
* (C) 2010-2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
* (C) 2010-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
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "libusb_util.h"
|
||||
#include <osmocom/simtrace2/libusb_util.h>
|
||||
|
||||
static char path_buf[USB_MAX_PATH_LEN];
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
|
||||
/* simtrace2-protocol - USB protocol library code for SIMtrace2
|
||||
*
|
||||
* (C) 2016-2019 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
|
||||
* 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>
|
||||
#include <time.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
//#include <osmocom/simtrace2/libusb_util.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include <osmocom/simtrace2/simtrace2_api.h>
|
||||
//#include "apdu_dispatch.h"
|
||||
//#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/sim/class_tables.h>
|
||||
#include <osmocom/sim/sim.h>
|
||||
|
||||
/***********************************************************************
|
||||
* SIMTRACE core protocol
|
||||
***********************************************************************/
|
||||
|
||||
/*! \brief allocate a message buffer for simtrace use */
|
||||
static struct msgb *st_msgb_alloc(void)
|
||||
{
|
||||
return msgb_alloc_headroom(1024+32, 32, "SIMtrace");
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void apdu_out_cb(uint8_t *buf, unsigned int len, void *user_data)
|
||||
{
|
||||
printf("APDU: %s\n", osmo_hexdump(buf, len));
|
||||
gsmtap_send_sim(buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief Transmit a given command to the SIMtrace2 device */
|
||||
int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
printf("<- %s\n", msgb_hexdump(msg));
|
||||
|
||||
if (transp->udp_fd < 0) {
|
||||
int xfer_len;
|
||||
|
||||
rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out,
|
||||
msgb_data(msg), msgb_length(msg),
|
||||
&xfer_len, 100000);
|
||||
} else {
|
||||
rc = write(transp->udp_fd, msgb_data(msg), msgb_length(msg));
|
||||
}
|
||||
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct simtrace_msg_hdr *st_push_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type,
|
||||
uint8_t slot_nr)
|
||||
{
|
||||
struct simtrace_msg_hdr *sh;
|
||||
|
||||
sh = (struct simtrace_msg_hdr *) msgb_push(msg, sizeof(*sh));
|
||||
memset(sh, 0, sizeof(*sh));
|
||||
sh->msg_class = msg_class;
|
||||
sh->msg_type = msg_type;
|
||||
sh->slot_nr = slot_nr;
|
||||
sh->msg_len = msgb_length(msg);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
/* transmit a given message to a specified slot. Expects all headers
|
||||
* present before calling the function */
|
||||
int st_slot_tx_msg(struct st_slot *slot, struct msgb *msg,
|
||||
uint8_t msg_class, uint8_t msg_type)
|
||||
{
|
||||
st_push_hdr(msg, msg_class, msg_type, slot->slot_nr);
|
||||
|
||||
return st_transp_tx_msg(slot->transp, msg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Card Emulation protocol
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/*! \brief Request the SIMtrace2 to generate a card-insert signal */
|
||||
int cardem_request_card_insert(struct cardem_inst *ci, bool inserted)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_cardinsert *cins;
|
||||
|
||||
cins = (struct cardemu_usb_msg_cardinsert *) msgb_put(msg, sizeof(*cins));
|
||||
memset(cins, 0, sizeof(*cins));
|
||||
if (inserted)
|
||||
cins->card_insert = 1;
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_CARDINSERT);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Rx */
|
||||
int cardem_request_pb_and_rx(struct cardem_inst *ci, uint8_t pb, uint8_t le)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
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);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 1;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_RX;
|
||||
/* one data byte */
|
||||
msgb_put_u8(msg, pb);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Tx */
|
||||
int cardem_request_pb_and_tx(struct cardem_inst *ci, uint8_t pb,
|
||||
const uint8_t *data, uint16_t data_len_in)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_tx_data *txd;
|
||||
uint8_t *cur;
|
||||
|
||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||
|
||||
printf("<= %s(%02x, %s, %d)\n", __func__, pb,
|
||||
osmo_hexdump(data, data_len_in), data_len_in);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 1 + data_len_in;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_TX;
|
||||
/* procedure byte */
|
||||
msgb_put_u8(msg, pb);
|
||||
/* data */
|
||||
cur = msgb_put(msg, data_len_in);
|
||||
memcpy(cur, data, data_len_in);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to send a Status Word */
|
||||
int cardem_request_sw_tx(struct cardem_inst *ci, const uint8_t *sw)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_tx_data *txd;
|
||||
uint8_t *cur;
|
||||
|
||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||
|
||||
printf("<= %s(%02x %02x)\n", __func__, sw[0], sw[1]);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 2;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_TX | CEMU_DATA_F_FINAL;
|
||||
cur = msgb_put(msg, 2);
|
||||
cur[0] = sw[0];
|
||||
cur[1] = sw[1];
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
int cardem_request_set_atr(struct cardem_inst *ci, const uint8_t *atr, unsigned int atr_len)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_set_atr *satr;
|
||||
uint8_t *cur;
|
||||
|
||||
satr = (struct cardemu_usb_msg_set_atr *) msgb_put(msg, sizeof(*satr));
|
||||
|
||||
printf("<= %s(%s)\n", __func__, osmo_hexdump(atr, atr_len));
|
||||
|
||||
memset(satr, 0, sizeof(*satr));
|
||||
satr->atr_len = atr_len;
|
||||
cur = msgb_put(msg, atr_len);
|
||||
memcpy(cur, atr, atr_len);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_SET_ATR);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Modem Control protocol
|
||||
***********************************************************************/
|
||||
|
||||
static int _modem_reset(struct st_slot *slot, uint8_t asserted, uint16_t pulse_ms)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct st_modem_reset *sr ;
|
||||
|
||||
sr = (struct st_modem_reset *) msgb_put(msg, sizeof(*sr));
|
||||
sr->asserted = asserted;
|
||||
sr->pulse_duration_msec = pulse_ms;
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_DT_MODEM_RESET);
|
||||
}
|
||||
|
||||
/*! \brief pulse the RESET line of the modem for \a duration_ms milli-seconds*/
|
||||
int st_modem_reset_pulse(struct st_slot *slot, uint16_t duration_ms)
|
||||
{
|
||||
return _modem_reset(slot, 2, duration_ms);
|
||||
}
|
||||
|
||||
/*! \brief assert the RESET line of the modem */
|
||||
int st_modem_reset_active(struct st_slot *slot)
|
||||
{
|
||||
return _modem_reset(slot, 1, 0);
|
||||
}
|
||||
|
||||
/*! \brief de-assert the RESET line of the modem */
|
||||
int st_modem_reset_inactive(struct st_slot *slot)
|
||||
{
|
||||
return _modem_reset(slot, 0, 0);
|
||||
}
|
||||
|
||||
static int _modem_sim_select(struct st_slot *slot, uint8_t remote_sim)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct st_modem_sim_select *ss;
|
||||
|
||||
ss = (struct st_modem_sim_select *) msgb_put(msg, sizeof(*ss));
|
||||
ss->remote_sim = remote_sim;
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_DT_MODEM_SIM_SELECT);
|
||||
}
|
||||
|
||||
/*! \brief select local (physical) SIM for given slot */
|
||||
int st_modem_sim_select_local(struct st_slot *slot)
|
||||
{
|
||||
return _modem_sim_select(slot, 0);
|
||||
}
|
||||
|
||||
/*! \brief select remote (emulated/forwarded) SIM for given slot */
|
||||
int st_modem_sim_select_remote(struct st_slot *slot)
|
||||
{
|
||||
return _modem_sim_select(slot, 1);
|
||||
}
|
||||
|
||||
/*! \brief Request slot to send us status information about the modem */
|
||||
int st_modem_get_status(struct st_slot *slot)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_BD_MODEM_STATUS);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Osmocom SIMtrace2 library
|
||||
Description: Library for SIM Card / Smart Card tracing + emulation
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -losmo-simtrace2
|
||||
Cflags: -I${includedir}/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef _SIMTRACE_H
|
||||
#define _SIMTRACE_H
|
||||
|
||||
#define SIMTRACE_USB_VENDOR 0x1d50
|
||||
#define SIMTRACE_USB_PRODUCT 0x60e3
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
../firmware/libcommon/include/simtrace_prot.h
|
|
@ -1 +0,0 @@
|
|||
../firmware/libcommon/include/simtrace_usb.h
|
|
@ -0,0 +1,18 @@
|
|||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
||||
AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOSIM_CFLAGS) $(LIBUSB_CFLAGS) $(COVERAGE_FLAGS)
|
||||
AM_LDFLAGS=$(COVERAGE_LDFLAGS)
|
||||
|
||||
LDADD= $(top_builddir)/lib/libosmo-simtrace2.la \
|
||||
$(LIBOSMOCORE_LIBS) $(LIBOSMOSIM_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
noinst_HEADERS = simtrace2-discovery.h
|
||||
|
||||
bin_PROGRAMS = simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list simtrace2-sniff
|
||||
|
||||
simtrace2_remsim_SOURCES = simtrace2-remsim.c simtrace2-discovery.c
|
||||
|
||||
simtrace2_remsim_usb2udp_SOURCES = usb2udp.c simtrace2-discovery.c
|
||||
|
||||
simtrace2_list_SOURCES = simtrace2_usb.c
|
||||
|
||||
simtrace2_sniff_SOURCES = simtrace2-sniff.c simtrace2-discovery.c
|
|
@ -18,6 +18,7 @@
|
|||
* 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>
|
||||
|
@ -37,231 +38,20 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "libusb_util.h"
|
||||
#include "simtrace.h"
|
||||
#include "simtrace_prot.h"
|
||||
#include "apdu_dispatch.h"
|
||||
#include <osmocom/simtrace2/libusb_util.h>
|
||||
#include <osmocom/simtrace2/simtrace2_api.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include <osmocom/simtrace2/apdu_dispatch.h>
|
||||
#include <osmocom/simtrace2/gsmtap.h>
|
||||
|
||||
#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/sim/class_tables.h>
|
||||
#include <osmocom/sim/sim.h>
|
||||
|
||||
/* transport to a SIMtrace device */
|
||||
struct st_transport {
|
||||
/* USB */
|
||||
struct libusb_device_handle *usb_devh;
|
||||
struct {
|
||||
uint8_t in;
|
||||
uint8_t out;
|
||||
uint8_t irq_in;
|
||||
} usb_ep;
|
||||
|
||||
/* UDP */
|
||||
int udp_fd;
|
||||
};
|
||||
|
||||
/* a SIMtrace slot; communicates over a transport */
|
||||
struct st_slot {
|
||||
/* transport through which the slot can be reached */
|
||||
struct st_transport *transp;
|
||||
/* number of the slot within the transport */
|
||||
uint8_t slot_nr;
|
||||
};
|
||||
|
||||
/* One istance of card emulation */
|
||||
struct cardem_inst {
|
||||
/* slot on which this card emulation instance runs */
|
||||
struct st_slot *slot;
|
||||
/* libosmosim SIM card profile */
|
||||
const struct osim_cla_ins_card_profile *card_prof;
|
||||
/* libosmosim SIM card channel */
|
||||
struct osim_chan_hdl *chan;
|
||||
};
|
||||
|
||||
/* global GSMTAP instance */
|
||||
static struct gsmtap_inst *g_gti;
|
||||
|
||||
static int gsmtap_send_sim(const uint8_t *apdu, unsigned int len)
|
||||
{
|
||||
struct gsmtap_hdr *gh;
|
||||
unsigned int gross_len = len + sizeof(*gh);
|
||||
uint8_t *buf = malloc(gross_len);
|
||||
int rc;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(buf, 0, sizeof(*gh));
|
||||
gh = (struct gsmtap_hdr *) buf;
|
||||
gh->version = GSMTAP_VERSION;
|
||||
gh->hdr_len = sizeof(*gh)/4;
|
||||
gh->type = GSMTAP_TYPE_SIM;
|
||||
|
||||
memcpy(buf + sizeof(*gh), apdu, len);
|
||||
|
||||
rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
|
||||
if (rc < 0) {
|
||||
perror("write gsmtap");
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SIMTRACE pcore protocol
|
||||
***********************************************************************/
|
||||
|
||||
/*! \brief allocate a message buffer for simtrace use */
|
||||
static struct msgb *st_msgb_alloc(void)
|
||||
{
|
||||
return msgb_alloc_headroom(1024+32, 32, "SIMtrace");
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void apdu_out_cb(uint8_t *buf, unsigned int len, void *user_data)
|
||||
{
|
||||
printf("APDU: %s\n", osmo_hexdump(buf, len));
|
||||
gsmtap_send_sim(buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief Transmit a given command to the SIMtrace2 device */
|
||||
int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
printf("<- %s\n", msgb_hexdump(msg));
|
||||
|
||||
if (transp->udp_fd < 0) {
|
||||
int xfer_len;
|
||||
|
||||
rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out,
|
||||
msgb_data(msg), msgb_length(msg),
|
||||
&xfer_len, 100000);
|
||||
} else {
|
||||
rc = write(transp->udp_fd, msgb_data(msg), msgb_length(msg));
|
||||
}
|
||||
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct simtrace_msg_hdr *st_push_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type,
|
||||
uint8_t slot_nr)
|
||||
{
|
||||
struct simtrace_msg_hdr *sh;
|
||||
|
||||
sh = (struct simtrace_msg_hdr *) msgb_push(msg, sizeof(*sh));
|
||||
memset(sh, 0, sizeof(*sh));
|
||||
sh->msg_class = msg_class;
|
||||
sh->msg_type = msg_type;
|
||||
sh->slot_nr = slot_nr;
|
||||
sh->msg_len = msgb_length(msg);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
/* transmit a given message to a specified slot. Expects all headers
|
||||
* present before calling the function */
|
||||
int st_slot_tx_msg(struct st_slot *slot, struct msgb *msg,
|
||||
uint8_t msg_class, uint8_t msg_type)
|
||||
{
|
||||
st_push_hdr(msg, msg_class, msg_type, slot->slot_nr);
|
||||
|
||||
return st_transp_tx_msg(slot->transp, msg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Card Emulation protocol
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/*! \brief Request the SIMtrace2 to generate a card-insert signal */
|
||||
static int cardem_request_card_insert(struct cardem_inst *ci, bool inserted)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_cardinsert *cins;
|
||||
|
||||
cins = (struct cardemu_usb_msg_cardinsert *) msgb_put(msg, sizeof(*cins));
|
||||
memset(cins, 0, sizeof(*cins));
|
||||
if (inserted)
|
||||
cins->card_insert = 1;
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_CARDINSERT);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Rx */
|
||||
static int cardem_request_pb_and_rx(struct cardem_inst *ci, uint8_t pb, uint8_t le)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
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);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 1;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_RX;
|
||||
/* one data byte */
|
||||
msgb_put_u8(msg, pb);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to transmit a Procedure Byte, then Tx */
|
||||
static int cardem_request_pb_and_tx(struct cardem_inst *ci, uint8_t pb,
|
||||
const uint8_t *data, uint16_t data_len_in)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_tx_data *txd;
|
||||
uint8_t *cur;
|
||||
|
||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||
|
||||
printf("<= %s(%02x, %s, %d)\n", __func__, pb,
|
||||
osmo_hexdump(data, data_len_in), data_len_in);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 1 + data_len_in;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_TX;
|
||||
/* procedure byte */
|
||||
msgb_put_u8(msg, pb);
|
||||
/* data */
|
||||
cur = msgb_put(msg, data_len_in);
|
||||
memcpy(cur, data, data_len_in);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
/*! \brief Request the SIMtrace2 to send a Status Word */
|
||||
static int cardem_request_sw_tx(struct cardem_inst *ci, const uint8_t *sw)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_tx_data *txd;
|
||||
uint8_t *cur;
|
||||
|
||||
txd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*txd));
|
||||
|
||||
printf("<= %s(%02x %02x)\n", __func__, sw[0], sw[1]);
|
||||
|
||||
memset(txd, 0, sizeof(*txd));
|
||||
txd->data_len = 2;
|
||||
txd->flags = CEMU_DATA_F_PB_AND_TX | CEMU_DATA_F_FINAL;
|
||||
cur = msgb_put(msg, 2);
|
||||
cur[0] = sw[0];
|
||||
cur[1] = sw[1];
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_TX_DATA);
|
||||
}
|
||||
|
||||
static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
|
||||
{
|
||||
uint8_t csum = 0;
|
||||
|
@ -273,90 +63,6 @@ static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
|
|||
atr[atr_len-1] = csum;
|
||||
}
|
||||
|
||||
static int cardem_request_set_atr(struct cardem_inst *ci, const uint8_t *atr, unsigned int atr_len)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct cardemu_usb_msg_set_atr *satr;
|
||||
uint8_t *cur;
|
||||
|
||||
satr = (struct cardemu_usb_msg_set_atr *) msgb_put(msg, sizeof(*satr));
|
||||
|
||||
printf("<= %s(%s)\n", __func__, osmo_hexdump(atr, atr_len));
|
||||
|
||||
memset(satr, 0, sizeof(*satr));
|
||||
satr->atr_len = atr_len;
|
||||
cur = msgb_put(msg, atr_len);
|
||||
memcpy(cur, atr, atr_len);
|
||||
|
||||
return st_slot_tx_msg(ci->slot, msg, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DT_CEMU_SET_ATR);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Modem Control protocol
|
||||
***********************************************************************/
|
||||
|
||||
static int _modem_reset(struct st_slot *slot, uint8_t asserted, uint16_t pulse_ms)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct st_modem_reset *sr ;
|
||||
|
||||
sr = (struct st_modem_reset *) msgb_put(msg, sizeof(*sr));
|
||||
sr->asserted = asserted;
|
||||
sr->pulse_duration_msec = pulse_ms;
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_DT_MODEM_RESET);
|
||||
}
|
||||
|
||||
/*! \brief pulse the RESET line of the modem for \a duration_ms milli-seconds*/
|
||||
int st_modem_reset_pulse(struct st_slot *slot, uint16_t duration_ms)
|
||||
{
|
||||
return _modem_reset(slot, 2, duration_ms);
|
||||
}
|
||||
|
||||
/*! \brief assert the RESET line of the modem */
|
||||
int st_modem_reset_active(struct st_slot *slot)
|
||||
{
|
||||
return _modem_reset(slot, 1, 0);
|
||||
}
|
||||
|
||||
/*! \brief de-assert the RESET line of the modem */
|
||||
int st_modem_reset_inactive(struct st_slot *slot)
|
||||
{
|
||||
return _modem_reset(slot, 0, 0);
|
||||
}
|
||||
|
||||
static int _modem_sim_select(struct st_slot *slot, uint8_t remote_sim)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
struct st_modem_sim_select *ss;
|
||||
|
||||
ss = (struct st_modem_sim_select *) msgb_put(msg, sizeof(*ss));
|
||||
ss->remote_sim = remote_sim;
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_DT_MODEM_SIM_SELECT);
|
||||
}
|
||||
|
||||
/*! \brief select local (physical) SIM for given slot */
|
||||
int st_modem_sim_select_local(struct st_slot *slot)
|
||||
{
|
||||
return _modem_sim_select(slot, 0);
|
||||
}
|
||||
|
||||
/*! \brief select remote (emulated/forwarded) SIM for given slot */
|
||||
int st_modem_sim_select_remote(struct st_slot *slot)
|
||||
{
|
||||
return _modem_sim_select(slot, 1);
|
||||
}
|
||||
|
||||
/*! \brief Request slot to send us status information about the modem */
|
||||
int st_modem_get_status(struct st_slot *slot)
|
||||
{
|
||||
struct msgb *msg = st_msgb_alloc();
|
||||
|
||||
return st_slot_tx_msg(slot, msg, SIMTRACE_MSGC_MODEM, SIMTRACE_MSGT_BD_MODEM_STATUS);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Incoming Messages
|
||||
***********************************************************************/
|
||||
|
@ -663,12 +369,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
|
||||
if (!g_gti) {
|
||||
rc = osmo_st2_gsmtap_init(gsmtap_host);
|
||||
if (rc < 0) {
|
||||
perror("unable to open GSMTAP");
|
||||
goto close_exit;
|
||||
}
|
||||
gsmtap_source_add_sink(g_gti);
|
||||
|
||||
reader = osim_reader_open(OSIM_READER_DRV_PCSC, 0, "", NULL);
|
||||
if (!reader) {
|
|
@ -37,33 +37,19 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "libusb_util.h"
|
||||
#include "simtrace.h"
|
||||
#include "simtrace_usb.h"
|
||||
#include "simtrace_prot.h"
|
||||
#include <osmocom/simtrace2/libusb_util.h>
|
||||
#include <osmocom/simtrace2/simtrace_usb.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/simtrace2/gsmtap.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/sim/class_tables.h>
|
||||
#include <osmocom/sim/sim.h>
|
||||
|
||||
/* as of August 26, 2018 we don't have any released libosmocore version which includes those
|
||||
* definitions yet. Let's ensure some backwards compatibility: */
|
||||
#ifndef GSMTAP_SIM_APDU
|
||||
#define GSMTAP_SIM_APDU 0x00 /* APDU data (complete APDU) */
|
||||
#define GSMTAP_SIM_ATR 0x01 /* card ATR data */
|
||||
#define GSMTAP_SIM_PPS_REQ 0x02 /* PPS request data */
|
||||
#define GSMTAP_SIM_PPS_RSP 0x03 /* PPS response data */
|
||||
#define GSMTAP_SIM_TPDU_HDR 0x04 /* TPDU command header */
|
||||
#define GSMTAP_SIM_TPDU_CMD 0x05 /* TPDU command body */
|
||||
#define GSMTAP_SIM_TPDU_RSP 0x06 /* TPDU response body */
|
||||
#define GSMTAP_SIM_TPDU_SW 0x07 /* TPDU response trailer */
|
||||
#endif
|
||||
|
||||
/* transport to a SIMtrace device */
|
||||
struct st_transport {
|
||||
/* USB */
|
||||
|
@ -75,39 +61,6 @@ struct st_transport {
|
|||
} usb_ep;
|
||||
};
|
||||
|
||||
/* global GSMTAP instance */
|
||||
static struct gsmtap_inst *g_gti;
|
||||
|
||||
static int gsmtap_send_sim(uint8_t sub_type, const uint8_t *data, unsigned int len)
|
||||
{
|
||||
struct gsmtap_hdr *gh;
|
||||
unsigned int gross_len = len + sizeof(*gh);
|
||||
uint8_t *buf = malloc(gross_len);
|
||||
int rc;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(buf, 0, sizeof(*gh));
|
||||
gh = (struct gsmtap_hdr *) buf;
|
||||
gh->version = GSMTAP_VERSION;
|
||||
gh->hdr_len = sizeof(*gh)/4;
|
||||
gh->type = GSMTAP_TYPE_SIM;
|
||||
gh->sub_type = sub_type;
|
||||
|
||||
memcpy(buf + sizeof(*gh), data, len);
|
||||
|
||||
rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
|
||||
if (rc < 0) {
|
||||
perror("write gsmtap");
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct value_string change_flags[] = {
|
||||
{
|
||||
.value = SNIFF_CHANGE_FLAG_CARD_INSERT,
|
||||
|
@ -252,11 +205,11 @@ static int process_data(enum simtrace_msg_type_sniff type, const uint8_t *buf, i
|
|||
/* Send message as GSNTAP */
|
||||
switch (type) {
|
||||
case SIMTRACE_MSGT_SNIFF_ATR:
|
||||
gsmtap_send_sim(GSMTAP_SIM_ATR, data->data, data->length);
|
||||
osmo_st2_gsmtap_send_apdu(GSMTAP_SIM_ATR, data->data, data->length);
|
||||
break;
|
||||
case SIMTRACE_MSGT_SNIFF_TPDU:
|
||||
/* TPDU is now considered as APDU since SIMtrace sends complete TPDU */
|
||||
gsmtap_send_sim(GSMTAP_SIM_APDU, data->data, data->length);
|
||||
osmo_st2_gsmtap_send_apdu(GSMTAP_SIM_APDU, data->data, data->length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -542,12 +495,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
printf("(%s)\n", strbuf);
|
||||
|
||||
g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
|
||||
if (!g_gti) {
|
||||
rc = osmo_st2_gsmtap_init(gsmtap_host);
|
||||
if (rc < 0) {
|
||||
perror("unable to open GSMTAP");
|
||||
goto close_exit;
|
||||
}
|
||||
gsmtap_source_add_sink(g_gti);
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "libusb_util.h"
|
||||
#include "simtrace_usb.h"
|
||||
#include <osmocom/simtrace2/libusb_util.h>
|
||||
#include <osmocom/simtrace2/simtrace_usb.h>
|
||||
|
||||
static const struct dev_id compatible_dev_ids[] = {
|
||||
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OWHW_SAM3 },
|
|
@ -35,9 +35,8 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "simtrace_usb.h"
|
||||
#include "simtrace_prot.h"
|
||||
#include "apdu_dispatch.h"
|
||||
#include <osmocom/simtrace2/simtrace_usb.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/utils.h>
|
Loading…
Reference in New Issue