forked from cellular-infrastructure/osmocom-analog
C-Netz: Implementation of a Funkvermittlungsstelle (FuVSt)
Useful to connect with a Funkfeststation (FuFSt).
This commit is contained in:
parent
b5016d52ba
commit
59119f380f
|
@ -54,6 +54,7 @@ src/anetz/libgermanton.a
|
|||
src/anetz/anetz
|
||||
src/bnetz/bnetz
|
||||
src/bnetz/bnetz-dialer
|
||||
src/cnetz/libcnetztones.a
|
||||
src/cnetz/cnetz
|
||||
src/nmt/libdmssms.a
|
||||
src/nmt/nmt
|
||||
|
@ -72,6 +73,8 @@ src/radio/osmoradio
|
|||
src/datenklo/datenklo
|
||||
src/zeitansage/zeitansage
|
||||
src/sim/cnetz_sim
|
||||
src/fuvst/fuvst
|
||||
src/fuvst/fuvst_sniffer
|
||||
extra/cnetz_memory_card_generator
|
||||
src/test/test_filter
|
||||
src/test/test_sendevolumenregler
|
||||
|
|
4
README
4
README
|
@ -16,6 +16,7 @@ generated simultaniously using SDR. Currently supported networks:
|
|||
* IMTS / MTS ((Improved) Mobile Telephone Service)
|
||||
* Eurosignal (ERuRD paging service)
|
||||
* JollyCom (Unofficial network, invented by the author)
|
||||
* C-Netz BSC (Connecting to a C-Netz Base Station)
|
||||
|
||||
Additionally the following communication services are implemented:
|
||||
|
||||
|
@ -64,3 +65,6 @@ Dieter Spaar providing TACS recordings to verify and debug TACS support.
|
|||
Hans Wigger providing Radiocom 2000 recordings, to reverse-enigeer the standard,
|
||||
which seems not to exist anymore...
|
||||
|
||||
Peter, Peter and Friedhelm and Stephan for providing documentation and hardware
|
||||
for C-Netz Base Station and other C-Netz documents.
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ AC_OUTPUT(
|
|||
src/datenklo/Makefile
|
||||
src/zeitansage/Makefile
|
||||
src/sim/Makefile
|
||||
src/fuvst/Makefile
|
||||
src/test/Makefile
|
||||
src/Makefile
|
||||
extra/Makefile
|
||||
|
|
|
@ -113,6 +113,7 @@ Additional features:
|
|||
<li><a href="datenklo.html">Das Datenklo</a></li>
|
||||
<li><a href="tv.html">Osmo TV</a></li>
|
||||
<li><a href="sim.html">C-Netz Sim Card</a></li>
|
||||
<li>C-Netz FuVSt (BSC to control a real base station)</li>
|
||||
</ul>
|
||||
</center>
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ SUBDIRS += \
|
|||
tv \
|
||||
radio \
|
||||
zeitansage \
|
||||
sim
|
||||
sim \
|
||||
fuvst
|
||||
|
||||
if HAVE_SDR
|
||||
if HAVE_FUSE
|
||||
|
|
|
@ -3,6 +3,11 @@ AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
|||
bin_PROGRAMS = \
|
||||
cnetz
|
||||
|
||||
noinst_LIBRARIES = libcnetztones.a
|
||||
|
||||
libcnetztones_a_SOURCES = \
|
||||
ansage.c
|
||||
|
||||
cnetz_SOURCES = \
|
||||
cnetz.c \
|
||||
transaction.c \
|
||||
|
@ -12,12 +17,12 @@ cnetz_SOURCES = \
|
|||
dsp.c \
|
||||
fsk_demod.c \
|
||||
image.c \
|
||||
ansage.c \
|
||||
stations.c \
|
||||
main.c
|
||||
cnetz_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
../anetz/libgermanton.a \
|
||||
libcnetztones.a \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||
|
||||
if HAVE_ALSA
|
||||
bin_PROGRAMS = \
|
||||
fuvst fuvst_sniffer
|
||||
|
||||
fuvst_SOURCES = \
|
||||
fuvst.c \
|
||||
mup.c \
|
||||
systemmeldungen.c \
|
||||
image.c \
|
||||
main.c
|
||||
fuvst_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
../anetz/libgermanton.a \
|
||||
../cnetz/libcnetztones.a \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
$(top_builddir)/src/libcompandor/libcompandor.a \
|
||||
$(top_builddir)/src/libjitter/libjitter.a \
|
||||
$(top_builddir)/src/libtimer/libtimer.a \
|
||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||
$(top_builddir)/src/libscrambler/libscrambler.a \
|
||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||
$(top_builddir)/src/libfm/libfm.a \
|
||||
$(top_builddir)/src/libv27/libv27.a \
|
||||
$(top_builddir)/src/libmtp/libmtp.a \
|
||||
$(top_builddir)/src/libfilter/libfilter.a \
|
||||
$(top_builddir)/src/libwave/libwave.a \
|
||||
$(top_builddir)/src/libmncc/libmncc.a \
|
||||
$(top_builddir)/src/libsample/libsample.a \
|
||||
$(top_builddir)/src/libsound/libsound.a \
|
||||
$(ALSA_LIBS) \
|
||||
-lm
|
||||
|
||||
fuvst_sniffer_SOURCES = \
|
||||
sniffer.c
|
||||
fuvst_sniffer_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
$(top_builddir)/src/libcompandor/libcompandor.a \
|
||||
$(top_builddir)/src/libjitter/libjitter.a \
|
||||
$(top_builddir)/src/libtimer/libtimer.a \
|
||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||
$(top_builddir)/src/libscrambler/libscrambler.a \
|
||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||
$(top_builddir)/src/libfm/libfm.a \
|
||||
$(top_builddir)/src/libv27/libv27.a \
|
||||
$(top_builddir)/src/libmtp/libmtp.a \
|
||||
$(top_builddir)/src/libfilter/libfilter.a \
|
||||
$(top_builddir)/src/libwave/libwave.a \
|
||||
$(top_builddir)/src/libmncc/libmncc.a \
|
||||
$(top_builddir)/src/libsample/libsample.a \
|
||||
$(top_builddir)/src/libsound/libsound.a \
|
||||
$(ALSA_LIBS) \
|
||||
-lm
|
||||
|
||||
if HAVE_SDR
|
||||
fuvst_LDADD += \
|
||||
$(top_builddir)/src/libsdr/libsdr.a \
|
||||
$(top_builddir)/src/libam/libam.a \
|
||||
$(top_builddir)/src/libfft/libfft.a \
|
||||
$(UHD_LIBS) \
|
||||
$(SOAPY_LIBS)
|
||||
|
||||
fuvst_sniffer_LDADD += \
|
||||
$(top_builddir)/src/libsdr/libsdr.a \
|
||||
$(top_builddir)/src/libam/libam.a \
|
||||
$(top_builddir)/src/libfft/libfft.a \
|
||||
$(UHD_LIBS) \
|
||||
$(SOAPY_LIBS)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
#include "../libmobile/sender.h"
|
||||
#include "../libscrambler/scrambler.h"
|
||||
#include "../libv27/modem.h"
|
||||
#include "../libmtp/mtp.h"
|
||||
#include "mup.h"
|
||||
|
||||
enum fuvst_chan_type {
|
||||
CHAN_TYPE_ZZK, /* SS7 signalling channel */
|
||||
CHAN_TYPE_SPK, /* pure traffic channel */
|
||||
};
|
||||
|
||||
/* instance of fuvst sender */
|
||||
typedef struct fuvst {
|
||||
sender_t sender;
|
||||
v27modem_t modem;
|
||||
mtp_t mtp;
|
||||
|
||||
int chan_num; /* number of SPK or ZZK */
|
||||
enum fuvst_chan_type chan_type; /* ZZK or SPK */
|
||||
int callref;
|
||||
int link; /* MTP l2 link up */
|
||||
struct SysMeld SM; /* collects alarm messages */
|
||||
} fuvst_t;
|
||||
|
||||
int fuvst_create(const char *kanal, enum fuvst_chan_type chan_type, const char *audiodev, int samplerate, double rx_gain, double tx_gain, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, int ignore_link_failure, uint8_t sio, uint16_t local_pc, uint16_t remove_pc);
|
||||
void fuvst_destroy(sender_t *sender);
|
||||
void add_emergency(const char *number);
|
||||
void config_init(void);
|
||||
int config_file(const char *filename);
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../libmobile/image.h"
|
||||
|
||||
const char *image[] = {
|
||||
"",
|
||||
"@K ___. @M._____.@K _.",
|
||||
"@K / \\| @M|/ | \\|@K \\|",
|
||||
"@K | @M | @K __ | @W * FuVSt *",
|
||||
"@K [] | []@M | @K /__\\ | [] @K A CNetz @MMSC@K for",
|
||||
"@K | @M | @K| | @K a real Base Station",
|
||||
"@K \\___/ @M _|_ @K \\__/ _|_",
|
||||
"",
|
||||
NULL
|
||||
};
|
||||
|
||||
void print_image(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; image[i]; i++) {
|
||||
for (j = 0; j < (int)strlen(image[i]); j++) {
|
||||
if (image[i][j] == '@') {
|
||||
j++;
|
||||
switch(image[i][j]) {
|
||||
case 'k': /* black */
|
||||
printf("\033[0;30m");
|
||||
break;
|
||||
case 'r': /* red */
|
||||
printf("\033[0;31m");
|
||||
break;
|
||||
case 'g': /* green */
|
||||
printf("\033[0;32m");
|
||||
break;
|
||||
case 'y': /* yellow */
|
||||
printf("\033[0;33m");
|
||||
break;
|
||||
case 'b': /* blue */
|
||||
printf("\033[0;34m");
|
||||
break;
|
||||
case 'm': /* magenta */
|
||||
printf("\033[0;35m");
|
||||
break;
|
||||
case 'c': /* cyan */
|
||||
printf("\033[0;36m");
|
||||
break;
|
||||
case 'w': /* white */
|
||||
printf("\033[0;37m");
|
||||
break;
|
||||
case 'K': /* bright black */
|
||||
printf("\033[1;30m");
|
||||
break;
|
||||
case 'R': /* bright red */
|
||||
printf("\033[1;31m");
|
||||
break;
|
||||
case 'G': /* bright green */
|
||||
printf("\033[1;32m");
|
||||
break;
|
||||
case 'Y': /* bright yellow */
|
||||
printf("\033[1;33m");
|
||||
break;
|
||||
case 'B': /* bright blue */
|
||||
printf("\033[1;34m");
|
||||
break;
|
||||
case 'M': /* bright magenta */
|
||||
printf("\033[1;35m");
|
||||
break;
|
||||
case 'C': /* bright cyan */
|
||||
printf("\033[1;36m");
|
||||
break;
|
||||
case 'W': /* bright white */
|
||||
printf("\033[1;37m");
|
||||
break;
|
||||
}
|
||||
} else
|
||||
printf("%c", image[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\033[0;39m");
|
||||
}
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
/* FuVSt main
|
||||
*
|
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libdebug/debug.h"
|
||||
#include "../libmobile/call.h"
|
||||
#include "../libmobile/main_mobile.h"
|
||||
#include "../libtimer/timer.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "../libfm/fm.h"
|
||||
#include "../anetz/freiton.h"
|
||||
#include "../anetz/besetztton.h"
|
||||
#include "../cnetz/ansage.h"
|
||||
#include "fuvst.h"
|
||||
|
||||
static int num_chan_type = 0;
|
||||
static enum fuvst_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_ZZK };
|
||||
static uint8_t sio = 0xcd;
|
||||
static uint16_t uele_pc = 1400;
|
||||
static uint16_t fuko_pc = 1466;
|
||||
static int ignore_link_monitor = 0;
|
||||
static int config_loaded = 0;
|
||||
double gebuehren = 12.0;
|
||||
int authentication = 0;
|
||||
int alarms = 1;
|
||||
int warmstart = 0;
|
||||
|
||||
void print_help(const char *arg0)
|
||||
{
|
||||
main_mobile_print_help(arg0, "");
|
||||
/* - - */
|
||||
printf(" -T --channel-type ZZK / SpK\n");
|
||||
printf(" The channel type to use. One ZZK is default.\n");
|
||||
printf(" -S --sio <hex value>\n");
|
||||
printf(" Service Indicator Object. Must be 0xcd! (default = 0x%02x).\n", sio);
|
||||
printf(" -U --uele <value>\n");
|
||||
printf(" Point Code of MSC, which must match the EEPROM configuration data of\n");
|
||||
printf(" the base station. (default = %d).\n", uele_pc);
|
||||
printf(" -F --fuko <value>\n");
|
||||
printf(" Point Code of BS, which must match the EEPROM configuration data of\n");
|
||||
printf(" the base station. (default = %d).\n", fuko_pc);
|
||||
printf(" -A --authentication 1 | 0\n");
|
||||
printf(" Enable or disable authentication procedure. (default = %d).\n", authentication);
|
||||
printf(" -E --emergency <prefix>\n");
|
||||
printf(" Add given prefix to the list of emergency numbers.\n");
|
||||
printf(" --alarms 1 | 0\n");
|
||||
printf(" Enable or disable alarm messages from BS to MSC (default = %d).\n", alarms);
|
||||
printf(" -G --gebuehren <duration>\n");
|
||||
printf(" Give Metering pulse duration is seconds (default = %.2f).\n", gebuehren);
|
||||
printf(" --ignore-link-monitor\n");
|
||||
printf(" Don't do any link error checking at MTP.\n");
|
||||
printf(" -C --config <filename>\n");
|
||||
printf(" Give DKO config file (6 KBytes tape file) to be loaded at boot time.\n");
|
||||
main_mobile_print_hotkeys();
|
||||
}
|
||||
|
||||
#define OPT_ALARMS 256
|
||||
#define OPT_IGNORE_LINK_MONITOR 257
|
||||
|
||||
static void add_options(void)
|
||||
{
|
||||
main_mobile_add_options();
|
||||
option_add('T', "channel-type", 1);
|
||||
option_add('S', "sio", 1);
|
||||
option_add('U', "uele", 1);
|
||||
option_add('F', "fuko", 1);
|
||||
option_add('A', "auth", 1);
|
||||
option_add('E', "emergency", 1);
|
||||
option_add('G', "gebuehren", 1);
|
||||
option_add(OPT_ALARMS, "alarms", 1);
|
||||
option_add(OPT_IGNORE_LINK_MONITOR, "ignore-link-monitor", 0);
|
||||
option_add('C', "config", 1);
|
||||
}
|
||||
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (short_option) {
|
||||
case 'T':
|
||||
if (!strcasecmp(argv[argi], "zzk")) {
|
||||
OPT_ARRAY(num_chan_type, chan_type, CHAN_TYPE_ZZK);
|
||||
} else if (!strcasecmp(argv[argi], "spk")) {
|
||||
OPT_ARRAY(num_chan_type, chan_type, CHAN_TYPE_SPK);
|
||||
} else {
|
||||
fprintf(stderr, "Illegal channel type '%s', see help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
sio = strtoul(argv[argi], NULL, 16);
|
||||
break;
|
||||
case 'U':
|
||||
uele_pc = atoi(argv[argi]);
|
||||
break;
|
||||
case 'F':
|
||||
fuko_pc = atoi(argv[argi]);
|
||||
break;
|
||||
case 'A':
|
||||
authentication = atoi(argv[argi]);
|
||||
break;
|
||||
case 'E':
|
||||
add_emergency(argv[argi]);
|
||||
break;
|
||||
case 'G':
|
||||
gebuehren = atof(argv[argi]);
|
||||
if (gebuehren < 1.0) {
|
||||
fprintf(stderr, "Metering duration too small!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (gebuehren > 2458.0) {
|
||||
fprintf(stderr, "Metering duration too large!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case OPT_ALARMS:
|
||||
alarms = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_IGNORE_LINK_MONITOR:
|
||||
ignore_link_monitor = 1;
|
||||
break;
|
||||
case 'C':
|
||||
rc = config_file(argv[argi]);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
config_loaded = 1;
|
||||
break;
|
||||
default:
|
||||
return main_mobile_handle_options(short_option, argi, argv);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, argi;
|
||||
const char *station_id = "";
|
||||
int i = 0;
|
||||
int any_zzk = 0, any_spk = 0;
|
||||
|
||||
/* init system specific tones */
|
||||
init_freiton();
|
||||
init_besetzton();
|
||||
init_ansage();
|
||||
|
||||
allow_sdr = 0;
|
||||
uses_emphasis = 0;
|
||||
check_channel = 0;
|
||||
main_mobile_init();
|
||||
|
||||
config_init();
|
||||
|
||||
add_emergency("110");
|
||||
add_emergency("112");
|
||||
add_emergency("*110");
|
||||
add_emergency("*112");
|
||||
|
||||
/* handle options / config file */
|
||||
add_options();
|
||||
rc = options_config_file("~/.osmocom/cnetz/fuvst.conf", handle_options);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
if (argi < argc) {
|
||||
station_id = argv[argi];
|
||||
if (strlen(station_id) != 7) {
|
||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_kanal == 1 && num_audiodev == 0)
|
||||
num_audiodev = 1; /* use default */
|
||||
if (num_kanal != num_audiodev) {
|
||||
fprintf(stderr, "You need to specify as many sound devices as you have channels.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num_kanal == 1 && num_chan_type == 0)
|
||||
num_chan_type = 1; /* use default */
|
||||
if (num_kanal != num_chan_type) {
|
||||
fprintf(stderr, "You need to specify as many channel types as you have channels.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
if (chan_type[i] == CHAN_TYPE_ZZK) {
|
||||
if (!!strcmp(kanal[i], "1") && !!strcmp(kanal[i], "2")) {
|
||||
fprintf(stderr, "A ZZK must have a channel 1 or 2.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
any_zzk = 1;
|
||||
}
|
||||
if (chan_type[i] == CHAN_TYPE_SPK)
|
||||
any_spk = 1;
|
||||
}
|
||||
if (!any_zzk) {
|
||||
fprintf(stderr, "You need to specify at least one Control Channel (ZZK).\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!any_spk) {
|
||||
fprintf(stderr, "You need to specify at least one Speech Channel (SpK)\n");
|
||||
fprintf(stderr, "in order to make or receive any call.\n");
|
||||
}
|
||||
|
||||
/* inits */
|
||||
fm_init(fast_math);
|
||||
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
rc = fuvst_create(kanal[i], chan_type[i], audiodev[i], samplerate, rx_gain, tx_gain, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, ignore_link_monitor, sio, uele_pc, fuko_pc);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to create \"Kanal\" instance. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
Does not work! Reset works, but not config is loaded from BS
|
||||
if (config_loaded) {
|
||||
char buffer[10];
|
||||
|
||||
printf("*******************************************************************************\n");
|
||||
printf("You have selected a BS config file. The BS loads this config after cold start.\n");
|
||||
printf("At warm start or reset it doesn't. Press 'y' to force a warm start and load the\n");
|
||||
printf("config, otherwise press 'n'.\n\n");
|
||||
printf("*******************************************************************************\n");
|
||||
do {
|
||||
printf("Enter 'y' or 'n': "); fflush(stdout);
|
||||
if (fgets(buffer, sizeof(buffer), stdin))
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
} while (buffer[0] != 'y' && buffer[0] != 'n');
|
||||
if (buffer[0] == 'y')
|
||||
warmstart = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
if (chan_type[i] == CHAN_TYPE_ZZK)
|
||||
printf("Using Signaling Channel: ZZK-%s\n", kanal[i]);
|
||||
if (chan_type[i] == CHAN_TYPE_SPK)
|
||||
printf("Using Speech Channel: SPK-%s\n", kanal[i]);
|
||||
}
|
||||
|
||||
main_mobile(&quit, latency, interval, NULL, station_id, 7);
|
||||
fail:
|
||||
|
||||
/* destroy transceiver instance */
|
||||
while (sender_head)
|
||||
fuvst_destroy(sender_head);
|
||||
|
||||
/* exits */
|
||||
// zeit_exit();
|
||||
fm_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,145 @@
|
|||
|
||||
#define OPCODE_SWAF 0xc0 /* Wiederanlaufauftrag der BS */
|
||||
#define OPCODE_SWQU 0xe0 /* Wiederanlaufquittung des MSC */
|
||||
|
||||
#define OPCODE_SSSAF 0xcc /* Sprechkanal-Sammel-Sperrauftrag der BS */
|
||||
#define OPCODE_SSSQU 0xec /* Sprechkanal-Sammel-Sperrquitting des MSC */
|
||||
#define OPCODE_SSAF 0xd8 /* SPRECHKANAL-SPERR-AUFTRAG DER BS */
|
||||
#define OPCODE_SSQU 0xd1 /* SPRECHKANAL-SPERR-QUITTUNG VON DER MSC */
|
||||
#define OPCODE_SFAF 0xda /* SPRECHKANAL-FREIGABE-AUFTRAG DER BS */
|
||||
#define OPCODE_SFQU 0xd3 /* SPRECHKANAL-FREIGABE-QUITTUNG VON DER MSC */
|
||||
|
||||
#define OPCODE_SUAF 0xc5 /* Datum-Uhrzeit-Auftrag der BS */
|
||||
#define OPCODE_SUQU 0xe6 /* Datum-Uhrzeit-Quittung des MSC */
|
||||
|
||||
#define OPCODE_SVAF 0xc2 /* Vermittlungsfaehig-Auftrag der BS */
|
||||
#define OPCODE_SVQU 0xe2 /* Vermittlungsfaehig-Quittung des MSC */
|
||||
|
||||
#define OPCODE_YLSAF 0xc3 /* Systemmeldungsanforderung an MSC */
|
||||
#define OPCODE_YLSMU 0xe3 /* Systemmeldungsbestaetigung vom MSC */
|
||||
#define OPCODE_YLSMF 0xdf /* Systemmeldung an MSC */
|
||||
#define OPCODE_YLSEF 0xcb /* Systemmeldungsuebertragungsende an MSC */
|
||||
|
||||
#define OPCODE_STDAF 0xc6 /* Tarifdatenauftrag der BS */
|
||||
#define OPCODE_XGTAU 0x90 /* Tarifdatensignalisierung vom MSC */
|
||||
|
||||
#define OPCODE_EBAF 0x09 /* EINBUCHUNGS-AUFTRAG DER BS */
|
||||
#define OPCODE_EBPQU 0x01 /* EINBUCHUNGS-POSITIV-QUITTUNG VOM MSC */
|
||||
#define OPCODE_EBNQU 0x02 /* EINBUCHUNGS-NEGATIV-QUITTUNG VOM MSC */
|
||||
|
||||
#define OPCODE_ABAF 0x08 /* AUSBUCHUNGS-AUFTRAG DER BS */
|
||||
|
||||
#define OPCODE_GVAF 0x12 /* GEHENDER VERBINDUNGS-AUFTRAG DER BS */
|
||||
#define OPCODE_GVWAF 0x13 /* GEHENDER VERBINDUNGS-WARTESCHLANGEN-AUFTRAG DER BS */
|
||||
#define OPCODE_GVPQU 0x22 /* GEHENDE VERBINDUNGS-POSITIV-QUITTUNG VOM MSC */
|
||||
#define OPCODE_GVNQU 0x23 /* GEHENDE VERBINDUNGS-NEGATIV-QUITTUNG VOM MSC */
|
||||
|
||||
#define OPCODE_KVAU 0x20 /* KOMMENDER VERBINDUNGS-AUFTRAG VOM MSC */
|
||||
#define OPCODE_KVWQF 0x11 /* KOMMENDE VERBINDUNGS-WARTESCHLANGEN-QUITTUNG DER BS */
|
||||
#define OPCODE_KVBAF 0x10 /* KOMMENDE VERBINDUNGS-BEGINN-AUFTRAG DER BS */
|
||||
|
||||
#define OPCODE_STAF 0x18 /* SCHLEIFENTEST-AUFTRAG DER BS */
|
||||
#define OPCODE_STPQU 0x28 /* SCHLEIFENTEST-POSITIV-QUITTUNG VOM MSC */
|
||||
#define OPCODE_STNQU 0x29 /* SCHLEIFENTEST-NEGATIV-QUITTUNG VOM MSC */
|
||||
|
||||
#define OPCODE_APF 0x1d /* AUTORISIERUNGSPARAMETER */
|
||||
|
||||
#define OPCODE_GSTAU 0x2a /* GEBUEHREN-START-AUFTRAG VOM MSC */
|
||||
|
||||
#define OPCODE_FAF 0x19 /* FANG-AUFTRAG BS */
|
||||
|
||||
#define OPCODE_NAF 0x14 /* NEVATIV-AUFTRAG DER BS */
|
||||
#define OPCODE_EQU 0x25 /* ENDE-QUITTUNG VOM MSC */
|
||||
|
||||
#define OPCODE_AAF 0x16 /* AUSLOESE-AUFTRAG DER BS */
|
||||
#define OPCODE_AQU 0x27 /* AUSLOESE-QUITTUNG VOM MSC */
|
||||
|
||||
#define OPCODE_NAU 0x24 /* NEVATIV-AUFTRAG VOM MSC */
|
||||
#define OPCODE_EQF 0x15 /* ENDE-QUITTUNG DER BS */
|
||||
|
||||
#define OPCODE_AAU 0x26 /* AUSLOESE-AUFTRAG VOM MSC */
|
||||
#define OPCODE_AQF 0x17 /* AUSLOESE-QUITTUNG DER BS */
|
||||
|
||||
#define OPCODE_XADBF 0x86 /* ANFORDERUNG EINES BS-DB-DATENBLOCKES VON DER MSC */
|
||||
#define OPCODE_XEDBU 0x9b /* BS-DB-TRANSFER-ERGEBNIS-SIGN. VON DER MSC */
|
||||
|
||||
#define OPCODE_YAAAU 0xd4 /* ANLAUF-AKTIVIERUNGS-AUFTRAG DER MSC (INITIALISIEREN DER BS) */
|
||||
|
||||
#define OPCODE_SWAU 0xe1 /* Wiederanlaufauftrag des MSC */
|
||||
#define OPCODE_SWQF 0xc1 /* Wiederanlauf-Quittung von der BS */
|
||||
|
||||
#define OPCODE_SADAU 0xe4 /* Aktivdatei-Auftrag vom MSC */
|
||||
#define OPCODE_SADQF 0xc4 /* Aktivdateiquittung der BS */
|
||||
|
||||
#define VERSION_LM8 6
|
||||
|
||||
struct SysMeld {
|
||||
uint16_t FUKO;
|
||||
uint8_t Monat;
|
||||
uint8_t Tag;
|
||||
uint8_t Stunde;
|
||||
uint8_t Minute;
|
||||
uint8_t Kennzeichen_posthum;
|
||||
uint16_t Systemmeldungsnr;
|
||||
uint8_t Indizienlaenge;
|
||||
uint8_t Indizien[10];
|
||||
uint8_t ASCII_Typ;
|
||||
uint8_t Einrichtungstyp;
|
||||
uint8_t Einrichtungsnr;
|
||||
uint8_t Zusatzinfo[4];
|
||||
};
|
||||
|
||||
const char *einrichtrungstyp_string(uint8_t T);
|
||||
|
||||
void decode_swaf(uint8_t *data, int len, uint8_t *V, uint8_t *N, uint8_t *U, uint8_t *F, uint8_t *C, uint8_t *B);
|
||||
int encode_swqu(uint8_t *opcode, uint8_t **data, uint8_t A);
|
||||
void decode_suaf(uint8_t *data, int len, uint8_t *V, uint8_t *N, uint8_t *U, uint8_t *F, uint8_t *C, uint8_t *B);
|
||||
int encode_suqu(uint8_t *opcode, uint8_t **data, uint8_t Q, uint8_t N, time_t now);
|
||||
void decode_sssaf(uint8_t *data, int len);
|
||||
void encode_sssqu(uint8_t *opcode);
|
||||
void decode_ssaf(uint8_t *data, int len, uint8_t *S);
|
||||
int encode_ssqu(uint8_t *opcode, uint8_t **data, uint8_t S);
|
||||
void decode_sfaf(uint8_t *data, int len, uint8_t *S);
|
||||
int encode_sfqu(uint8_t *opcode, uint8_t **data, uint8_t S);
|
||||
void decode_svaf(uint8_t *data, int len);
|
||||
int encode_svqu(uint8_t *opcode, uint8_t **data);
|
||||
void decode_ylsaf(uint8_t *data, int len);
|
||||
int encode_ylsmu(uint8_t *opcode, uint8_t **data);
|
||||
void decode_ylsmf(uint8_t *data, int len, uint8_t *N, uint8_t *C, struct SysMeld *SM);
|
||||
void decode_ylsef(uint8_t *data, int len);
|
||||
void decode_stdaf(uint8_t *data, int len);
|
||||
int encode_xgtau(uint8_t *opcode, uint8_t **data, uint8_t Z, uint32_t T, uint8_t S, uint8_t K, uint16_t CS);
|
||||
void decode_ebaf(uint8_t *data, int len, uint16_t *T, uint8_t *U, uint8_t *N, uint16_t *s, uint8_t *u, uint8_t *b, uint8_t *l);
|
||||
int encode_ebpqu(uint8_t *opcode, uint8_t **data);
|
||||
void decode_abaf(uint8_t *data, int len, uint16_t *T, uint8_t *U, uint8_t *N);
|
||||
void decode_gvaf(uint8_t *data, int len, uint16_t *T, uint8_t *U, uint8_t *N, char *number);
|
||||
void decode_gvwaf(uint8_t *data, int len, uint16_t *T, uint8_t *U, uint8_t *N, char *number);
|
||||
int encode_gvpqu(uint8_t *opcode, uint8_t **data, uint8_t P, uint8_t e);
|
||||
int encode_gvnqu(uint8_t *opcode, uint8_t **data, uint8_t X, uint8_t Y);
|
||||
int encode_kvau(uint8_t *opcode, uint8_t **data, uint16_t T, uint8_t U, uint8_t N, uint8_t F, uint8_t e);
|
||||
void decode_kvwqf(uint8_t __attribute__((unused)) *data, int __attribute__((unused)) len);
|
||||
void decode_kvbaf(uint8_t __attribute__((unused)) *data, int __attribute__((unused)) len);
|
||||
void decode_staf(uint8_t *data, int len, uint8_t *Q, uint8_t *V, uint8_t *e, uint64_t *n);
|
||||
int encode_stpqu(uint8_t *opcode, uint8_t **data, uint8_t Q, uint8_t A, uint8_t K, uint16_t G, uint8_t U, uint8_t X, uint8_t Y, uint8_t mystery);
|
||||
int encode_stnqu(uint8_t *opcode, uint8_t **data, uint8_t Q);
|
||||
void decode_apf(uint8_t *data, int len, uint8_t *Q, uint64_t *a);
|
||||
int encode_gstau(uint8_t *opcode, uint8_t **data, uint8_t Q, uint16_t G, uint8_t U, uint8_t Y, uint8_t A, uint8_t K);
|
||||
void decode_faf(uint8_t __attribute__((unused)) *data, int __attribute__((unused)) len);
|
||||
void decode_naf(uint8_t *data, int len, uint8_t *X);
|
||||
int encode_equ(uint8_t *opcode, uint8_t **data);
|
||||
void decode_aaf(uint8_t *data, int len, uint8_t *Q, uint8_t *X);
|
||||
int encode_aqu(uint8_t *opcode, uint8_t **data, uint8_t Q);
|
||||
int encode_nau(uint8_t *opcode, uint8_t **data, uint8_t X, uint8_t Y);
|
||||
void decode_eqf(uint8_t *data, int len);
|
||||
int encode_aau(uint8_t *opcode, uint8_t **data, uint8_t Q, uint8_t X, uint8_t Y);
|
||||
void decode_aqf(uint8_t *data, int len, uint8_t *Q);
|
||||
void decode_xadbf(uint8_t *data, int len, uint8_t *PJ, uint16_t *D, uint16_t *L);
|
||||
int encode_xedbu_1(uint8_t *opcode, uint8_t **data, uint8_t R, uint8_t PJ, uint16_t A);
|
||||
int encode_xedbu_2(uint8_t *opcode, uint8_t **data, uint8_t S, uint8_t PJ, uint8_t *P);
|
||||
int encode_xedbu_3(uint8_t *opcode, uint8_t **data, uint8_t S, uint8_t PJ, uint16_t D, uint16_t L, uint32_t CS);
|
||||
int encode_yaaau(uint8_t *opcode, uint8_t **data, uint8_t J);
|
||||
int encode_swau(uint8_t *opcode, uint8_t **data, uint8_t V);
|
||||
void decode_swqf(uint8_t *data, int len, uint8_t *V, uint8_t *N, uint8_t *U, uint8_t *F, uint8_t *C, uint8_t *B);
|
||||
void encode_sadau(uint8_t *opcode);
|
||||
int decode_sadqf(uint8_t *data, int len, uint16_t *S, uint8_t *E, uint8_t *l, uint16_t *T, uint8_t *U, uint8_t *N);
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
/* FuVSt Sniffer
|
||||
*
|
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libtimer/timer.h"
|
||||
#include "../libdebug/debug.h"
|
||||
#include "../libmobile/call.h"
|
||||
#include "../libmobile/main_mobile.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "../libmobile/sender.h"
|
||||
#include "../libv27/modem.h"
|
||||
#include "../libmtp/mtp.h"
|
||||
#include "../libfm/fm.h"
|
||||
|
||||
typedef struct sniffer {
|
||||
sender_t sender;
|
||||
v27modem_t modem;
|
||||
mtp_t mtp;
|
||||
uint8_t last_fsn;
|
||||
} sniffer_t;
|
||||
|
||||
|
||||
void print_help(const char *arg0)
|
||||
{
|
||||
main_mobile_print_help(arg0, "");
|
||||
/* - - */
|
||||
printf("Use '-k BS -k BSC' to trace both sides of SS7 link, using a stereo input.\n");
|
||||
printf("Use '-v 0' for total message logging, including errors.\n");
|
||||
printf("Use '-v 1' for all messages, including resends (and weird messages from SAE).\n");
|
||||
printf("Use '-v 2' for messages between DKO and MSC.\n");
|
||||
main_mobile_print_hotkeys();
|
||||
}
|
||||
|
||||
static void add_options(void)
|
||||
{
|
||||
main_mobile_add_options();
|
||||
}
|
||||
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
switch (short_option) {
|
||||
default:
|
||||
return main_mobile_handle_options(short_option, argi, argv);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FISU is received form L2 */
|
||||
static void receive_fisu(mtp_t *mtp, uint8_t bsn, uint8_t bib, uint8_t fsn, uint8_t fib)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *)mtp->inst;
|
||||
|
||||
PDEBUG(DMTP3, (fsn == sniffer->last_fsn) ? DEBUG_INFO : DEBUG_NOTICE, "%s FISU Frame: FSN=%d FIB=%d BSN=%d BIB=%d\n", mtp->name, fsn, fib, bsn, bib);
|
||||
|
||||
/* store current FSN */
|
||||
sniffer->last_fsn = fsn;
|
||||
}
|
||||
|
||||
/* LSSU is received form L2 */
|
||||
static void receive_lssu(mtp_t *mtp, uint8_t fsn, uint8_t bib, uint8_t status)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *)mtp->inst;
|
||||
|
||||
PDEBUG(DMTP3, DEBUG_INFO, "%s LSSU Frame: FSN=%d BIB=%d status=%d\n", mtp->name, fsn, bib, status);
|
||||
|
||||
/* store initial FSN */
|
||||
sniffer->last_fsn = fsn;
|
||||
}
|
||||
|
||||
/* MSU is received form L2 */
|
||||
static void receive_msu(mtp_t *mtp, uint8_t bsn, uint8_t bib, uint8_t fsn, uint8_t fib, uint8_t sio, uint8_t *data, int len)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *)mtp->inst;
|
||||
uint16_t dcp, ocp;
|
||||
uint8_t slc, h2h1;
|
||||
uint8_t ident, opcode;
|
||||
|
||||
if (len < 4) {
|
||||
PDEBUG(DMTP3, DEBUG_NOTICE, "Short frame from layer 2 (len=%d)\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsn == sniffer->last_fsn) {
|
||||
PDEBUG(DMTP3, DEBUG_INFO, "%s MSU Frame: FSN=%d FIB=%d BSN=%d BIB=%d data: %02x %s\n", mtp->name, fsn, fib, bsn, bib, sio, debug_hex(data, len));
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 6) {
|
||||
PDEBUG(DMTP3, DEBUG_NOTICE, "Frame from layer 2 too short to carry an Opcode (len=%d)\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
dcp = data[0];
|
||||
dcp |= (data[1] << 8) & 0x3f00;
|
||||
ocp = data[1] >> 6;
|
||||
ocp |= data[2] << 2;
|
||||
ocp |= (data[3] << 10) & 0x3c00;
|
||||
slc = data[3] >> 4;
|
||||
h2h1 = data[4];
|
||||
ident = (h2h1 << 4) | slc;
|
||||
opcode = (data[5] >> 4) | (data[5] << 4);
|
||||
data += 6;
|
||||
len -= 6;
|
||||
|
||||
if (sio == 0xcd)
|
||||
PDEBUG(DMTP3, DEBUG_NOTICE, "%s MuP Frame: FSN=%d FIB=%d BSN=%d BIB=%d SIO=0x%02x DCP=%d OCP=%d Ident=0x%02x OP=%02XH %s\n", mtp->name, fsn, fib, bsn, bib, sio, dcp, ocp, ident, opcode, debug_hex(data, len));
|
||||
else
|
||||
PDEBUG(DMTP3, DEBUG_NOTICE, "%s MSU Frame: FSN=%d FIB=%d BSN=%d BIB=%d SIO=0x%02x DCP=%d OCP=%d SLC=%d H2/H1=0x%02x %02x %s\n", mtp->name, fsn, fib, bsn, bib, sio, dcp, ocp, slc, h2h1, data[-1], debug_hex(data, len));
|
||||
|
||||
/* store current FSN */
|
||||
sniffer->last_fsn = fsn;
|
||||
}
|
||||
|
||||
/* a bit is sent to the modem */
|
||||
static int send_bit(void *inst)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *)inst;
|
||||
|
||||
if (sniffer->sender.loopback)
|
||||
return mtp_send_bit(&sniffer->mtp);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a bit is received from the modem */
|
||||
static void receive_bit(void *inst, int bit)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *)inst;
|
||||
|
||||
mtp_receive_bit(&sniffer->mtp, bit);
|
||||
}
|
||||
|
||||
/* Destroy transceiver instance and unlink from list. */
|
||||
void sniffer_destroy(sender_t *sender)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *) sender;
|
||||
|
||||
PDEBUG(DCNETZ, DEBUG_DEBUG, "Destroying 'Sniffer' instance for 'Kanal' = %s.\n", sender->kanal);
|
||||
|
||||
mtp_exit(&sniffer->mtp);
|
||||
|
||||
v27_modem_exit(&sniffer->modem);
|
||||
|
||||
sender_destroy(&sniffer->sender);
|
||||
free(sniffer);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, argi;
|
||||
int i = 0;
|
||||
sniffer_t *sniffer;
|
||||
|
||||
/* forward L2 messages here */
|
||||
func_mtp_receive_fisu = receive_fisu;
|
||||
func_mtp_receive_lssu = receive_lssu;
|
||||
func_mtp_receive_msu = receive_msu;
|
||||
|
||||
allow_sdr = 0;
|
||||
uses_emphasis = 0;
|
||||
check_channel = 0;
|
||||
main_mobile_init();
|
||||
|
||||
/* handle options / config file */
|
||||
add_options();
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
/* inits */
|
||||
fm_init(fast_math);
|
||||
|
||||
if (!num_kanal) {
|
||||
printf("No channel (\"Kanal\") is specified, I suggest to add two channels 'MSC' and 'BS'.\n\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (num_audiodev <= 1)
|
||||
audiodev[1] = audiodev[0];
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
PDEBUG(DCNETZ, DEBUG_DEBUG, "Creating 'Sniffer' instance for 'Kanal' = %s (sample rate %d).\n", kanal[i], samplerate);
|
||||
|
||||
sniffer = calloc(1, sizeof(sniffer_t));
|
||||
if (!sniffer) {
|
||||
PDEBUG(DCNETZ, DEBUG_ERROR, "No memory!\n");
|
||||
goto fail;
|
||||
}
|
||||
rc = sender_create(&sniffer->sender, kanal[i], 131, 131, audiodev[i], 0, samplerate, rx_gain, tx_gain, 0, 0, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, PAGING_SIGNAL_NONE);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to create \"Sniffer\" instance. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = mtp_init(&sniffer->mtp, kanal[i], sniffer, NULL, 4800, 1, 0, 0, 0);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
|
||||
sender_set_fm(&sniffer->sender, 1.0, 4000.0, 1.0, 1.0);
|
||||
|
||||
rc = v27_modem_init(&sniffer->modem, sniffer, send_bit, receive_bit, samplerate, 1);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
main_mobile(&quit, latency, interval, NULL, NULL, 0);
|
||||
|
||||
fail:
|
||||
/* destroy transceiver instance */
|
||||
while (sender_head)
|
||||
sniffer_destroy(sender_head);
|
||||
|
||||
/* exits */
|
||||
fm_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* don't send anything */
|
||||
void sender_send(sender_t __attribute__((unused)) *sender, sample_t *samples, uint8_t *power, int length)
|
||||
{
|
||||
memset(power, 0, length);
|
||||
|
||||
memset(samples, 0, sizeof(*samples) * length);
|
||||
}
|
||||
|
||||
/* we receive everything */
|
||||
void sender_receive(sender_t *sender, sample_t *samples, int length, double __attribute__((unused)) rf_level_db)
|
||||
{
|
||||
sniffer_t *sniffer = (sniffer_t *) sender;
|
||||
|
||||
v27_modem_receive(&sniffer->modem, samples, length);
|
||||
}
|
||||
|
||||
void call_down_audio(int __attribute__((unused)) callref, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count) { }
|
||||
|
||||
void call_down_clock(void) {}
|
||||
|
||||
int call_down_setup(int __attribute__((unused)) callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char __attribute__((unused)) *dialing) { return 0; }
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref) { }
|
||||
|
||||
void call_down_disconnect(int __attribute__((unused)) callref, int __attribute__((unused)) cause) { }
|
||||
|
||||
void call_down_release(int __attribute__((unused)) callref, int __attribute__((unused)) cause) { }
|
||||
|
||||
void print_image(void) {}
|
||||
|
||||
void dump_info(void) {}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void print_systemmeldung(uint16_t code, int bytes, uint8_t *ind);
|
||||
|
|
@ -77,6 +77,7 @@ struct debug_cat {
|
|||
{ "sim layer 7", "\033[0;37m" },
|
||||
{ "mtp layer 2", "\033[1;33m" },
|
||||
{ "mtp layer 3", "\033[1;36m" },
|
||||
{ "MuP", "\033[1;37m" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define DSIM7 33
|
||||
#define DMTP2 34
|
||||
#define DMTP3 35
|
||||
#define DMUP 36
|
||||
|
||||
void get_win_size(int *w, int *h);
|
||||
|
||||
|
|
Loading…
Reference in New Issue