aboutsummaryrefslogtreecommitdiffstats
path: root/src/cnetz
diff options
context:
space:
mode:
Diffstat (limited to 'src/cnetz')
-rw-r--r--src/cnetz/Makefile.am16
-rw-r--r--src/cnetz/cnetz.c702
-rw-r--r--src/cnetz/cnetz.h31
-rw-r--r--src/cnetz/database.c97
-rw-r--r--src/cnetz/database.h4
-rw-r--r--src/cnetz/dsp.c265
-rw-r--r--src/cnetz/dsp.h2
-rw-r--r--src/cnetz/fsk_demod.c82
-rw-r--r--src/cnetz/fsk_demod.h4
-rw-r--r--src/cnetz/image.c95
-rw-r--r--src/cnetz/main.c127
-rw-r--r--src/cnetz/stations.c4493
-rw-r--r--src/cnetz/stations.h2
-rw-r--r--src/cnetz/sysinfo.c11
-rw-r--r--src/cnetz/sysinfo.h6
-rw-r--r--src/cnetz/telegramm.c127
-rw-r--r--src/cnetz/telegramm.h2
-rw-r--r--src/cnetz/transaction.c140
-rw-r--r--src/cnetz/transaction.h25
19 files changed, 3146 insertions, 3085 deletions
diff --git a/src/cnetz/Makefile.am b/src/cnetz/Makefile.am
index 28ae31a..fcf96da 100644
--- a/src/cnetz/Makefile.am
+++ b/src/cnetz/Makefile.am
@@ -1,8 +1,13 @@
-AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
+AM_CPPFLAGS = -Wall -Wextra -Wmissing-prototypes -g $(all_includes)
bin_PROGRAMS = \
cnetz
+noinst_LIBRARIES = libcnetztones.a
+
+libcnetztones_a_SOURCES = \
+ ansage.c
+
cnetz_SOURCES = \
cnetz.c \
transaction.c \
@@ -12,27 +17,28 @@ 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 \
$(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/libfilter/libfilter.a \
$(top_builddir)/src/libwave/libwave.a \
- $(top_builddir)/src/libmncc/libmncc.a \
$(top_builddir)/src/libsample/libsample.a \
+ $(top_builddir)/src/libaaimage/libaaimage.a \
+ $(top_builddir)/src/liblogging/liblogging.a \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOCC_LIBS) \
-lm
if HAVE_ALSA
diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c
index df0968b..b3771d7 100644
--- a/src/cnetz/cnetz.c
+++ b/src/cnetz/cnetz.c
@@ -42,7 +42,7 @@
* If no SpK is available, the call is rejected. If queue (Warteschlange) is
* enabled, WSK(R) is scheduled. After transmission, the state changes to
* TRANS_MT_QUEUE. Upon timeout (no channel becomes available), the call is
- * rejected by scheduling VA(R). Upon available channel the call proceeeds with
+ * rejected by scheduling VA(R). Upon available channel the call proceeds with
* VAK(R) as described above.
*
* If an MO (mobile originating) call is made (received VWG(K)), a transaction
@@ -57,11 +57,11 @@
* (Warteschlange) is enabled, WWBP(R) is scheduled. After transmission, the
* state is changed to TRANS_MO_QUEUE. Upon timeout (no channel becomes
* available), the call is rejected by scheduling VA(R). Upon available channel
- * the call proceeeds with VAG(R) as described above.
+ * the call proceeds with VAG(R) as described above.
*
* Switching to SpK is performed two time slots after transmitting VAK(R) or
* VAG(R). The timer is started. The schedulers schedules 8 times BQ(K) and
- * awaits at least one BEL(K). If BEK(K) is received, the timer is stoped. If
+ * awaits at least one BEL(K). If BEK(K) is received, the timer is stopped. If
* BQ(K) was sent at least 8 times and if timer is stopped, the scheduler
* schedules VHQ(K). If no BEL(K) was received, AFK(K) is scheduled N_AFKT
* times, then the process on OgK (WBP+VAG or VAK) is repeated N times.
@@ -114,7 +114,7 @@
/*
* Notes on the combined channel hack:
*
- * For combined SpK+OgK hack, the channel is used as SpK as last choise. This
+ * For combined SpK+OgK hack, the channel is used as SpK as last choice. This
* allows to use only one transceiver for making C-Netz to work. Also it allows
* to use all transceivers for simultanious phone calls. Some phones may not
* work with that.
@@ -126,7 +126,7 @@
* The encoder generates a precise clocked signal using correction value given
* by command line. For multichannel, the second sound card's channel (slave) is
* synced to the first one (master), if calculation of signal phase might drift
- * due to routing errors.
+ * due to rounding errors.
*
* The decoder is synced to the phone, whenever it receives a valid frame.
*
@@ -143,9 +143,12 @@
#include <math.h>
#include <inttypes.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "../libmobile/call.h"
-#include "../libmncc/cause.h"
+#include "../libmobile/cause.h"
+#include "../libmobile/get_time.h"
+#include "../libmobile/console.h"
+#include <osmocom/cc/message.h>
#include "cnetz.h"
#include "database.h"
#include "sysinfo.h"
@@ -156,11 +159,15 @@
/* uncomment this to do echo debugging (-l) on Speech Channel */
//#define DEBUG_SPK
+#define FLOAT_TO_TIMEOUT(f) floor(f), ((f) - floor(f)) * 1000000
+
#define CUT_OFF_EMPHASIS_CNETZ 796.0 /* 200 uS time constant */
-/* Call reference for calls from mobile station to network
- This offset of 0x400000000 is required for MNCC interface. */
-static int new_callref = 0x40000000;
+/* OgK list of alternative channels, NOT including 131 */
+cnetz_t *ogk_list[16];
+int ogk_list_count = 0;
+int ogk_list_index = 0;
+
/* Convert channel number to frequency number of base station.
Set 'unterband' to 1 to get frequency of mobile station. */
@@ -181,6 +188,28 @@ double cnetz_kanal2freq(int kanal, int unterband)
return freq * 1e6;
}
+/* check if number is a valid station ID */
+const char *cnetz_number_valid(const char *number)
+{
+ /* assume that the number has valid length(s) and digits */
+
+ if (number[0] > '7')
+ return "Digit 1 (mobile country code) exceeds 7.";
+ if (number[7]) {
+ if ((number[1] - '0') == 0)
+ return "Digit 2 and 3 (mobile network code) of 8-digit number must be at least 10.";
+ if ((number[1] - '0') * 10 + (number[2] - '0') > 31)
+ return "Digit 2 and 3 (mobile network code) of 8-digit number exceed 31.";
+ if (atoi(number + 3) > 65535)
+ return "Digit 4 to 8 (mobile subscriber suffix) of 8-digit number exceed 65535.";
+ } else {
+ if (atoi(number + 2) > 65535)
+ return "Digit 3 to 7 (mobile subscriber suffix) of 7-digit number exceed 65535.";
+ }
+
+ return NULL;
+}
+
/* convert power level to P-bits by selecting next higher level */
static uint8_t cnetz_power2bits(int power)
{
@@ -201,7 +230,7 @@ static uint8_t cnetz_power2bits(int power)
}
}
-const char *cnetz_state_name(enum cnetz_state state)
+static const char *cnetz_state_name(enum cnetz_state state)
{
static char invalid[16];
@@ -238,13 +267,13 @@ static void cnetz_new_state(cnetz_t *cnetz, enum cnetz_state new_state)
{
if (cnetz->state == new_state)
return;
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "State change: %s -> %s\n", cnetz_state_name(cnetz->state), cnetz_state_name(new_state));
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "State change: %s -> %s\n", cnetz_state_name(cnetz->state), cnetz_state_name(new_state));
cnetz->state = new_state;
cnetz_display_status();
}
/* Convert ISDN cause to 'Ausloesegrund' of C-Netz mobile station */
-uint8_t cnetz_cause_isdn2cnetz(int cause)
+static uint8_t cnetz_cause_isdn2cnetz(int cause)
{
switch (cause) {
case CAUSE_NORMAL:
@@ -267,65 +296,71 @@ int cnetz_init(void)
}
/* Create transceiver instance and link to a list. */
-int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
+int cnetz_create(const char *kanal_name, enum cnetz_chan_type chan_type, const char *device, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, double tx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
{
sender_t *sender;
cnetz_t *cnetz;
+ int kanal;
int rc;
- if ((atoi(kanal) & 1) && (atoi(kanal) < 3 || atoi(kanal) > 1147)) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %s invalid. For odd channel numbers, use channel 3 ... 1147.\n", kanal);
+ kanal = atoi(kanal_name);
+ if ((kanal & 1) && (kanal < 3 || kanal > 1147)) {
+ LOGP(DCNETZ, LOGL_ERROR, "Channel ('Kanal') number %d invalid. For odd channel numbers, use channel 3 ... 1147.\n", kanal);
return -EINVAL;
}
- if ((atoi(kanal) & 1) && atoi(kanal) > 947) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency channel %s, only newer phones support this!\n", kanal);
+ if ((kanal & 1) && kanal > 947) {
+ LOGP(DCNETZ, LOGL_NOTICE, "You defined an extended frequency channel %d, only newer phones support this!\n", kanal);
}
- if (!(atoi(kanal) & 1) && (atoi(kanal) < 4 || atoi(kanal) > 918)) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %s invalid. For even channel numbers, use channel 4 ... 918.\n", kanal);
+ if (!(kanal & 1) && (kanal < 4 || kanal > 918)) {
+ LOGP(DCNETZ, LOGL_ERROR, "Channel ('Kanal') number %d invalid. For even channel numbers, use channel 4 ... 918.\n", kanal);
return -EINVAL;
}
- if (!(atoi(kanal) & 1) && atoi(kanal) > 758) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency %s, only newer phones support this!\n", kanal);
- }
-
- /* OgK must be on channel 131 */
- if ((chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK) && atoi(kanal) != CNETZ_OGK_KANAL) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "You must use channel %d for calling channel ('Orga-Kanal') or for combined calling + traffic channel!\n", CNETZ_OGK_KANAL);
- return -EINVAL;
+ if (!(kanal & 1) && kanal > 758) {
+ LOGP(DCNETZ, LOGL_NOTICE, "You defined an extended frequency channel %d, only newer phones support this!\n", kanal);
}
/* SpK must be on channel other than 131 */
- if (chan_type == CHAN_TYPE_SPK && atoi(kanal) == CNETZ_OGK_KANAL) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "You must not use channel %d for traffic channel!\n", CNETZ_OGK_KANAL);
+ if (chan_type == CHAN_TYPE_SPK && kanal == CNETZ_STD_OGK_KANAL) {
+ LOGP(DCNETZ, LOGL_NOTICE, "You must not use channel %d for traffic channel!\n", CNETZ_STD_OGK_KANAL);
return -EINVAL;
}
/* warn if we combine SpK and OgK, this is not supported by standard */
if (chan_type == CHAN_TYPE_OGK_SPK) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "You selected channel %d ('Orga-Kanal') for combined calling + traffic channel. Some phones will reject this.\n", CNETZ_OGK_KANAL);
+ LOGP(DCNETZ, LOGL_NOTICE, "You selected channel %d ('Orga-Kanal') for combined control + traffic channel. Some phones will reject this.\n", kanal);
}
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *)sender;
- if (!!strcmp(sender->audiodev, audiodev)) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "To be able to sync multiple channels, all channels must be on the same sound device!\n");
+ if (!!strcmp(sender->device, device)) {
+ LOGP(DCNETZ, LOGL_NOTICE, "To be able to sync multiple channels, all channels must be on the same sound device!\n");
return -EINVAL;
}
}
cnetz = calloc(1, sizeof(cnetz_t));
if (!cnetz) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "No memory!\n");
+ LOGP(DCNETZ, LOGL_ERROR, "No memory!\n");
return -ENOMEM;
}
- PDEBUG(DCNETZ, DEBUG_DEBUG, "Creating 'C-Netz' instance for 'Kanal' = %s (sample rate %d).\n", kanal, samplerate);
+ LOGP(DCNETZ, LOGL_DEBUG, "Creating 'C-Netz' instance for 'Kanal' = %d (sample rate %d).\n", kanal, samplerate);
+
+ cnetz->kanal = kanal;
+ if ((chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK) && kanal != CNETZ_STD_OGK_KANAL) {
+ if (ogk_list_count == 16) {
+ LOGP(DCNETZ, LOGL_ERROR, "No more than 16 non-standard OGK are allowed!\n");
+ rc = -EINVAL;
+ goto error;
+ }
+ ogk_list[ogk_list_count++] = cnetz;
+ }
/* init general part of transceiver */
/* do not enable emphasis, since it is done by cnetz code, not by common sender code */
- rc = sender_create(&cnetz->sender, kanal, cnetz_kanal2freq(atoi(kanal), 0), cnetz_kanal2freq(atoi(kanal), 1), audiodev, use_sdr, samplerate, rx_gain, 0, 0, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, PAGING_SIGNAL_NONE);
+ rc = sender_create(&cnetz->sender, kanal_name, cnetz_kanal2freq(kanal, 0), cnetz_kanal2freq(kanal, 1), device, use_sdr, 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) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to init transceiver process!\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to init transceiver process!\n");
goto error;
}
@@ -340,7 +375,7 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
/* init audio processing */
rc = dsp_init_sender(cnetz, measure_speed, clock_speed, demod, speech_deviation);
if (rc < 0) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to init signal processing!\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to init signal processing!\n");
goto error;
}
@@ -377,42 +412,46 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
goto error;
/* go into idle state */
- cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK);
- cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_OGK, 0);
+ if (chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK)
+ cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK);
+ else
+ cnetz_set_dsp_mode(cnetz, DSP_MODE_OFF);
cnetz_go_idle(cnetz);
#ifdef DEBUG_SPK
- transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1);
+ transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1, NAN);
trans->mo_call = 1;
- cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 2);
+ cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31);
#else
/* create transaction for speech channel loopback */
if (loopback && chan_type == CHAN_TYPE_SPK) {
- transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1);
+ transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1, NAN);
trans->mo_call = 1;
cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K);
- cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 0);
+ cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 1) & 31);
}
#endif
#if 0
/* debug flushing transactions */
transaction_t *trans1, *trans2;
- trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
+ trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
destroy_transaction(trans1);
- trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
+ trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
destroy_transaction(trans1);
- trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
- trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
+ trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
+ trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1, NAN);
unlink_transaction(trans1);
link_transaction(trans1, cnetz);
cnetz_flush_other_transactions(cnetz, trans1);
- trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
+ trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1, NAN);
cnetz_flush_other_transactions(cnetz, trans2);
#endif
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Created 'Kanal' #%s of type '%s' = %s\n", kanal, chan_type_short_name(chan_type), chan_type_long_name(chan_type));
- PDEBUG(DNMT, DEBUG_NOTICE, " -> Using cell ID: Nat=%d FuVst=%d Rest=%d Name='%s'\n", si.fuz_nat, si.fuz_fuvst, si.fuz_rest, get_station_name(si.fuz_nat, si.fuz_fuvst, si.fuz_rest));
+ LOGP(DCNETZ, LOGL_NOTICE, "Created 'Kanal' #%d of type '%s' = %s\n", kanal, chan_type_short_name(chan_type), chan_type_long_name(chan_type));
+ const char *name, *long_name;
+ name = get_station_name(si.fuz_nat, si.fuz_fuvst, si.fuz_rest, &long_name);
+ LOGP(DCNETZ, LOGL_NOTICE, " -> Using cell ID: Nat=%d FuVst=%d Rest=%d Name='%s' Long Name='%s'\n", si.fuz_nat, si.fuz_fuvst, si.fuz_rest, name, long_name);
return 0;
@@ -428,11 +467,11 @@ void cnetz_destroy(sender_t *sender)
cnetz_t *cnetz = (cnetz_t *) sender;
transaction_t *trans;
- PDEBUG(DCNETZ, DEBUG_DEBUG, "Destroying 'C-Netz' instance for 'Kanal' = %s.\n", sender->kanal);
+ LOGP(DCNETZ, LOGL_DEBUG, "Destroying 'C-Netz' instance for 'Kanal' = %s.\n", sender->kanal);
while ((trans = search_transaction(cnetz, ~0))) {
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Removing pending transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DCNETZ, LOGL_NOTICE, "Removing pending transaction for subscriber '%s'\n", rufnummer);
destroy_transaction(trans);
}
@@ -450,9 +489,9 @@ static cnetz_t *search_free_spk(int extended)
cnetz = (cnetz_t *) sender;
/* ignore extended frequency, if not supported */
if (!extended) {
- if ((atoi(sender->kanal) & 1) && atoi(sender->kanal) > 947)
+ if ((cnetz->kanal & 1) && cnetz->kanal > 947)
continue;
- if (!(atoi(sender->kanal) & 1) && atoi(sender->kanal) > 758)
+ if (!(cnetz->kanal & 1) && cnetz->kanal > 758)
continue;
}
/* ignore busy channel */
@@ -469,7 +508,7 @@ static cnetz_t *search_free_spk(int extended)
return ogk_spk;
}
-static cnetz_t *search_ogk(void)
+static cnetz_t *search_ogk(int kanal)
{
sender_t *sender;
cnetz_t *cnetz;
@@ -479,6 +518,8 @@ static cnetz_t *search_ogk(void)
/* ignore busy channel */
if (cnetz->state != CNETZ_IDLE)
continue;
+ if (cnetz->kanal != kanal)
+ continue;
if (cnetz->chan_type == CHAN_TYPE_OGK)
return cnetz;
if (cnetz->chan_type == CHAN_TYPE_OGK_SPK)
@@ -491,39 +532,40 @@ static cnetz_t *search_ogk(void)
/* Abort connection, if any and send idle broadcast */
void cnetz_go_idle(cnetz_t *cnetz)
{
- cnetz_t *ogk;
transaction_t *trans;
if (cnetz->state == CNETZ_IDLE)
return;
if (cnetz->trans_list) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Releasing but still having transaction, please fix!\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Releasing but still having transaction, please fix!\n");
if (cnetz->trans_list->callref)
call_up_release(cnetz->trans_list->callref, CAUSE_NORMAL);
destroy_transaction(cnetz->trans_list);
}
- PDEBUG(DCNETZ, DEBUG_INFO, "Entering IDLE state on channel %s.\n", cnetz->sender.kanal);
+ LOGP(DCNETZ, LOGL_INFO, "Entering IDLE state on channel %s.\n", cnetz->sender.kanal);
cnetz_new_state(cnetz, CNETZ_IDLE);
+ cnetz->sched_lr_debugged = 0;
+ cnetz->sched_mlr_debugged = 0;
/* set scheduler to OgK or turn off SpK */
if (cnetz->dsp_mode == DSP_MODE_SPK_K || cnetz->dsp_mode == DSP_MODE_SPK_V) {
- /* go idle after next frame/slot */
- cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 1);
+ /* switch next frame after distributed signaling boundary (multiple of 8 slots) */
+ cnetz_set_sched_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 8) & 24);
} else {
- cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 0);
- cnetz_set_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF);
+ /* switch next frame */
+ cnetz_set_sched_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 1) & 31);
+ cnetz_set_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF);
}
/* check for first phone in queue and trigger completion of call (becoming idle means that SpK is now available) */
- ogk = search_ogk();
- trans = search_transaction(ogk, TRANS_MT_QUEUE | TRANS_MO_QUEUE);
+ trans = search_transaction_queue();
if (trans) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Now channel available for queued subscriber '%s'.\n", transaction2rufnummer(trans));
+ LOGP(DCNETZ, LOGL_NOTICE, "Now channel is available for queued subscriber '%s'.\n", transaction2rufnummer(trans));
trans_new_state(trans, (trans->state == TRANS_MT_QUEUE) ? TRANS_MT_DELAY : TRANS_MO_DELAY);
- timer_stop(&trans->timer);
- timer_start(&trans->timer, 2.0);
+ osmo_timer_del(&trans->timer);
+ osmo_timer_schedule(&trans->timer, 3,0); /* Wait at least one frame cycles (2.4s) until timeout */
}
}
@@ -533,120 +575,68 @@ static void cnetz_release(transaction_t *trans, uint8_t cause)
trans_new_state(trans, (trans->cnetz->dsp_mode == DSP_MODE_OGK) ? TRANS_VA : TRANS_AF);
trans->repeat = 0;
trans->release_cause = cause;
- trans->cnetz->sched_switch_mode = 0;
- timer_stop(&trans->timer);
-}
-
-/* Receive audio from call instance. */
-void call_down_audio(int callref, sample_t *samples, int count)
-{
- sender_t *sender;
- cnetz_t *cnetz;
-
- for (sender = sender_head; sender; sender = sender->next) {
- cnetz = (cnetz_t *) sender;
- if (cnetz->trans_list && cnetz->trans_list->callref == callref)
- break;
- }
- if (!sender)
- return;
-
- if (cnetz->dsp_mode == DSP_MODE_SPK_V) {
- /* store as is, since we convert rate when processing FSK frames */
- jitter_save(&cnetz->sender.dejitter, samples, count);
- }
+ trans->cnetz->sched_dsp_mode_ts = -1;
+ osmo_timer_del(&trans->timer);
}
-void call_down_clock(void) {}
-
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
- sender_t *sender;
- cnetz_t *cnetz, *spk;
+ cnetz_t *ogk, *spk;
int rc;
int extended;
transaction_t *trans;
uint8_t futln_nat;
uint8_t futln_fuvst;
int futln_rest; /* use int for checking size > 65535 */
- int len;
- int i;
-
- /* 1. check if number is invalid, return INVALNUMBER */
- len = strlen(dialing);
- if (len >= 11 && !strncmp(dialing, "0161", 4)) {
- dialing += 4;
- len -= 4;
- }
- if (len < 7 || len > 8) {
-inval:
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
- return -CAUSE_INVALNUMBER;
- }
- for (i = 0; i < len; i++) {
- if (dialing[i] < '0' || dialing[i] > '9')
- goto inval;
- }
+ int ogk_kanal;
+ /* 1. split number into elements */
futln_nat = dialing[0] - '0';
- if (len == 7)
- futln_fuvst = dialing[1] - '0';
- else {
+ if (dialing[7]) {
futln_fuvst = (dialing[1] - '0') * 10 + (dialing[2] - '0');
- if (futln_fuvst > 31) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Digit 2 and 3 '%02d' must not exceed '31', but they do!\n", futln_fuvst);
- goto inval;
- }
- }
- futln_rest = atoi(dialing + len - 5);
- if (futln_rest > 65535) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Last 5 digits '%05d' must not exceed '65535', but they do!\n", futln_rest);
- goto inval;
+ futln_rest = atoi(dialing + 3);
+ } else {
+ futln_fuvst = dialing[1] - '0';
+ futln_rest = atoi(dialing + 2);
}
/* 2. check if the subscriber is attached */
- rc = find_db(futln_nat, futln_fuvst, futln_rest, NULL, &extended);
+ rc = find_db(futln_nat, futln_fuvst, futln_rest, &ogk_kanal, NULL, &extended);
if (rc < 0) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to not attached subscriber, rejecting!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing call to not attached subscriber, rejecting!\n");
return -CAUSE_OUTOFORDER;
}
/* 3. check if given number is already in a call, return BUSY */
- for (sender = sender_head; sender; sender = sender->next) {
- cnetz = (cnetz_t *) sender;
- /* search transaction for this number */
- trans = search_transaction_number(cnetz, futln_nat, futln_fuvst, futln_rest);
- if (trans)
- break;
- }
- if (sender) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to busy number, rejecting!\n");
+ trans = search_transaction_number_global(futln_nat, futln_fuvst, futln_rest);
+ if (trans) {
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing call to busy number, rejecting!\n");
return -CAUSE_BUSY;
}
/* 4. check if we have no OgK, return NOCHANNEL */
- cnetz = search_ogk();
- if (!cnetz) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but OgK is currently busy, rejecting!\n");
+ ogk = search_ogk(ogk_kanal);
+ if (!ogk) {
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing call, but OgK is currently busy, rejecting!\n");
return -CAUSE_NOCHANNEL;
}
/* 5. check if all senders are busy, return NOCHANNEL */
spk = search_free_spk(extended);
if (!spk) {
- if (!cnetz->warteschlange) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but no free channel, rejecting!\n");
+ if (!ogk->warteschlange) {
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing call, but no free channel, rejecting!\n");
return -CAUSE_NOCHANNEL;
} else
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but no free channel, queuing call!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing call, but no free channel, queuing call!\n");
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
+ LOGP(DCNETZ, LOGL_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
/* 6. trying to page mobile station */
- trans = create_transaction(cnetz, (spk) ? TRANS_VAK : TRANS_WSK, dialing[0] - '0', dialing[1] - '0', atoi(dialing + 2), -1, -1);
+ trans = create_transaction(ogk, (spk) ? TRANS_VAK : TRANS_WSK, futln_nat, futln_fuvst, futln_rest, -1, -1, NAN);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
return -CAUSE_TEMPFAIL;
}
trans->callref = callref;
@@ -655,8 +645,35 @@ inval:
return 0;
}
-void call_down_answer(int __attribute__((unused)) callref)
+void call_down_answer(int callref, struct timeval *tv_meter)
{
+ sender_t *sender;
+ cnetz_t *cnetz;
+ transaction_t *trans;
+
+ LOGP(DCNETZ, LOGL_INFO, "Call has been answered by network.\n");
+
+ for (sender = sender_head; sender; sender = sender->next) {
+ cnetz = (cnetz_t *) sender;
+ trans = search_transaction_callref(cnetz, callref);
+ if (trans)
+ break;
+ }
+ if (!sender) {
+ LOGP(DCNETZ, LOGL_NOTICE, "Incoming answer, but no callref!\n");
+ return;
+ }
+
+ /* At least tone second! */
+ if (tv_meter->tv_sec) {
+ LOGP(DCNETZ, LOGL_INFO, "Network starts metering pulses every %lu.%03lu seconds.\n", tv_meter->tv_sec, tv_meter->tv_usec / 1000);
+ trans->meter_start = get_time();
+ trans->metering_time = (double)tv_meter->tv_sec + (double)tv_meter->tv_usec / 1000000.0;
+ } else if (cnetz->metering) {
+ LOGP(DCNETZ, LOGL_INFO, "Command line options starts metering pulses every %d seconds.\n", cnetz->metering);
+ trans->meter_start = get_time();
+ trans->metering_time = (double)cnetz->metering;
+ }
}
/* Call control sends disconnect (with tones).
@@ -669,7 +686,7 @@ void call_down_disconnect(int callref, int cause)
cnetz_t *cnetz;
transaction_t *trans;
- PDEBUG(DCNETZ, DEBUG_INFO, "Call has been disconnected by network.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call has been disconnected by network.\n");
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *) sender;
@@ -679,7 +696,7 @@ void call_down_disconnect(int callref, int cause)
break;
}
if (!sender) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing disconnect, but no callref!\n");
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@@ -688,15 +705,17 @@ void call_down_disconnect(int callref, int cause)
switch (cnetz->dsp_mode) {
case DSP_MODE_SPK_V:
+ /* stop metering */
+ trans->meter_end = get_time();
return;
case DSP_MODE_SPK_K:
- PDEBUG(DCNETZ, DEBUG_INFO, "Call control disconnects on speech channel, releasing towards mobile station.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call control disconnects on speech channel, releasing towards mobile station.\n");
cnetz_release(trans, cnetz_cause_isdn2cnetz(cause));
call_up_release(callref, cause);
trans->callref = 0;
break;
default:
- PDEBUG(DCNETZ, DEBUG_INFO, "Call control disconnects on organisation channel, removing transaction.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call control disconnects on organisation channel, removing transaction.\n");
call_up_release(callref, cause);
trans->callref = 0;
if (trans->state == TRANS_MT_QUEUE || trans->state == TRANS_MT_DELAY) {
@@ -716,7 +735,7 @@ void call_down_release(int callref, int cause)
cnetz_t *cnetz;
transaction_t *trans;
- PDEBUG(DCNETZ, DEBUG_INFO, "Call has been released by network, releasing call.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call has been released by network, releasing call.\n");
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *) sender;
@@ -726,7 +745,7 @@ void call_down_release(int callref, int cause)
break;
}
if (!sender) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing release, but no callref!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "Outgoing release, but no callref!\n");
/* don't send release, because caller already released */
return;
}
@@ -736,11 +755,11 @@ void call_down_release(int callref, int cause)
switch (cnetz->dsp_mode) {
case DSP_MODE_SPK_K:
case DSP_MODE_SPK_V:
- PDEBUG(DCNETZ, DEBUG_INFO, "Call control releases on speech channel, releasing towards mobile station.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call control releases on speech channel, releasing towards mobile station.\n");
cnetz_release(trans, cnetz_cause_isdn2cnetz(cause));
break;
default:
- PDEBUG(DCNETZ, DEBUG_INFO, "Call control releases on organisation channel, removing transaction.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Call control releases on organisation channel, removing transaction.\n");
if (trans->state == TRANS_MT_QUEUE) {
cnetz_release(trans, cnetz_cause_isdn2cnetz(cause));
} else {
@@ -750,19 +769,19 @@ void call_down_release(int callref, int cause)
}
}
-int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest)
+int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal)
{
cnetz_t *cnetz;
transaction_t *trans;
- cnetz = search_ogk();
+ cnetz = search_ogk(ogk_kanal);
if (!cnetz) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "'Meldeaufruf', but OgK is currently busy!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "'Meldeaufruf', but OgK is currently busy!\n");
return -CAUSE_NOCHANNEL;
}
- trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1, -1);
+ trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1, -1, NAN);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
return -CAUSE_TEMPFAIL;
}
@@ -827,29 +846,20 @@ const char *chan_type_long_name(enum cnetz_chan_type chan_type)
}
/* Timeout handling */
-void transaction_timeout(struct timer *timer)
+void transaction_timeout(void *data)
{
- transaction_t *trans = (transaction_t *)timer->priv;
+ transaction_t *trans = data;
cnetz_t *cnetz = trans->cnetz;
switch (trans->state) {
- case TRANS_WAF:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
- if (trans->try == N) {
- trans_new_state(trans, TRANS_WBN);
- break;
- }
- trans->try++;
- trans_new_state(trans, TRANS_VWG);
- break;
case TRANS_MT_QUEUE:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Phone in queue, but still no channel available, releasing call!\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Phone in queue, but still no channel available, releasing call!\n");
call_up_release(trans->callref, CAUSE_NOCHANNEL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_GASSENBESETZT);
break;
case TRANS_MO_QUEUE:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Phone in queue, but still no channel available, releasing!\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Phone in queue, but still no channel available, releasing!\n");
cnetz_release(trans, CNETZ_CAUSE_GASSENBESETZT);
break;
case TRANS_MT_DELAY:
@@ -859,12 +869,12 @@ void transaction_timeout(struct timer *timer)
trans_new_state(trans, TRANS_VAG);
break;
case TRANS_BQ:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after channel allocation 'Belegung Quittung'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after channel allocation 'Belegung Quittung'\n");
trans_new_state(trans, TRANS_AF);
trans->repeat = 0;
break;
case TRANS_ZFZ:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after sending random number 'Zufallszahl'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after sending random number 'Zufallszahl'\n");
if (trans->callref) {
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
@@ -872,7 +882,7 @@ void transaction_timeout(struct timer *timer)
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_AP:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after waiting for challenge response 'Autorisierungsparameter'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after waiting for challenge response 'Autorisierungsparameter'\n");
if (trans->callref) {
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
@@ -882,9 +892,9 @@ void transaction_timeout(struct timer *timer)
case TRANS_VHQ_K:
case TRANS_VHQ_V:
if (cnetz->dsp_mode != DSP_MODE_SPK_V)
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response while holding call 'Quittung Verbindung halten'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response while holding call 'Quittung Verbindung halten'\n");
else
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Lost signal from 'FuTln' (mobile station)\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Lost signal from 'FuTln' (mobile station)\n");
if (trans->callref) {
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
@@ -892,31 +902,25 @@ void transaction_timeout(struct timer *timer)
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_DS:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after connect 'Durchschalten'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after connect 'Durchschalten'\n");
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_RTA:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after ringing order 'Rufton anschalten'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after ringing order 'Rufton anschalten'\n");
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_AHQ:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after answer 'Abhebequittung'\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after answer 'Abhebequittung'\n");
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
- case TRANS_MFT:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
- /* no response to availability check */
- trans->page_failed = 1;
- destroy_transaction(trans);
- break;
default:
- PDEBUG_CHAN(DCNETZ, DEBUG_ERROR, "Timeout unhandled in state %" PRIu64 "\n", trans->state);
+ LOGP_CHAN(DCNETZ, LOGL_ERROR, "Timeout unhandled in state %" PRIu64 "\n", trans->state);
}
}
@@ -948,13 +952,13 @@ void cnetz_sync_frame(cnetz_t *cnetz, double sync, int block)
}
/* if more than +- one bit out of sync */
if (offset < -0.5 || offset > 0.5) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Frame sync offset = %.2f, correcting!\n", offset);
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Frame sync offset = %.2f, correcting!\n", offset);
fsk_correct_sync(&cnetz->fsk_demod, offset);
return;
}
/* resync by some fraction of received sync error */
- PDEBUG_CHAN(DCNETZ, DEBUG_DEBUG, "Frame sync offset = %.2f, correcting.\n", offset);
+ LOGP_CHAN(DCNETZ, LOGL_DEBUG, "Frame sync offset = %.2f, correcting.\n", offset);
fsk_correct_sync(&cnetz->fsk_demod, offset / 2.0);
}
@@ -984,6 +988,7 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.fuz_fuvst_nr = si.fuz_fuvst;
telegramm.fuz_rest_nr = si.fuz_rest;
telegramm.kennung_fufst = si.kennung_fufst;
+ telegramm.bahn_bs = si.bahn_bs;
telegramm.nachbarschafts_prioritaets_bit = si.nachbar_prio;
telegramm.bewertung_nach_pegel_und_entfernung = si.bewertung;
telegramm.entfernungsangabe_der_fufst = si.entfernung;
@@ -992,7 +997,7 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.grenzwert_fuer_umschalten = si.grenz_umschalten;
telegramm.grenze_fuer_ausloesen = si.grenz_ausloesen;
- trans = search_transaction(cnetz, TRANS_EM | TRANS_UM | TRANS_WBN | TRANS_WBP | TRANS_VAG | TRANS_VAK | TRANS_ATQ | TRANS_VA | TRANS_WSK);
+ trans = search_transaction(cnetz, TRANS_EM | TRANS_UM | TRANS_WBN | TRANS_WBP | TRANS_VAG | TRANS_VAK | TRANS_ATQ | TRANS_ATQ_IDLE | TRANS_VA | TRANS_WSK);
if (trans) {
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
@@ -1000,18 +1005,18 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.ausloesegrund = trans->release_cause;
switch (trans->state) {
case TRANS_EM:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Einbuchquittung' to Attachment request.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending acknowledgment 'Einbuchquittung' to Attachment request.\n");
telegramm.opcode = OPCODE_EBQ_R;
destroy_transaction(trans);
break;
case TRANS_UM:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Umbuchquittung' to Roaming requuest.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending acknowledgment 'Umbuchquittung' to Roaming requuest.\n");
telegramm.opcode = OPCODE_UBQ_R;
destroy_transaction(trans);
break;
case TRANS_WBN:
wbn:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending call reject 'Wahlbestaetigung negativ'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending call reject 'Wahlbestaetigung negativ'.\n");
telegramm.opcode = OPCODE_WBN_R;
destroy_transaction(trans);
cnetz_go_idle(cnetz);
@@ -1020,17 +1025,17 @@ wbn:
spk = search_free_spk(trans->extended);
/* Accept call if channel available, otherwise reject or queue call */
if (spk) {
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending call accept 'Wahlbestaetigung positiv'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending call accept 'Wahlbestaetigung positiv'.\n");
telegramm.opcode = OPCODE_WBP_R;
trans_new_state(trans, TRANS_VAG);
} else if (cnetz->warteschlange) {
/* queue call if no channel is available, but queue allowed */
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "No free channel, sending call accept in queue 'Wahlbestaetigung positiv in Warteschlage'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "No free channel, sending call accept in queue 'Wahlbestaetigung positiv in Warteschlage'.\n");
telegramm.opcode = OPCODE_WWBP_R;
trans_new_state(trans, TRANS_MO_QUEUE);
- timer_start(&trans->timer, T_VAG2); /* Maximum time to hold queue */
+ osmo_timer_schedule(&trans->timer, T_VAG2); /* Maximum time to hold queue */
} else {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "No free channel anymore, rejecting call!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "No free channel anymore, rejecting call!\n");
trans_new_state(trans, TRANS_WBN);
goto wbn;
}
@@ -1039,36 +1044,36 @@ wbn:
case TRANS_VAK:
vak:
if (trans->state == TRANS_VAG) {
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending channel assignment 'Verbindungsaufbau gehend'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending channel assignment 'Verbindungsaufbau gehend'.\n");
telegramm.opcode = OPCODE_VAG_R;
} else {
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending channel assignment 'Verbindungsaufbau kommend'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending channel assignment 'Verbindungsaufbau kommend'.\n");
telegramm.opcode = OPCODE_VAK_R;
}
trans_new_state(trans, TRANS_BQ);
trans->repeat = 0;
- timer_start(&trans->timer, 0.150 + 0.0375 * F_BQ); /* two slots + F_BQ frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.150 + 0.0375 * F_BQ)); /* two slots + F_BQ frames */
/* select channel */
spk = search_free_spk(trans->extended);
if (!spk) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "No free channel anymore, rejecting call!\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "No free channel anymore, rejecting call!\n");
destroy_transaction(trans);
cnetz_go_idle(cnetz);
break;
}
if (spk == cnetz) {
- PDEBUG(DCNETZ, DEBUG_INFO, "Staying on combined calling + traffic channel %s\n", spk->sender.kanal);
+ LOGP(DCNETZ, LOGL_INFO, "Staying on combined control + traffic channel %s\n", spk->sender.kanal);
} else {
- PDEBUG(DCNETZ, DEBUG_INFO, "Assigning phone to traffic channel %s\n", spk->sender.kanal);
+ LOGP(DCNETZ, LOGL_INFO, "Assigning phone to traffic channel %s\n", spk->sender.kanal);
/* sync RX time to current OgK time */
fsk_copy_sync(&spk->fsk_demod, &cnetz->fsk_demod);
}
/* set channel */
- telegramm.frequenz_nr = atoi(spk->sender.kanal);
+ telegramm.frequenz_nr = spk->kanal;
/* change state to busy */
cnetz_new_state(spk, CNETZ_BUSY);
/* schedule switching two slots ahead */
- cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, 2);
+ cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31);
/* relink */
unlink_transaction(trans);
link_transaction(trans, spk);
@@ -1076,12 +1081,13 @@ vak:
cnetz_flush_other_transactions(spk, trans);
break;
case TRANS_ATQ:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Quittung fuer Ausloesen des FuTelG im OgK-Betrieb' to release request.\n");
+ case TRANS_ATQ_IDLE:
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending acknowledgment 'Quittung fuer Ausloesen des FuTelG im OgK-Betrieb' to release request.\n");
telegramm.opcode = OPCODE_ATQ_R;
destroy_transaction(trans);
break;
case TRANS_VA:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Vorzeitiges Ausloesen' to queued mobile station\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Vorzeitiges Ausloesen' to queued mobile station\n");
telegramm.opcode = OPCODE_VA_R;
destroy_transaction(trans);
break;
@@ -1092,10 +1098,10 @@ vak:
trans_new_state(trans, TRANS_VAK);
goto vak;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "No free channel, sending incoming call in queue 'Warteschglange kommend'.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "No free channel, sending incoming call in queue 'Warteschglange kommend'.\n");
telegramm.opcode = OPCODE_WSK_R;
trans_new_state(trans, TRANS_MT_QUEUE);
- timer_start(&trans->timer, T_VAK); /* Maximum time to hold queue */
+ osmo_timer_schedule(&trans->timer, T_VAK); /* Maximum time to hold queue */
call_up_alerting(trans->callref);
default:
; /* LR */
@@ -1114,33 +1120,54 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
memset(&telegramm, 0, sizeof(telegramm));
telegramm.opcode = OPCODE_MLR_M;
telegramm.max_sendeleistung = cnetz_power2bits(cnetz->ms_power);
- telegramm.ogk_verkehrsanteil = 0; /* must be 0 or phone might not respond to messages in different slot */
+ telegramm.ogk_verkehrsanteil = 0; /* must be 0 or some phone might not respond to messages in different slots */
telegramm.teilnehmergruppensperre = si.teilnehmergruppensperre;
telegramm.anzahl_gesperrter_teilnehmergruppen = si.anzahl_gesperrter_teilnehmergruppen;
- telegramm.ogk_vorschlag = CNETZ_OGK_KANAL;
+ if (ogk_list_count) {
+ /* if we have alternative OGKs, we cycle through the list and indicate their channels */
+ telegramm.ogk_vorschlag = ogk_list[ogk_list_index]->kanal;
+ if (++ogk_list_index == ogk_list_count)
+ ogk_list_index = 0;
+ } else
+ telegramm.ogk_vorschlag = CNETZ_STD_OGK_KANAL;
telegramm.fuz_rest_nr = si.fuz_rest;
- trans = search_transaction(cnetz, TRANS_VWG | TRANS_MA);
+next_candidate:
+ trans = search_transaction(cnetz, TRANS_VWG | TRANS_WAF | TRANS_MA | TRANS_MFT);
if (trans) {
switch (trans->state) {
+ case TRANS_WAF:
+ /* no response to dial request (try again or drop connection) */
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
+ if (trans->try == N) {
+ trans_new_state(trans, TRANS_WBN);
+ goto next_candidate;
+ }
+ trans->try++;
+ trans_new_state(trans, TRANS_VWG);
+ /* FALLTHRU */
case TRANS_VWG:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Wahlaufforderung' to outging call\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending acknowledgment 'Wahlaufforderung' to outging call\n");
telegramm.opcode = OPCODE_WAF_M;
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_WAF);
- timer_start(&trans->timer, 1.0); /* Wait two slot cycles until resending */
break;
case TRANS_MA:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending keepalive request 'Meldeaufruf'\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending keepalive request 'Meldeaufruf'\n");
telegramm.opcode = OPCODE_MA_M;
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_MFT);
- timer_start(&trans->timer, 1.0); /* Wait two slot cycles until timeout */
break;
+ case TRANS_MFT:
+ /* no response to availability check */
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
+ trans->page_failed = 1;
+ destroy_transaction(trans);
+ goto next_candidate;
default:
; /* MLR */
}
@@ -1162,20 +1189,22 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
rufnummer = telegramm2rufnummer(telegramm);
if (si.authentifikationsbit && telegramm->chipkarten_futelg_bit)
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
else
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
if (telegramm->erweitertes_frequenzbandbit)
- PDEBUG(DCNETZ, DEBUG_INFO, " -> Phone support extended frequency band\n");
+ LOGP(DCNETZ, LOGL_INFO, " -> Phone supports extended frequency band\n");
if (cnetz->state != CNETZ_IDLE) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Attachment from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
+ LOGP(DCNETZ, LOGL_NOTICE, "Ignoring Attachment from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
- trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
+ console_inscription(rufnummer);
+ trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
break;
}
+ cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
valid_frame = 1;
break;
case OPCODE_UM_R:
@@ -1183,20 +1212,22 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
rufnummer = telegramm2rufnummer(telegramm);
if (si.authentifikationsbit && telegramm->chipkarten_futelg_bit)
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
else
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
if (telegramm->erweitertes_frequenzbandbit)
- PDEBUG(DCNETZ, DEBUG_INFO, " -> Phone support extended frequency band\n");
+ LOGP(DCNETZ, LOGL_INFO, " -> Phone supports extended frequency band\n");
if (cnetz->state != CNETZ_IDLE) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Roaming from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
+ LOGP(DCNETZ, LOGL_NOTICE, "Ignoring Roaming from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
- trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
+ console_inscription(rufnummer);
+ trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
break;
}
+ cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
valid_frame = 1;
break;
case OPCODE_UWG_R:
@@ -1204,39 +1235,43 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming request 'Umbuchantrag' message from Subscriber '%s' on queue\n", rufnummer);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received Roaming request 'Umbuchantrag' message from Subscriber '%s' on queue\n", rufnummer);
break;
case OPCODE_VWG_R:
case OPCODE_SRG_R:
+ case OPCODE_NUG_R:
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
if (opcode == OPCODE_VWG_R)
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing Call 'Verbindungswunsch gehend' message from Subscriber '%s'\n", rufnummer);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received outgoing Call 'Verbindungswunsch gehend' message from Subscriber '%s'\n", rufnummer);
+ else if (opcode == OPCODE_SRG_R)
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received outgoing emergency Call 'Sonderruf gehend' message from Subscriber '%s'\n", rufnummer);
else
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing emergency Call 'Sonderruf gehend' message from Subscriber '%s'\n", rufnummer);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received outgoing Call 'Verbindungswunsch gehend bei Nachbarschaftsunterstuetzung' message from Subscriber '%s'\n", rufnummer);
if (cnetz->state != CNETZ_IDLE) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Call from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
+ LOGP(DCNETZ, LOGL_NOTICE, "Ignoring Call from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
- trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, telegramm->erweitertes_frequenzbandbit);
+ trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
break;
}
+ cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
trans->try = 1;
valid_frame = 1;
break;
case OPCODE_WUE_M:
trans = search_transaction(cnetz, TRANS_WAF | TRANS_WBP | TRANS_VAG | TRANS_MO_QUEUE);
if (!trans) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received dialing digits 'Wahluebertragung' message without transaction, ignoring!\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received dialing digits 'Wahluebertragung' message without transaction (on this OgK), ignoring!\n");
break;
}
rufnummer = transaction2rufnummer(trans);
strncpy(trans->dialing, telegramm->wahlziffern, sizeof(trans->dialing) - 1);
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received dialing digits 'Wahluebertragung' message from Subscriber '%s' to Number '%s'\n", rufnummer, trans->dialing);
- timer_stop(&trans->timer);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received dialing digits 'Wahluebertragung' message from Subscriber '%s' to Number '%s'\n", rufnummer, trans->dialing);
+ osmo_timer_del(&trans->timer);
trans_new_state(trans, TRANS_WBP);
trans->try = 1; /* try */
valid_frame = 1;
@@ -1245,18 +1280,31 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received release 'Ausloesen des FuTelG im OgK-Betrieb bei WS' message from Subscriber '%s'\n", rufnummer);
- trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received release 'Ausloesen des FuTelG im OgK-Betrieb bei WS' message from Subscriber '%s'\n", rufnummer);
+ trans = search_transaction_number_global(telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
if (!trans) {
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "There is no transaction, so we assume that the phone did not receive previous release.\n");
/* create transaction, in case the phone repeats the release after we have acked it */
- trans = create_transaction(cnetz, TRANS_ATQ, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1);
+ trans = create_transaction(cnetz, TRANS_ATQ_IDLE, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1, cnetz->rf_level_db);
if (!trans) {
- PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
break;
}
+ cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
} else {
- timer_stop(&trans->timer);
- trans_new_state(trans, TRANS_ATQ);
+ if (cnetz == trans->cnetz) {
+ osmo_timer_del(&trans->timer);
+ trans_new_state(trans, TRANS_ATQ);
+ } else
+ if (trans->state == TRANS_ATQ_IDLE) {
+ trans = create_transaction(cnetz, TRANS_ATQ_IDLE, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1, cnetz->rf_level_db);
+ if (!trans) {
+ LOGP(DCNETZ, LOGL_ERROR, "Failed to create transaction\n");
+ break;
+ }
+ cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
+ } else
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received release 'Ausloesen des FuTelG im OgK-Betrieb bei WS' message without transaction (on this OgK), ignoring!\n");
}
valid_frame = 1;
break;
@@ -1265,16 +1313,16 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
if (!trans) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received acknowledge 'Meldung Funktelefonteilnehmer' message without transaction, ignoring!\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received acknowledge 'Meldung Funktelefonteilnehmer' message without transaction (on this OgK), ignoring!\n");
break;
}
rufnummer = transaction2rufnummer(trans);
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received acknowledge 'Meldung Funktelefonteilnehmer' message from Subscriber '%s'\n", rufnummer);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received acknowledge 'Meldung Funktelefonteilnehmer' message from Subscriber '%s'\n", rufnummer);
destroy_transaction(trans);
valid_frame = 1;
break;
default:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
}
if (cnetz->sender.loopback) {
@@ -1295,11 +1343,14 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
{
static telegramm_t telegramm;
transaction_t *trans = cnetz->trans_list;
+ int ogk_kanal;
cnetz_t *ogk;
+ int rc;
- memset(&telegramm, 0, sizeof(telegramm));
if (!trans)
- return &telegramm;
+ return NULL;
+
+ memset(&telegramm, 0, sizeof(telegramm));
telegramm.max_sendeleistung = cnetz_power2bits(cnetz->ms_power);
telegramm.sendeleistungsanpassung = (cnetz->ms_power < 8) ? 1 : 0;
@@ -1310,104 +1361,96 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
- telegramm.frequenz_nr = atoi(cnetz->sender.kanal);
+ telegramm.frequenz_nr = cnetz->kanal;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.zufallszahl = cnetz->challenge;
+ telegramm.bahn_bs = si.bahn_bs;
switch (trans->state) {
case TRANS_BQ:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Belegungsquittung' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Belegungsquittung' on traffic channel\n");
telegramm.opcode = OPCODE_BQ_K;
- if (++trans->repeat >= 8 && !timer_running(&trans->timer)) {
+ if (++trans->repeat >= 8 && !osmo_timer_pending(&trans->timer)) {
if (cnetz->challenge_valid) {
if (si.authentifikationsbit == 0) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Cannot authenticate, because base station does not support it. (Authentication disabled in sysinfo.)\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Cannot authenticate, because base station does not support it. (Authentication disabled in sysinfo.)\n");
goto no_auth;
}
if (trans->futelg_bit == 0) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Cannot authenticate, because mobile station does not support it. (Mobile station has magnetic card.)\n");
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Cannot authenticate, because mobile station does not support it. (Mobile station has magnetic card.)\n");
goto no_auth;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Perform authentication with subscriber's card, use challenge: 0x%016" PRIx64 "\n", telegramm.zufallszahl);
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Perform authentication with subscriber's card, use challenge: 0x%016" PRIx64 "\n", telegramm.zufallszahl);
trans_new_state(trans, TRANS_ZFZ);
- timer_start(&trans->timer, 0.0375 * F_ZFZ); /* F_ZFZ frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_ZFZ)); /* F_ZFZ frames */
} else {
no_auth:
trans_new_state(trans, TRANS_VHQ_K);
- timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_VHQK)); /* F_VHQK frames */
}
trans->repeat = 0;
}
break;
case TRANS_ZFZ:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Zufallszahl' on traffic channel (0x%016" PRIx64 ").\n", telegramm.zufallszahl);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Zufallszahl' on traffic channel (0x%016" PRIx64 ").\n", telegramm.zufallszahl);
telegramm.opcode = OPCODE_ZFZ_K;
break;
case TRANS_AP:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
telegramm.opcode = OPCODE_VHQ_K;
break;
case TRANS_VHQ_K:
if (!cnetz->sender.loopback)
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
telegramm.opcode = OPCODE_VHQ_K;
/* continue until next sub frame, so we send DS from first block of next sub frame. */
- if (!cnetz->sender.loopback && (cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
+ if (!cnetz->sender.loopback && (cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !osmo_timer_pending(&trans->timer)) {
/* next sub frame */
if (trans->mo_call) {
- int rc;
- trans->callref = ++new_callref;
- rc = call_up_setup(trans->callref, transaction2rufnummer(trans), trans->dialing);
- if (rc < 0) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", -rc);
- trans->callref = 0;
- cnetz_release(trans, cnetz_cause_isdn2cnetz(-rc));
- goto call_failed;
- }
+ trans->callref = call_up_setup(transaction2rufnummer(trans), trans->dialing, OSMO_CC_NETWORK_CNETZ_NONE, "");
trans_new_state(trans, TRANS_DS);
trans->repeat = 0;
- timer_start(&trans->timer, 0.0375 * F_DS); /* F_DS frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_DS)); /* F_DS frames */
}
if (trans->mt_call) {
trans_new_state(trans, TRANS_RTA);
- timer_start(&trans->timer, 0.0375 * F_RTA); /* F_RTA frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_RTA)); /* F_RTA frames */
trans->repeat = 0;
call_up_alerting(trans->callref);
}
}
break;
case TRANS_DS:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Durchschalten' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Durchschalten' on traffic channel\n");
telegramm.opcode = OPCODE_DSB_K;
/* send exactly a sub frame (8 time slots) */
- if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
+ if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !osmo_timer_pending(&trans->timer)) {
/* next sub frame */
trans_new_state(trans, TRANS_VHQ_V);
trans->repeat = 0;
- cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
+ cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31);
#ifndef DEBUG_SPK
- timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.075 + 0.6 * F_VHQ)); /* one slot + F_VHQ frames */
#endif
}
break;
case TRANS_RTA:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Rufton anschalten' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Rufton anschalten' on traffic channel\n");
telegramm.opcode = OPCODE_RTA_K;
break;
case TRANS_AHQ:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Abhebe Quittung' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Abhebe Quittung' on traffic channel\n");
telegramm.opcode = OPCODE_AHQ_K;
if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m) {
/* next sub frame */
trans_new_state(trans, TRANS_VHQ_V);
trans->repeat = 0;
- cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
- timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
+ cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31);
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.075 + 0.6 * F_VHQ)); /* one slot + F_VHQ frames */
}
break;
case TRANS_AF:
-call_failed:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Ausloesen durch FuFSt' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Ausloesen durch FuFSt' on traffic channel\n");
telegramm.opcode = OPCODE_AF_K;
if (++trans->repeat < N_AFKT)
break;
@@ -1418,7 +1461,7 @@ call_failed:
break;
}
if (trans->try == N) {
- PDEBUG(DCNETZ, DEBUG_INFO, "Maximum retries, removing transaction\n");
+ LOGP(DCNETZ, LOGL_INFO, "Maximum retries, removing transaction\n");
/* no response to incomming call */
trans->page_failed = 1;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
@@ -1434,9 +1477,15 @@ call_failed:
/* idle channel */
cnetz_go_idle(cnetz);
/* alloc ogk again */
- ogk = search_ogk();
+ rc = find_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, &ogk_kanal, NULL, NULL);
+ if (rc < 0) {
+ LOGP(DCNETZ, LOGL_NOTICE, "Cannot find subscriber in database anymore, releasing!\n");
+ goto no_ogk;
+ }
+ ogk = search_ogk(ogk_kanal);
if (!ogk) {
- PDEBUG(DCNETZ, DEBUG_NOTICE, "Cannot retry, because currently no OgK available (busy)\n");
+ LOGP(DCNETZ, LOGL_NOTICE, "Cannot retry, because currently no OgK available (busy)\n");
+no_ogk:
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
if (trans->callref)
call_up_release(trans->callref, CAUSE_NOCHANNEL);
@@ -1444,7 +1493,7 @@ call_failed:
destroy_transaction(trans);
break;
}
- PDEBUG(DCNETZ, DEBUG_INFO, "Retry to assign channel.\n");
+ LOGP(DCNETZ, LOGL_INFO, "Retry to assign channel.\n");
/* attach call to OgK */
link_transaction(trans, ogk);
/* change state */
@@ -1455,7 +1504,7 @@ call_failed:
trans->try++;
break;
case TRANS_AT:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Auslosen durch FuFst' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Auslosen durch FuFst' on traffic channel\n");
telegramm.opcode = OPCODE_AF_K;
if (++trans->repeat == 1) {
destroy_transaction(trans);
@@ -1485,11 +1534,11 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received allocation 'Belegung' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received allocation 'Belegung' message.\n");
valid_frame = 1;
if (trans->state != TRANS_BQ)
break;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
trans->try = 0;
break;
case OPCODE_DSQ_K:
@@ -1499,35 +1548,35 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received assignment confirm 'Durchschaltung Quittung' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received assignment confirm 'Durchschaltung Quittung' message.\n");
valid_frame = 1;
if (trans->state != TRANS_DS)
break;
cnetz->scrambler = telegramm->betriebs_art;
cnetz->scrambler_switch = 0;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
break;
case OPCODE_ZFZQ_K:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received random number acknowledge 'Zufallszahlquittung' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received random number acknowledge 'Zufallszahlquittung' message.\n");
valid_frame = 1;
if (trans->state != TRANS_ZFZ)
break;
if (cnetz->challenge != telegramm->zufallszahl) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received random number acknowledge (0x%016" PRIx64 ") does not match the transmitted one (0x%016" PRIx64 "), ignoring!\n", telegramm->zufallszahl, cnetz->challenge);
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received random number acknowledge (0x%016" PRIx64 ") does not match the transmitted one (0x%016" PRIx64 "), ignoring!\n", telegramm->zufallszahl, cnetz->challenge);
break;
}
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
trans_new_state(trans, TRANS_AP);
- timer_start(&trans->timer, T_AP); /* 750 milliseconds */
+ osmo_timer_schedule(&trans->timer, T_AP); /* 750 milliseconds */
break;
case OPCODE_AP_K:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received challenge response 'Autorisierungsparameter' message (0x%016" PRIx64 ").\n", telegramm->authorisierungsparameter);
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received challenge response 'Autorisierungsparameter' message (0x%016" PRIx64 ").\n", telegramm->authorisierungsparameter);
valid_frame = 1;
if (trans->state != TRANS_AP)
break;
/* if authentication response from card does not match */
if (cnetz->response_valid && telegramm->authorisierungsparameter != cnetz->response) {
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received challenge response (0x%016" PRIx64 ") does not match the expected one (0x%016" PRIx64 "), releasing!\n", telegramm->authorisierungsparameter, cnetz->response);
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received challenge response (0x%016" PRIx64 ") does not match the expected one (0x%016" PRIx64 "), releasing!\n", telegramm->authorisierungsparameter, cnetz->response);
if (trans->callref) {
call_up_release(trans->callref, CAUSE_TEMPFAIL); /* jolly guesses that */
trans->callref = 0;
@@ -1535,10 +1584,10 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
cnetz_release(trans, CNETZ_CAUSE_GASSENBESETZT); /* when authentication is not valid */
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Completed authentication with subscriber's card, challenge response: 0x%016" PRIx64 "\n", telegramm->authorisierungsparameter);
- timer_stop(&trans->timer);
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Completed authentication with subscriber's card, challenge response: 0x%016" PRIx64 "\n", telegramm->authorisierungsparameter);
+ osmo_timer_del(&trans->timer);
trans_new_state(trans, TRANS_VHQ_K);
- timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_VHQK)); /* F_VHQK frames */
break;
case OPCODE_VH_K:
if (!match_fuz(telegramm)) {
@@ -1547,11 +1596,11 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received connection hold 'Verbindung halten' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received connection hold 'Verbindung halten' message.\n");
valid_frame = 1;
if (trans->state != TRANS_VHQ_K)
break;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
break;
case OPCODE_RTAQ_K:
if (!match_fuz(telegramm)) {
@@ -1561,10 +1610,10 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
break;
}
valid_frame = 1;
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received ringback 'Rufton anschalten Quittung' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received ringback 'Rufton anschalten Quittung' message.\n");
if (trans->state != TRANS_RTA)
break;
- timer_start(&trans->timer, 0.0375 * F_RTA); /* F_RTA frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.0375 * F_RTA)); /* F_RTA frames */
break;
case OPCODE_AH_K:
if (!match_fuz(telegramm)) {
@@ -1573,7 +1622,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received answer frame 'Abheben' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received answer frame 'Abheben' message.\n");
valid_frame = 1;
/* if already received this frame, or if we are already on VHQ or if we are releasing */
if (trans->state == TRANS_AHQ || trans->state == TRANS_VHQ_K || trans->state == TRANS_VHQ_V || trans->state == TRANS_AF)
@@ -1582,7 +1631,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
cnetz->scrambler_switch = 0;
trans_new_state(trans, TRANS_AHQ);
trans->repeat = 0;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
call_up_answer(trans->callref, transaction2rufnummer(trans));
break;
case OPCODE_AT_K:
@@ -1592,21 +1641,21 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received release frame 'Ausloesen durch FuTln' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received release frame 'Ausloesen durch FuTln' message.\n");
valid_frame = 1;
/* if already received this frame, if we are releasing */
if (trans->state == TRANS_AT || trans->state == TRANS_AF)
break;
trans_new_state(trans, TRANS_AT);
trans->repeat = 0;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
if (trans->callref) {
call_up_release(trans->callref, CAUSE_NORMAL);
trans->callref = 0;
}
break;
default:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
}
if (valid_frame)
@@ -1620,15 +1669,16 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
transaction_t *trans = cnetz->trans_list;
int meter = 0;
- memset(&telegramm, 0, sizeof(telegramm));
if (!trans)
- return &telegramm;
+ return NULL;
+
+ memset(&telegramm, 0, sizeof(telegramm));
- if (cnetz->metering) {
- double now = get_time();
- if (!trans->call_start)
- trans->call_start = now;
- meter = (now - trans->call_start) / (double)cnetz->metering + 1;
+ if (trans->metering_time) {
+ /* get end time. if not set, use current time. (still running) */
+ double end = (trans->meter_end) ? : get_time();
+ /* add one unit, because when metering is started, the first unit is counted. */
+ meter = (end - trans->meter_start) / (double)trans->metering_time + 1.0;
}
telegramm.max_sendeleistung = cnetz_power2bits(cnetz->ms_power);
@@ -1641,7 +1691,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
- telegramm.frequenz_nr = atoi(cnetz->sender.kanal);
+ telegramm.frequenz_nr = cnetz->kanal;
telegramm.entfernung = si.entfernung;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.gueltigkeit_des_gebuehrenstandes = 0;
@@ -1650,15 +1700,15 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
switch (trans->state) {
case TRANS_VHQ_V:
if ((cnetz->sched_ts & 8) == 0) { /* sub frame 1 and 3 */
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten 1' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Quittung Verbindung halten 1' on traffic channel\n");
telegramm.opcode = OPCODE_VHQ1_V;
} else { /* sub frame 2 and 4 */
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten 2' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Quittung Verbindung halten 2' on traffic channel\n");
telegramm.opcode = OPCODE_VHQ2_V;
}
break;
case TRANS_AF:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Ausloesen durch FuFSt' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending 'Ausloesen durch FuFSt' on traffic channel\n");
telegramm.opcode = OPCODE_AF_V;
if (++trans->repeat == N_AFV) {
destroy_transaction(trans);
@@ -1666,7 +1716,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
}
break;
case TRANS_AT:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledge to 'Ausloesen durch FuTln' on traffic channel\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Sending acknowledge to 'Ausloesen durch FuTln' on traffic channel\n");
telegramm.opcode = OPCODE_AF_V;
if (++trans->repeat == 1) {
destroy_transaction(trans);
@@ -1700,16 +1750,16 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
}
if (trans->state != TRANS_VHQ_V)
break;
- timer_start(&trans->timer, 0.6 * F_VHQ); /* F_VHQ frames */
+ osmo_timer_schedule(&trans->timer, FLOAT_TO_TIMEOUT(0.6 * F_VHQ)); /* F_VHQ frames */
switch (opcode) {
case OPCODE_VH_V:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received supervisory frame 'Verbindung halten' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received supervisory frame 'Verbindung halten' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
break;
case OPCODE_USAI_V:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received internal handover request frame 'Umschaltantrag intern' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received internal handover request frame 'Umschaltantrag intern' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
break;
case OPCODE_USAE_V:
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received external handover request frame 'Umschaltantrag extern' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received external handover request frame 'Umschaltantrag extern' message%s.\n", (telegramm->test_telefonteilnehmer_geraet) ? ", phone is a test-phone" : "");
break;
}
valid_frame = 1;
@@ -1730,21 +1780,21 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
break;
}
- PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received release frame 'Ausloesen durch FuTln' message.\n");
+ LOGP_CHAN(DCNETZ, LOGL_INFO, "Received release frame 'Ausloesen durch FuTln' message.\n");
valid_frame = 1;
/* if already received this frame, if we are releasing */
if (trans->state == TRANS_AT || trans->state == TRANS_AF)
break;
trans_new_state(trans, TRANS_AT);
trans->repeat = 0;
- timer_stop(&trans->timer);
+ osmo_timer_del(&trans->timer);
if (trans->callref) {
call_up_release(trans->callref, CAUSE_NORMAL);
trans->callref = 0;
}
break;
default:
- PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
+ LOGP_CHAN(DCNETZ, LOGL_NOTICE, "Received unexpected Telegramm (opcode %d = %s)\n", opcode, telegramm_name(opcode));
}
if (valid_frame)
diff --git a/src/cnetz/cnetz.h b/src/cnetz/cnetz.h
index 88e621f..b9bbafe 100644
--- a/src/cnetz/cnetz.h
+++ b/src/cnetz/cnetz.h
@@ -1,16 +1,16 @@
#include "../libcompandor/compandor.h"
-#include "../libtimer/timer.h"
+#include <osmocom/core/timer.h>
#include "../libmobile/sender.h"
#include "../libscrambler/scrambler.h"
typedef struct cnetz cnetz_t;
#include "fsk_demod.h"
#include "transaction.h"
-#define CNETZ_OGK_KANAL 131
+#define CNETZ_STD_OGK_KANAL 131
/* dsp modes of transmission */
enum dsp_mode {
- DSP_SCHED_NONE = 0, /* use for sheduling: nothing to shedule */
+ DSP_SCHED_NONE = 0, /* use for scheduling: nothing to schedule */
DSP_MODE_OFF, /* send nothing on unused SpK */
DSP_MODE_OGK, /* send "Telegramm" on OgK */
DSP_MODE_SPK_K, /* send concentrated "Telegramm" SpK */
@@ -40,9 +40,9 @@ enum cnetz_state {
#define N_AFKT 6 /* number of release frames to send during concentrated signaling */
#define N_AFV 4 /* number of release frames to send during distributed signaling */
#define N 3 /* now many times we repeat a message on OgK */
-#define T_VAG2 180 /* time on outgoing queue */
-#define T_VAK 60 /* time on incoming queue */
-#define T_AP 750 /* Time to wait for SIM card's authentication reply */
+#define T_VAG2 180,0 /* time on outgoing queue */
+#define T_VAK 60,0 /* time on incoming queue */
+#define T_AP 0,750000 /* Time to wait for SIM card's authentication reply */
/* clear causes */
#define CNETZ_CAUSE_GASSENBESETZT 0 /* network congested */
@@ -66,6 +66,7 @@ struct clock_speed {
/* instance of cnetz sender */
struct cnetz {
sender_t sender;
+ int kanal; /* channel number */
enum cnetz_chan_type chan_type; /* channel type */
scrambler_t scrambler_tx; /* mirror what we transmit to MS */
scrambler_t scrambler_rx; /* mirror what we receive from MS */
@@ -81,7 +82,7 @@ struct cnetz {
int response_valid; /* expect authorizaton response */
uint64_t response; /* authorization response */
int warteschlange; /* use queue */
- int metering; /* use metering pulses in seconds 0 = off */
+ int metering; /* send metering units in seconds 0 = off */
/* all cnetz states */
enum cnetz_state state; /* main state of sender */
@@ -94,11 +95,14 @@ struct cnetz {
int sched_ts; /* current time slot */
int sched_last_ts; /* last timeslot we transmitted, to sync time of the receiver */
int sched_r_m; /* Rufblock (0) / Meldeblock (1) */
- int sched_switch_mode; /* counts slots until mode is switched */
- enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */
+ enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */
+ int sched_dsp_mode_ts; /* time slot when to switch mode (-1 = don't switch) */
+ int sched_lr_debugged; /* indicator to prevent debugging all idle frames */
+ int sched_mlr_debugged; /* indicator to prevent debugging all idle frames */
/* dsp states */
enum dsp_mode dsp_mode; /* current mode: audio, "Telegramm", .... */
+ double rf_level_db; /* current RF level or nan, if not applicable */
iir_filter_t lp; /* low pass filter to eliminate noise above 5280 Hz */
fsk_fm_demod_t fsk_demod; /* demod process */
double fsk_deviation; /* deviation of FSK signal on sound card */
@@ -123,8 +127,8 @@ struct cnetz {
double frame_last_phase; /* master's bit phase of last frame sync */
/* audio offset removal */
- double offset_factor; /* filer alpha of high-pass filter */
- double offset_y_last; /* last stored sample */
+ double offset_last; /* last sample value of last frame */
+ int offset_range; /* range of samples to ramp the offset */
/* measurements */
int measure_speed; /* measure clock speed */
@@ -133,17 +137,18 @@ struct cnetz {
transaction_t *trans_list; /* list of transactions */
};
+const char *cnetz_number_valid(const char *number);
double cnetz_kanal2freq(int kanal, int unterband);
void cnetz_channel_list(void);
int cnetz_channel_by_short_name(const char *short_name);
const char *chan_type_short_name(enum cnetz_chan_type chan_type);
const char *chan_type_long_name(enum cnetz_chan_type chan_type);
int cnetz_init(void);
-int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback);
+int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *device, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, double tx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback);
void cnetz_destroy(sender_t *sender);
void cnetz_go_idle(cnetz_t *cnetz);
void cnetz_sync_frame(cnetz_t *cnetz, double sync, int ts);
-int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
+int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal);
const struct telegramm *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz);
const struct telegramm *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz);
void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, struct telegramm *telegramm, int block);
diff --git a/src/cnetz/database.c b/src/cnetz/database.c
index c6d3765..4bdfb2c 100644
--- a/src/cnetz/database.c
+++ b/src/cnetz/database.c
@@ -22,32 +22,47 @@
#include <stdlib.h>
#include <string.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
+#include "../libmobile/get_time.h"
#include "cnetz.h"
#include "database.h"
+#include "sysinfo.h"
/* the network specs say: check every 1 - 6.5 minutes for availability
* remove from database after 3 subsequent failures
* the phone will register 20 minutes after no call / no paging from network.
*/
-#define MELDE_INTERVAL 120.0
-#define MELDE_WIEDERHOLUNG 60.0
-#define MELDE_MAXIMAL 3
+#define MELDE_WIEDERHOLUNG 60.0 /* when busy */
typedef struct cnetz_database {
struct cnetz_database *next;
+ int ogk_kanal; /* available on which channel */
uint8_t futln_nat; /* who ... */
uint8_t futln_fuvst;
uint16_t futln_rest;
int futelg_bit; /* chip card inside */
int extended; /* mobile supports extended frequencies */
- struct timer timer; /* timer for next availability check */
+ int eingebucht; /* set if still available */
+ double last_seen;
+ int busy; /* set if currently in a call */
+ struct osmo_timer_list timer; /* timer for next availability check */
int retry; /* counts number of retries */
} cnetz_db_t;
cnetz_db_t *cnetz_db_head;
+static const char *print_meldeaufrufe(int versuche)
+{
+ static char text[32];
+
+ if (versuche <= 0)
+ return "infinite";
+
+ sprintf(text, "%d", versuche);
+ return text;
+}
+
/* destroy transaction */
static void remove_db(cnetz_db_t *db)
{
@@ -58,43 +73,43 @@ static void remove_db(cnetz_db_t *db)
while (*dbp && *dbp != db)
dbp = &((*dbp)->next);
if (!(*dbp)) {
- PDEBUG(DDB, DEBUG_ERROR, "Subscriber not in list, please fix!!\n");
+ LOGP(DDB, LOGL_ERROR, "Subscriber not in list, please fix!!\n");
abort();
}
*dbp = db->next;
- PDEBUG(DDB, DEBUG_INFO, "Removing subscriber '%d,%d,%d' from database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
+ LOGP(DDB, LOGL_INFO, "Removing subscriber '%d,%d,%05d' from database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
- timer_exit(&db->timer);
+ osmo_timer_del(&db->timer);
free(db);
}
/* Timeout handling */
-static void db_timeout(struct timer *timer)
+static void db_timeout(void *data)
{
- cnetz_db_t *db = (cnetz_db_t *)timer->priv;
+ cnetz_db_t *db = data;
int rc;
- PDEBUG(DDB, DEBUG_INFO, "Check, if subscriber '%d,%d,%d' is still available.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
+ LOGP(DDB, LOGL_INFO, "Check, if subscriber '%d,%d,%05d' is still available.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
- rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest);
+ rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
if (rc < 0) {
/* OgK is used for speech, but this never happens in a real
* network. We just assume that the phone has responded and
* assume we had a response. */
- PDEBUG(DDB, DEBUG_INFO, "OgK busy, so we assume a positive response.\n");
- timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability again */
+ LOGP(DDB, LOGL_INFO, "OgK busy, so we assume a positive response.\n");
+ osmo_timer_schedule(&db->timer, si.meldeinterval,0); /* when to check avaiability again */
db->retry = 0;
}
}
/* create/update db entry */
-int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed)
+int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal, int *futelg_bit, int *extended, int busy, int failed)
{
cnetz_db_t *db, **dbp;
- /* search transaction for this subsriber */
+ /* search transaction for this subscriber */
db = cnetz_db_head;
while (db) {
if (db->futln_nat == futln_nat
@@ -106,11 +121,12 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t
if (!db) {
db = calloc(1, sizeof(*db));
if (!db) {
- PDEBUG(DDB, DEBUG_ERROR, "No memory!\n");
+ LOGP(DDB, LOGL_ERROR, "No memory!\n");
return 0;
}
- timer_init(&db->timer, db_timeout, db);
+ osmo_timer_setup(&db->timer, db_timeout, db);
+ db->eingebucht = 1;
db->futln_nat = futln_nat;
db->futln_fuvst = futln_fuvst;
db->futln_rest = futln_rest;
@@ -121,30 +137,37 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t
dbp = &((*dbp)->next);
*dbp = db;
- PDEBUG(DDB, DEBUG_INFO, "Adding subscriber '%d,%d,%d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
+ LOGP(DDB, LOGL_INFO, "Adding subscriber '%d,%d,%05d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
}
+ if (ogk_kanal)
+ db->ogk_kanal = ogk_kanal;
+
if (futelg_bit && *futelg_bit >= 0)
db->futelg_bit = *futelg_bit;
if (extended && *extended >= 0)
db->extended = *extended;
+ db->busy = busy;
if (busy) {
- PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
- timer_stop(&db->timer);
+ LOGP(DDB, LOGL_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
+ osmo_timer_del(&db->timer);
} else if (!failed) {
- PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
- timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability (again) */
+ LOGP(DDB, LOGL_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
+ osmo_timer_schedule(&db->timer, si.meldeinterval,0); /* when to check avaiability (again) */
db->retry = 0;
+ db->eingebucht = 1;
+ db->last_seen = get_time();
} else {
db->retry++;
- PDEBUG(DDB, DEBUG_NOTICE, "Paging subscriber '%d,%d,%d' failed (try %d of %d).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->retry, MELDE_MAXIMAL);
- if (db->retry == MELDE_MAXIMAL) {
- remove_db(db);
+ LOGP(DDB, LOGL_NOTICE, "Paging subscriber '%d,%d,%05d' on OGK channel #%d failed (try %d of %s).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal, db->retry, print_meldeaufrufe(si.meldeaufrufe));
+ if (si.meldeaufrufe && db->retry == si.meldeaufrufe) {
+ LOGP(DDB, LOGL_INFO, "Marking subscriber as gone.\n");
+ db->eingebucht = 0;
return db->extended;
}
- timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */
+ osmo_timer_schedule(&db->timer, (si.meldeinterval < MELDE_WIEDERHOLUNG) ? si.meldeinterval : MELDE_WIEDERHOLUNG,0); /* when to do retry */
}
if (futelg_bit)
@@ -154,14 +177,17 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t
return 0;
}
-int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended)
+int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *ogk_kanal, int *futelg_bit, int *extended)
{
cnetz_db_t *db = cnetz_db_head;
while (db) {
- if (db->futln_nat == futln_nat
+ if (db->eingebucht
+ && db->futln_nat == futln_nat
&& db->futln_fuvst == futln_fuvst
&& db->futln_rest == futln_rest) {
+ if (ogk_kanal)
+ *ogk_kanal = db->ogk_kanal;
if (futelg_bit)
*futelg_bit = db->futelg_bit;
if (extended)
@@ -182,15 +208,22 @@ void flush_db(void)
void dump_db(void)
{
cnetz_db_t *db = cnetz_db_head;
+ double now = get_time();
+ int last;
+ char attached[16];
- PDEBUG(DDB, DEBUG_NOTICE, "Dump of subscriber database:\n");
+ LOGP(DDB, LOGL_NOTICE, "Dump of subscriber database:\n");
if (!db) {
- PDEBUG(DDB, DEBUG_NOTICE, " - No subscribers attached!\n");
+ LOGP(DDB, LOGL_NOTICE, " - No subscribers attached!\n");
return;
}
+ LOGP(DDB, LOGL_NOTICE, "Subscriber\tAttached\tBusy\t\tLast seen\tMeldeaufrufe\n");
+ LOGP(DDB, LOGL_NOTICE, "-------------------------------------------------------------------------------\n");
while (db) {
- PDEBUG(DDB, DEBUG_NOTICE, " - Subscriber '%d,%d,%d' is attached.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
+ last = (db->busy) ? 0 : (uint32_t)(now - db->last_seen);
+ sprintf(attached, "YES (OGK %d)", db->ogk_kanal);
+ LOGP(DDB, LOGL_NOTICE, "%d,%d,%05d\t%s\t%s\t\t%02d:%02d:%02d \t%d/%s\n", db->futln_nat, db->futln_fuvst, db->futln_rest, (db->eingebucht) ? attached : "-no-\t", (db->busy) ? "YES" : "-no-", last / 3600, (last / 60) % 60, last % 60, db->retry, print_meldeaufrufe(si.meldeaufrufe));
db = db->next;
}
}
diff --git a/src/cnetz/database.h b/src/cnetz/database.h
index a1339a0..7cd1c16 100644
--- a/src/cnetz/database.h
+++ b/src/cnetz/database.h
@@ -1,6 +1,6 @@
-int update_db(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed);
-int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended);
+int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal, int *futelg_bit, int *extended, int busy, int failed);
+int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *ogk_kanal, int *futelg_bit, int *extended);
void flush_db(void);
void dump_db(void);
diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c
index 91f967c..af29c62 100644
--- a/src/cnetz/dsp.c
+++ b/src/cnetz/dsp.c
@@ -26,8 +26,9 @@
#include <math.h>
#include <errno.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "../libmobile/call.h"
+#include "../libmobile/get_time.h"
#include "cnetz.h"
#include "sysinfo.h"
#include "telegramm.h"
@@ -46,18 +47,37 @@
#define MAX_DISPLAY 1.4 /* something above speech level, no emphasis */
#define BITRATE 5280.0 /* bits per second */
#define BLOCK_BITS 198 /* duration of one time slot including pause at beginning and end */
-#define CUT_OFF_OFFSET 300.0 /* cut off frequency for offset filter (level correction between subsequent audio chunks) */
#ifdef TEST_SCRAMBLE
-jitter_t scrambler_test_jb;
+test_echo_t scrambler_test_echo = {};
scrambler_t scrambler_test_scrambler1;
scrambler_t scrambler_test_scrambler2;
#endif
-static sample_t ramp_up[256], ramp_down[256];
+static const char *cnetz_dsp_mode_name(enum dsp_mode mode)
+{
+ static char invalid[16];
+
+ switch (mode) {
+ case DSP_SCHED_NONE:
+ return "SCHED_NONE";
+ case DSP_MODE_OFF:
+ return "OFF";
+ case DSP_MODE_OGK:
+ return "OGK";
+ case DSP_MODE_SPK_K:
+ return "SPK_K";
+ case DSP_MODE_SPK_V:
+ return "SPK_V";
+ }
+
+ sprintf(invalid, "invalid(%d)", mode);
+ return invalid;
+}
void dsp_init(void)
{
+ compandor_init();
}
static void dsp_init_ramp(cnetz_t *cnetz)
@@ -65,17 +85,17 @@ static void dsp_init_ramp(cnetz_t *cnetz)
double c;
int i;
- PDEBUG(DDSP, DEBUG_DEBUG, "Generating smooth ramp table.\n");
+ LOGP(DDSP, LOGL_DEBUG, "Generating smooth ramp table.\n");
for (i = 0; i < 256; i++) {
- c = cos((double)i / 256.0 * PI);
/* use square-root of cosine ramp. tests showed that phones are more
- * happy with that. */
+ * happy with that. (This is not correct pulse shaping!) */
+ c = cos((double)i / 256.0 * PI);
if (c < 0)
c = -sqrt(-c);
else
c = sqrt(c);
- ramp_down[i] = c * (double)cnetz->fsk_deviation;
- ramp_up[i] = -ramp_down[i];
+ cnetz->fsk_ramp_down[i] = c * (double)cnetz->fsk_deviation;
+ cnetz->fsk_ramp_up[i] = -cnetz->fsk_ramp_down[i];
}
}
@@ -84,9 +104,8 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
{
int rc = 0;
double size;
- double RC, dt;
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init FSK for 'Sender'.\n");
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Init FSK for 'Sender'.\n");
/* set modulation parameters */
sender_set_fm(&cnetz->sender, MAX_DEVIATION, MAX_MODULATION, speech_deviation, MAX_DISPLAY);
@@ -97,25 +116,25 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
}
if (clock_speed[0] > 1000 || clock_speed[0] < -1000 || clock_speed[1] > 1000 || clock_speed[1] < -1000) {
- PDEBUG(DDSP, DEBUG_ERROR, "Clock speed %.1f,%.1f ppm out of range! Plese use range between +-1000 ppm!\n", clock_speed[0], clock_speed[1]);
+ LOGP_CHAN(DDSP, LOGL_ERROR, "Clock speed %.1f,%.1f ppm out of range! Please use range between +-1000 ppm!\n", clock_speed[0], clock_speed[1]);
return -EINVAL;
}
- PDEBUG(DDSP, DEBUG_INFO, "Using clock speed of %.1f ppm (RX) and %.1f ppm (TX) to correct sound card's clock.\n", clock_speed[0], clock_speed[1]);
+ LOGP_CHAN(DDSP, LOGL_INFO, "Using clock speed of %.1f ppm (RX) and %.1f ppm (TX) to correct sound card's clock.\n", clock_speed[0], clock_speed[1]);
cnetz->fsk_bitduration = (double)cnetz->sender.samplerate / ((double)BITRATE / (1.0 + clock_speed[1] / 1000000.0));
cnetz->fsk_tx_bitstep = 1.0 / cnetz->fsk_bitduration;
- PDEBUG(DDSP, DEBUG_DEBUG, "Use %.4f samples for one bit duration @ %d.\n", cnetz->fsk_bitduration, cnetz->sender.samplerate);
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Use %.4f samples for one bit duration @ %d.\n", cnetz->fsk_bitduration, cnetz->sender.samplerate);
size = cnetz->fsk_bitduration * (double)BLOCK_BITS * 16.0; /* 16 blocks for distributed frames */
cnetz->fsk_tx_buffer_size = size * 1.1; /* more to compensate clock speed */
cnetz->fsk_tx_buffer = calloc(sizeof(sample_t), cnetz->fsk_tx_buffer_size);
if (!cnetz->fsk_tx_buffer) {
- PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n");
+ LOGP_CHAN(DDSP, LOGL_ERROR, "No memory!\n");
rc = -ENOMEM;
goto error;
}
- /* create devation and ramp */
+ /* create deviation and ramp */
cnetz->fsk_deviation = FSK_DEVIATION;
dsp_init_ramp(cnetz);
@@ -125,13 +144,13 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
/* create speech buffer */
cnetz->dsp_speech_buffer = calloc(sizeof(sample_t), (int)(cnetz->fsk_bitduration * 70.0)); /* more to compensate clock speed. we just need it to fill 62 bits (60 bits, including pause bits). */
if (!cnetz->dsp_speech_buffer) {
- PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n");
+ LOGP_CHAN(DDSP, LOGL_ERROR, "No memory!\n");
rc = -ENOMEM;
goto error;
}
/* reinit the sample rate to shrink/expand audio */
- init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / 1.1, 3300.0); /* 66 <-> 60 */
+ init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / (1.1 / (1.0 + clock_speed[0] / 1000000.0)), 3300.0); /* 66 <-> 60 */
rc = fsk_fm_init(&cnetz->fsk_demod, cnetz, cnetz->sender.samplerate, (double)BITRATE / (1.0 + clock_speed[0] / 1000000.0), demod);
if (rc < 0)
@@ -141,31 +160,25 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
scrambler_setup(&cnetz->scrambler_tx, (double)cnetz->sender.samplerate / 1.1);
scrambler_setup(&cnetz->scrambler_rx, (double)cnetz->sender.samplerate / 1.1);
- /* reinit jitter buffer for 8000 kHz */
- jitter_destroy(&cnetz->sender.dejitter);
- rc = jitter_create(&cnetz->sender.dejitter, 8000 / 5);
- if (rc < 0)
- goto error;
-
/* init compandor, according to C-Netz specs, attack and recovery time
* shall not exceed according to ITU G.162 */
- init_compandor(&cnetz->cstate, 8000, 5.0, 22.5);
+ setup_compandor(&cnetz->cstate, 8000, 5.0, 22.5);
- /* use this filter to compensate level changes between two subsequent audio chunks */
- RC = 1.0 / (CUT_OFF_OFFSET * 2.0 *3.14);
- dt = 1.0 / cnetz->sender.samplerate;
- cnetz->offset_factor = RC / (RC + dt);
+ /* use duration of one bit to ramp level of last frame to current frame */
+ cnetz->offset_range = ceil(cnetz->fsk_bitduration);
#ifdef TEST_SCRAMBLE
- rc = jitter_create(&scrambler_test_jb, cnetz->sender.samplerate / 5);
+ rc = test_echo_alloc(&scrambler_test_echo, cnetz->sender.samplerate / 20);
if (rc < 0) {
- PDEBUG(DDSP, DEBUG_ERROR, "Failed to init jitter buffer for scrambler test!\n");
+ LOGP_CHAN(DDSP, LOGL_ERROR, "Failed to init echo buffer for scrambler test!\n");
exit(0);
}
scrambler_setup(&scrambler_test_scrambler1, cnetz->sender.samplerate);
scrambler_setup(&scrambler_test_scrambler2, cnetz->sender.samplerate);
#endif
+ cnetz->sched_dsp_mode_ts = -1;
+
return 0;
error:
@@ -176,7 +189,7 @@ error:
void dsp_cleanup_sender(cnetz_t *cnetz)
{
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Cleanup FSK for 'Sender'.\n");
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Cleanup FSK for 'Sender'.\n");
if (cnetz->fsk_tx_buffer) {
free(cnetz->fsk_tx_buffer);
@@ -206,7 +219,7 @@ void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result)
ti = get_time();
- /* skip some time to avoid false mesurement due to filling of buffers */
+ /* skip some time to avoid false measurement due to filling of buffers */
if (cs->meas_ti == 0.0) {
cs->meas_ti = ti + 1.0;
return;
@@ -244,7 +257,7 @@ void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result)
speed_ppm_avg[index] += cs->speed_ppm[index][(cs->idx[index] - i - 1) & 0xff];
speed_ppm_avg[index] /= (double)cs->num[index];
}
- PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Clock: RX=%.3f TX=%.3f; Signal: RX=%.3f TX=%.3f ppm\n", speed_ppm_avg[0], speed_ppm_avg[1], speed_ppm_avg[2], speed_ppm_avg[3]);
+ LOGP_CHAN(DDSP, LOGL_NOTICE, "Clock: RX=%.3f TX=%.3f; Signal: RX=%.3f TX=%.3f ppm\n", speed_ppm_avg[0], speed_ppm_avg[1], speed_ppm_avg[2], speed_ppm_avg[3]);
}
static int fsk_nothing_encode(cnetz_t *cnetz)
@@ -308,14 +321,14 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk)
if (bits[i] == '1') {
/* ramp up from 0 */
do {
- *spl++ = ramp_up[(uint8_t)phase] / 2 + deviation / 2;
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase] / 2 + deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
} else {
/* ramp down from 0 */
do {
- *spl++ = ramp_down[(uint8_t)phase] / 2 - deviation / 2;
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase] / 2 - deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -332,7 +345,7 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk)
} else {
/* ramp down */
do {
- *spl++ = ramp_down[(uint8_t)phase];
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -342,7 +355,7 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk)
if (bits[i] == '1') {
/* ramp up */
do {
- *spl++ = ramp_up[(uint8_t)phase];
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -362,14 +375,14 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk)
if (last == '0') {
/* ramp up to 0 */
do {
- *spl++ = ramp_up[(uint8_t)phase] / 2 - deviation / 2;
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase] / 2 - deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
} else {
/* ramp down to 0 */
do {
- *spl++ = ramp_down[(uint8_t)phase] / 2 + deviation / 2;
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase] / 2 + deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -408,7 +421,7 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk)
* the marker is placed in the middle of the 6th bit.
* because we have a transition (ramp) in the middle of each bit.
* the phone will see the position of the marker as start of the 6th bit.
- * the marker marks the pont where the speech is ramped up, so the phone
+ * the marker marks the point where the speech is ramped up, so the phone
* will see the speech completely ramped up after the 6th bit
*/
static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
@@ -458,14 +471,14 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
if (bits[i * 4 + j] == '1') {
/* ramp up from 0 */
do {
- *spl++ = ramp_up[(uint8_t)phase] / 2 + deviation / 2;
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase] / 2 + deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
} else {
/* ramp down from 0 */
do {
- *spl++ = ramp_down[(uint8_t)phase] / 2 - deviation / 2;
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase] / 2 - deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -482,7 +495,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
} else {
/* ramp down */
do {
- *spl++ = ramp_down[(uint8_t)phase];
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -492,7 +505,7 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
if (bits[i * 4 + j] == '1') {
/* ramp up */
do {
- *spl++ = ramp_up[(uint8_t)phase];
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -512,14 +525,14 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
if (last == '0') {
/* ramp up to 0 */
do {
- *spl++ = ramp_up[(uint8_t)phase] / 2 - deviation / 2;
+ *spl++ = cnetz->fsk_ramp_up[(uint8_t)phase] / 2 - deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
} else {
/* ramp down to 0 */
do {
- *spl++ = ramp_down[(uint8_t)phase] / 2 + deviation / 2;
+ *spl++ = cnetz->fsk_ramp_down[(uint8_t)phase] / 2 + deviation / 2;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
@@ -547,10 +560,12 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
/* decode samples and hut for bit changes
* use deviation to find greatest slope of the signal (bit change)
*/
-void sender_receive(sender_t *sender, sample_t *samples, int length, double __attribute__((unused)) rf_level_db)
+void sender_receive(sender_t *sender, sample_t *samples, int length, double rf_level_db)
{
cnetz_t *cnetz = (cnetz_t *) sender;
+ cnetz->rf_level_db = rf_level_db;
+
/* measure rx sample speed */
calc_clock_speed(cnetz, length, 0, 0);
@@ -558,7 +573,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
#ifdef TEST_UNSCRAMBLE
scrambler(&scrambler_test_scrambler1, samples, length);
#endif
- jitter_save(&scrambler_test_jb, samples, length);
+ test_echo_store(&scrambler_test_echo, samples, length);
return;
#endif
@@ -574,12 +589,15 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
static int shrink_speech(cnetz_t *cnetz, sample_t *speech_buffer)
{
int speech_length;
+ int16_t spl[100];
- jitter_load(&cnetz->sender.dejitter, speech_buffer, 100);
+ jitter_load_samples(&cnetz->sender.dejitter, (uint8_t *)spl, 100, sizeof(*spl), jitter_conceal_s16, NULL);
+ int16_to_samples_speech(speech_buffer, spl, 100);
/* 1. compress dynamics */
compress_audio(&cnetz->cstate, speech_buffer, 100);
/* 2. upsample */
- speech_length = samplerate_upsample(&cnetz->sender.srstate, speech_buffer, 100, speech_buffer);
+ speech_length = samplerate_upsample_output_num(&cnetz->sender.srstate, 100);
+ samplerate_upsample(&cnetz->sender.srstate, speech_buffer, 100, speech_buffer, speech_length);
/* 3. scramble */
if (cnetz->scrambler)
scrambler(&cnetz->scrambler_tx, speech_buffer, speech_length);
@@ -627,60 +645,66 @@ again:
* because one has a phase wrap before and the other after a sample.
* then we do it next super frame cycle */
if (master->frame_last_scount == cnetz->fsk_tx_scount) {
- PDEBUG(DDSP, DEBUG_DEBUG, "Sync phase of slave to master: master=%.15f, slave=%.15f, diff=%.15f\n", master->frame_last_phase, cnetz->fsk_tx_phase, master->frame_last_phase - cnetz->fsk_tx_phase);
+ LOGP(DDSP, LOGL_DEBUG, "Sync phase of slave to master: master=%.15f, slave=%.15f, diff=%.15f\n", master->frame_last_phase, cnetz->fsk_tx_phase, master->frame_last_phase - cnetz->fsk_tx_phase);
cnetz->fsk_tx_phase = master->frame_last_phase;
} else {
- PDEBUG(DDSP, DEBUG_DEBUG, "Not sync phase of slave to master: Sample counts during frame change are different, ignoring this time!\n");
+ LOGP(DDSP, LOGL_DEBUG, "Not sync phase of slave to master: Sample counts during frame change are different, ignoring this time!\n");
}
}
}
/* switch to speech channel */
- if (cnetz->sched_switch_mode && cnetz->sched_r_m == 0) {
- if (--cnetz->sched_switch_mode == 0) {
+ if (cnetz->sched_dsp_mode_ts >= 0 && cnetz->sched_r_m == 0) {
+ if (cnetz->sched_dsp_mode_ts == cnetz->sched_ts) {
/* OgK / SpK(K) / SpK(V) */
- PDEBUG_CHAN(DDSP, DEBUG_INFO, "Switching channel (mode)\n");
+ LOGP_CHAN(DDSP, LOGL_INFO, "Now switching channel mode to %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->sched_dsp_mode), cnetz->sched_dsp_mode_ts);
+ cnetz->sched_dsp_mode_ts = -1;
cnetz_set_dsp_mode(cnetz, cnetz->sched_dsp_mode);
}
}
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
- /* if automatic polarity selection is used, toggle between
- * two polarities (every 4 slots) until a response is received
- * then continue to use the time slots of that polarity
- */
- if (cnetz->auto_polarity)
- cnetz->negative_polarity = (cnetz->sched_ts & 7) >> 2;
- /* send on timeslots depending on the polarity:
- * positive polarity: 0, 8, 16, 24
- * negative polarity: 4, 12, 20, 28
- */
- if (((cnetz->sched_ts & 7) == 0 && cnetz->negative_polarity == 0)
- || ((cnetz->sched_ts & 7) == 4 && cnetz->negative_polarity == 1)) {
+ if (((si.timeslots >> cnetz->sched_ts) & 1)) {
if (cnetz->sched_r_m == 0) {
+ /* if automatic polarity selection is used, toggle between two polarities (every transmitted slot) until a response is received then continue to use the time slots of that polarity */
+ if (cnetz->auto_polarity)
+ cnetz->negative_polarity = (cnetz->sched_ts & 7) >> 2;
/* set last time slot, so we know to which time slot the message from mobile station belongs to */
cnetz->sched_last_ts = cnetz->sched_ts;
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Rufblock' at timeslot %d\n", cnetz->sched_ts);
bits = cnetz_encode_telegramm(cnetz);
+ if (bits) {
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Transmitting 'Rufblock' at timeslot %d\n", cnetz->sched_ts);
+ fsk_block_encode(cnetz, bits, 1);
+ } else
+ fsk_nothing_encode(cnetz);
} else {
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Meldeblock' at timeslot %d\n", cnetz->sched_ts);
bits = cnetz_encode_telegramm(cnetz);
+ if (bits) {
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Transmitting 'Meldeblock' at timeslot %d\n", cnetz->sched_ts);
+ fsk_block_encode(cnetz, bits, 1);
+ } else
+ fsk_nothing_encode(cnetz);
}
- fsk_block_encode(cnetz, bits, 1);
} else {
fsk_nothing_encode(cnetz);
}
break;
case DSP_MODE_SPK_K:
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Konzentrierte Signalisierung'\n");
bits = cnetz_encode_telegramm(cnetz);
- fsk_block_encode(cnetz, bits, 0);
+ if (bits) {
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Transmitting 'Konzentrierte Signalisierung' at timeslot %d.%d\n", cnetz->sched_ts, cnetz->sched_r_m * 5);
+ fsk_block_encode(cnetz, bits, 0);
+ } else
+ fsk_nothing_encode(cnetz);
break;
case DSP_MODE_SPK_V:
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Verteilte Signalisierung'\n");
bits = cnetz_encode_telegramm(cnetz);
- fsk_distributed_encode(cnetz, bits);
+ if (bits) {
+ LOGP_CHAN(DDSP, LOGL_DEBUG, "Transmitting 'Verteilte Signalisierung' starting at timeslot %d\n", cnetz->sched_ts);
+ fsk_distributed_encode(cnetz, bits);
+ } else
+ fsk_nothing_encode(cnetz);
break;
case DSP_MODE_OFF:
default:
@@ -718,7 +742,7 @@ again:
/* ramp before speech */
for (j = 0; j < begin; j++) {
/* ramp up from 0 to speech level */
- speech_buffer[j] = speech_buffer[begin] * (ramp_up[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
+ speech_buffer[j] = speech_buffer[begin] * (cnetz->fsk_ramp_up[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
}
speech_length += begin; /* add one bit duration before speech*/
/* ramp after speech */
@@ -729,7 +753,7 @@ again:
speech_length = end; /* shorten 'speech_length', if greater than 'end' */
for (j = 0; j < begin; j++) {
/* ramp down from speech level to 0 */
- speech_buffer[end + j] = speech_buffer[end - 1] * (ramp_down[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
+ speech_buffer[end + j] = speech_buffer[end - 1] * (cnetz->fsk_ramp_down[j * 256 / begin] / cnetz->fsk_deviation / 2.0 + 0.5);
}
speech_length += begin; /* add one bit duration after speech */
speech_pos = 0;
@@ -773,7 +797,7 @@ void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length
calc_clock_speed(cnetz, length, 1, 0);
#ifdef TEST_SCRAMBLE
- jitter_load(&scrambler_test_jb, samples, length);
+ test_echo_load(&scrambler_test_echo, samples, length);
scrambler(&scrambler_test_scrambler2, samples, length);
return;
#endif
@@ -792,7 +816,8 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
{
sample_t *spl;
int pos, i;
- double x, y, x_last, y_last, factor;
+ int range;
+ double offset;
/* check if we still have a transaction
* this might not be true, if we just released transaction, but still
@@ -801,21 +826,13 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
if (!cnetz->trans_list)
return;
- /* fix offset between speech blocks by using high pass filter */
- /* use first sample as previous sample, so we don't have a level jump between two subsequent audio chunks */
- x_last = speech_buffer[0];
- y_last = cnetz->offset_y_last;
- factor = cnetz->offset_factor;
- for (i = 0; i < count; i++) {
- /* change level */
- x = speech_buffer[i];
- /* high-pass to remove low level frequencies, caused by level jump between audio chunks */
- y = factor * (y_last + x - x_last);
- x_last = x;
- y_last = y;
- speech_buffer[i] = y;
+ /* ramp from level of last frame to level of current frame */
+ range = cnetz->offset_range;
+ offset = speech_buffer[0] - cnetz->offset_last;
+ for (i = 0; i < range; i++) {
+ speech_buffer[i] -= offset * (1.0 - (double)i / (double)range);
}
- cnetz->offset_y_last = y_last;
+ cnetz->offset_last = speech_buffer[count - 1];
/* 4. de-emphasis is done by cnetz code, not by common code */
/* de-emphasis is only used when scrambler is off, see FTZ 171 TR 60 Clause 4 */
@@ -843,39 +860,51 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
cnetz->sender.rxbuf_pos = pos;
}
-const char *cnetz_dsp_mode_name(enum dsp_mode mode)
+void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode)
{
- static char invalid[16];
-
- switch (mode) {
- case DSP_SCHED_NONE:
- return "SCHED_NONE";
- case DSP_MODE_OFF:
- return "OFF";
- case DSP_MODE_OGK:
- return "OGK";
- case DSP_MODE_SPK_K:
- return "SPK_K";
- case DSP_MODE_SPK_V:
- return "SPK_V";
+ if (mode != cnetz->dsp_mode) {
+ LOGP_CHAN(DDSP, LOGL_INFO, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode));
+ cnetz->dsp_mode = mode;
}
+ if (mode == DSP_MODE_SPK_V && cnetz->dsp_mode != mode)
+ jitter_reset(&cnetz->sender.dejitter);
- sprintf(invalid, "invalid(%d)", mode);
- return invalid;
-}
-
-void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode)
-{
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode));
- cnetz->dsp_mode = mode;
/* we must get rid of partly received frame */
fsk_demod_reset(&cnetz->fsk_demod);
}
-void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead)
+void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot)
{
- PDEBUG_CHAN(DDSP, DEBUG_DEBUG, " Schedule DSP mode %s -> %s in %d frames\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), frames_ahead);
+ if (cnetz->sched_dsp_mode_ts < 0 && mode == cnetz->dsp_mode) {
+ LOGP_CHAN(DDSP, LOGL_INFO, "Schedule DSP mode %s not required, we are already in that mode\n", cnetz_dsp_mode_name(mode));
+ return;
+ }
+ LOGP_CHAN(DDSP, LOGL_INFO, "Schedule DSP mode %s -> %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), timeslot);
cnetz->sched_dsp_mode = mode;
- cnetz->sched_switch_mode = frames_ahead;
+ cnetz->sched_dsp_mode_ts = timeslot;
}
+/* Receive audio from call instance. */
+void call_down_audio(void *decoder, void *decoder_priv, int callref, uint16_t sequence, uint8_t marker, uint32_t timestamp, uint32_t ssrc, uint8_t *payload, int payload_len)
+{
+ sender_t *sender;
+ cnetz_t *cnetz;
+
+ for (sender = sender_head; sender; sender = sender->next) {
+ cnetz = (cnetz_t *) sender;
+ if (cnetz->trans_list && cnetz->trans_list->callref == callref)
+ break;
+ }
+ if (!sender)
+ return;
+
+ if (cnetz->dsp_mode == DSP_MODE_SPK_V) {
+ jitter_frame_t *jf;
+ jf = jitter_frame_alloc(decoder, decoder_priv, payload, payload_len, marker, sequence, timestamp, ssrc);
+ if (jf)
+ jitter_save(&cnetz->sender.dejitter, jf);
+ }
+}
+
+void call_down_clock(void) {}
+
diff --git a/src/cnetz/dsp.h b/src/cnetz/dsp.h
index f5e3506..7af7c94 100644
--- a/src/cnetz/dsp.h
+++ b/src/cnetz/dsp.h
@@ -5,5 +5,5 @@ void dsp_cleanup_sender(cnetz_t *cnetz);
void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result);
void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count);
void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode);
-void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead);
+void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot);
diff --git a/src/cnetz/fsk_demod.c b/src/cnetz/fsk_demod.c
index 42865df..9386b60 100644
--- a/src/cnetz/fsk_demod.c
+++ b/src/cnetz/fsk_demod.c
@@ -39,13 +39,13 @@
* 0-level of the phone's transmitter is. (level of carrier frequency) Also we
* use receiver and sound card that cause any level to return to 0 after some
* time, Even if the transmitter still transmits a level above or below the
- * carrier frequnecy. Insted we look at the change of the received signal. An
+ * carrier frequnecy. Instead we look at the change of the received signal. An
* upward change indicates 1. An downward change indicates 0. (This may also be
* reversed, if we find out, that we received a sync sequence in reversed
* polarity.) If there is no significant change in level, we keep the value of
* last change, regardless of what level we actually receive.
*
- * To determine a change from noise, we use a theshold. This is set to half of
+ * To determine a change from noise, we use a threshold. This is set to half of
* the level of last received change. This means that the next change may be
* down to a half lower. There is a special case during distributed signaling.
* The first level change of each data chunk raises or falls from 0-level
@@ -65,7 +65,7 @@
* determine the highest slope, the highest difference between subsequent
* samples is used. For every sample we move the window one bit to the right
* (next sample), check if change level matches the threshold and highest slope
- * is in the middle and so forth. Only if the highes slope is exactly in the
+ * is in the middle and so forth. Only if the highest slope is exactly in the
* middle, we declare a change. This means that we detect a slope about half of
* a bit duration later.
*
@@ -121,7 +121,10 @@
* if debug is set to 1, debugging will start at program start
*/
//#define DEBUG_DECODER
-//static int debug = 0;
+
+#ifdef DEBUG_DECODER
+static int debug = 0;
+#endif
#include <stdio.h>
#include <stdint.h>
@@ -129,7 +132,7 @@
#include <string.h>
#include <math.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "cnetz.h"
#include "dsp.h"
#include "telegramm.h"
@@ -140,7 +143,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
memset(fsk, 0, sizeof(*fsk));
if (samplerate < 48000) {
- PDEBUG(DDSP, DEBUG_ERROR, "Sample rate must be at least 48000 Hz!\n");
+ LOGP(DDSP, LOGL_ERROR, "Sample rate must be at least 48000 Hz!\n");
return -1;
}
@@ -149,13 +152,13 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
switch (demod) {
case FSK_DEMOD_SLOPE:
- PDEBUG(DDSP, DEBUG_INFO, "Detecting level change by looking at slope (good for sound cards)\n");
+ LOGP(DDSP, LOGL_INFO, "Detecting level change by looking at slope (good for sound cards)\n");
break;
case FSK_DEMOD_LEVEL:
- PDEBUG(DDSP, DEBUG_INFO, "Detecting level change by looking zero crosssing (good for SDR)\n");
+ LOGP(DDSP, LOGL_INFO, "Detecting level change by looking zero crosssing (good for SDR)\n");
break;
default:
- PDEBUG(DDSP, DEBUG_ERROR, "Wrong demod type, please fix!\n");
+ LOGP(DDSP, LOGL_ERROR, "Wrong demod type, please fix!\n");
abort();
}
@@ -163,7 +166,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
half = (int)((double)samplerate / bitrate / 2.0 + 0.5);
fsk->bit_buffer_spl = calloc(sizeof(fsk->bit_buffer_spl[0]), len);
if (!fsk->bit_buffer_spl) {
- PDEBUG(DDSP, DEBUG_ERROR, "No mem!\n");
+ LOGP(DDSP, LOGL_ERROR, "No mem!\n");
goto error;
}
@@ -174,7 +177,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
fsk->speech_size = samplerate * 60 / bitrate + 10; /* 60 bits duration, add 10 to be safe */
fsk->speech_buffer = calloc(sizeof(fsk->speech_buffer[0]), fsk->speech_size);
if (!fsk->speech_buffer) {
- PDEBUG(DDSP, DEBUG_ERROR, "No mem!\n");
+ LOGP(DDSP, LOGL_ERROR, "No mem!\n");
goto error;
}
@@ -182,7 +185,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
#ifdef DEBUG_DECODER
char debug_filename[256];
- sprintf(debug_filename, "/tmp/debug_decoder_channel_%d.txt", cnetz->sender.kanal);
+ sprintf(debug_filename, "/tmp/debug_decoder_channel_%s.txt", cnetz->sender.kanal);
fsk->debug_fp = fopen(debug_filename, "w");
if (!fsk->debug_fp) {
fprintf(stderr, "Failed to open decoder debug file '%s'!\n", debug_filename);
@@ -342,12 +345,12 @@ static inline void got_bit(fsk_fm_demod_t *fsk, int bit, double change_level)
case FSK_SYNC_NONE:
fsk->rx_sync = (fsk->rx_sync << 1) | bit;
/* use half level of last change for threshold change detection.
- * if there is no change detected for 5 bits, set theshold to
+ * if there is no change detected for 5 bits, set threshold to
* 1 percent, so the 7 pause bits before a frame will make sure
* that the change is below noise level, so the first sync
* bit is detected. then the change is set and adjusted
* for all other bits in the sync sequence.
- * after sync, the theshold is set to half of the average of
+ * after sync, the threshold is set to half of the average of
* all changes in the sync sequence */
if (change_level > 0.0) {
fsk->level_threshold = change_level / 2.0;
@@ -414,17 +417,6 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
sample_t threshold;
int i;
-#ifdef DEBUG_DECODER
- /* show deviation of middle sample in windows (in a range of bandwidth) */
- if (debug) {
- fprintf(fsk->debug_fp, "%s",
- debug_amplitude(
- fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]
- )
- );
- }
-#endif
-
/* get level range (level_min and level_max) and also
* get maximum slope (change_max) and where it was
* (change_at) and what direction it went (change_positive)
@@ -492,10 +484,6 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
}
fsk->next_bit -= fsk->bits_per_sample;
-#ifdef DEBUG_DECODER
- if (debug)
- fprintf(fsk->debug_fp, "\n");
-#endif
}
/* find bit change by looking at zero crossing */
@@ -507,12 +495,6 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
/* get bit in the middle of the buffer */
s = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
-#ifdef DEBUG_DECODER
- /* show deviation */
- if (debug)
- fprintf(fsk->debug_fp, "%s", debug_amplitude(s));
-#endif
-
/* just sample first bit in distributed mode */
if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V && fsk->bit_count == 0) {
if (fmod(fsk->bit_time, BITS_PER_SPK_BLOCK) < 1.5)
@@ -569,10 +551,6 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
fsk->next_bit -= fsk->bits_per_sample;
done:
-#ifdef DEBUG_DECODER
- if (debug)
- fprintf(fsk->debug_fp, "\n");
-#endif
return;
}
@@ -580,7 +558,7 @@ done:
void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
{
int i;
- double t;
+ double t = 0.0;
/* process signaling block, sample by sample */
for (i = 0; i < length; i++) {
@@ -590,6 +568,14 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_buffer_pos == fsk->bit_buffer_len)
fsk->bit_buffer_pos = 0;
+#ifdef DEBUG_DECODER
+ /* show deviation of center sample in window */
+ if (debug)
+ fprintf(fsk->debug_fp, "%s", debug_amplitude(fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]));
+ if (debug && fmod(fsk->bit_time - fsk->bits_per_sample, 1.0) > fmod(fsk->bit_time, 1.0))
+ fprintf(fsk->debug_fp, " -bitchange-");
+#endif
+
/* for each sample process buffer */
if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V) {
if (fsk->demod_type == FSK_DEMOD_SLOPE)
@@ -611,7 +597,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
fsk->next_bit = 1.0 - fsk->bits_per_sample;
#ifdef DEBUG_DECODER
if (debug && fsk->bit_count)
- fprintf(fsk->debug_fp, "---- SPK(V) BLOCK START ----\n");
+ fprintf(fsk->debug_fp, "\n---- SPK(V) BLOCK START ----");
#endif
fsk->bit_count = 0;
} else
@@ -622,13 +608,21 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
find_change_level(fsk);
} else
if (t >= 5.5 && t < 65.5) {
+#ifdef DEBUG_DECODER
+ if (debug && !fsk->speech_count)
+ fprintf(fsk->debug_fp, " (start recording speech)");
+#endif
/* get audio for the duration of 60 bits */
/* prevent overflow, if speech_size != 0 and SPK_V
* has been restarted. */
if (fsk->speech_count < fsk->speech_size)
- fsk->speech_buffer[fsk->speech_count++] = samples[i];
+ fsk->speech_buffer[fsk->speech_count++] = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
} else
if (t >= 65.5) {
+#ifdef DEBUG_DECODER
+ if (debug && fsk->speech_count)
+ fprintf(fsk->debug_fp, " (stop recording speech)");
+#endif
if (fsk->speech_count) {
unshrink_speech(fsk->cnetz, fsk->speech_buffer, fsk->speech_count);
fsk->speech_count = 0;
@@ -641,6 +635,10 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_time >= BITS_PER_SUPERFRAME) {
fsk->bit_time -= BITS_PER_SUPERFRAME;
}
+#ifdef DEBUG_DECODER
+ if (debug && samples)
+ fprintf(fsk->debug_fp, "\n");
+#endif
/* another clock is used to measure actual super frame time */
fsk->bit_time_uncorrected += fsk->bits_per_sample;
if (fsk->bit_time_uncorrected >= BITS_PER_SUPERFRAME) {
diff --git a/src/cnetz/fsk_demod.h b/src/cnetz/fsk_demod.h
index 2d33c80..fda73a5 100644
--- a/src/cnetz/fsk_demod.h
+++ b/src/cnetz/fsk_demod.h
@@ -1,6 +1,6 @@
-#define BITS_PER_SUPERFRAME 12672.0 /* super frame (Oberrahmen) has duration of excactly 2.4 seconds */
-#define BITS_PER_BLOCK 198.0 /* block has duration of excactly 37.5 milli seconds */
+#define BITS_PER_SUPERFRAME 12672.0 /* super frame (Oberrahmen) has duration of exactly 2.4 seconds */
+#define BITS_PER_BLOCK 198.0 /* block has duration of exactly 37.5 milli seconds */
#define BITS_PER_SPK_BLOCK 66.0 /* spk block has a duration of exactly 12.5 milli seconds */
/* fsk rx sync state */
diff --git a/src/cnetz/image.c b/src/cnetz/image.c
index b2313c8..a9be2c7 100644
--- a/src/cnetz/image.c
+++ b/src/cnetz/image.c
@@ -1,80 +1,39 @@
#include <stdio.h>
-#include <string.h>
-#include "../libmobile/image.h"
-const char *image[] = {
- "@g _\n"
- " @y______________@g ( )\n"
- " @y/ \\@g / /\n"
- " @y(@w Die Mauer ist@y )@g / /\n"
- " @y\\@w gefallen!@y /@g / /\n"
- " @y\\_______ __/@g / /\n"
- " @y\\ |@g / /\n"
- " @wC-NETZ@g @y\\|@g / /\n"
+const char *aaimage[] = {
+ "@w _\n"
+ " @y______________@w ( )\n"
+ " @y/ \\@w / /\n"
+ " @y(@W Die Mauer ist@y )@w / /\n"
+ " @y\\@W gefallen!@y /@w / /\n"
+ " @y\\_______ __/@w / /\n"
+ " @y\\ |@w / /\n"
+ " @WC-NETZ@w @y\\|@w / /\n"
" __________________/_/_\n"
" / oo /|\n"
" / o o o / |\n"
" / oo / |\n"
" / ________________ / |\n"
- " / / @G021250993@g / / /\n"
+ " / / @g021250993@w / / /\n"
" / /_______________/ / /\n"
- " / @b______ ______@g / / @c___@g\n"
- " / @b/_@G(@b_@G)@b_/ /_@r(@b_@r)@b_/@g / / @c\\ \\__ @r___/@g\n"
- " / @b____ ____ ____@g / / @c_ ) / @r__/ )@g\n"
- " / @b/_@w1@b_/ /_@w2@b_/ /_@w3@b_/@g / / @c( \\/ \\@r/ |@g\n"
- " / @b____ ____ ____@g / / @c| @r| \\@g\n"
- " / @b/_@w4@b_/ /_@w5@b_/ /_@w6@b_/@g / / @c/ @r\\ |@g\n"
- " / @b____ ____ ____@g / / @c| BRD @r/ DDR )@g\n"
- " / @b/_@w7@b_/ /_@w8@b_/ /_@w9@b_/@g / / @c_| @r/ |@g\n"
- " / @b____ ____ ____@g / / @c\\ @r| |@g\n"
- " / @b/_@w*@b_/ /_@w0@b_/ /_@w#@b_/@g / / @c/ @r/ ___/@g\n"
- " / / / @c| @r\\________/@g\n"
- " / o o / / @c\\ \\@g\n"
- " /_____________________/ / @c| \\@g\n"
- " | | / @c\\___ \\_@g\n"
- " | = = | / @c/ /@g\n"
- " | = = | / @c/ __ (@g\n"
- " |______________________|/ @c|___________/ \\)@g\n"
+ " / @B______ ______@w / / @c___@w\n"
+ " / @B/_@g(@B_@g)@B_/ /_@r(@B_@r)@B_/@w / / @c\\ \\__ @r___/@w\n"
+ " / @B____ ____ ____@w / / @c_ ) / @r__/ )@w\n"
+ " / @B/_@W1@B_/ /_@W2@B_/ /_@W3@B_/@w / / @c( \\/ \\@r/ |@w\n"
+ " / @B____ ____ ____@w / / @c| @r| \\@w\n"
+ " / @B/_@W4@B_/ /_@W5@B_/ /_@W6@B_/@w / / @c/ @r\\ |@w\n"
+ " / @B____ ____ ____@w / / @c| BRD @r/ DDR )@w\n"
+ " / @B/_@W7@B_/ /_@W8@B_/ /_@W9@B_/@w / / @c_| @r/ |@w\n"
+ " / @B____ ____ ____@w / / @c\\ @r| |@w\n"
+ " / @B/_@W*@B_/ /_@W0@B_/ /_@W#@B_/@w / / @c/ @r/ ___/@w\n"
+ " / / / @c| @r\\________/@w\n"
+ " / o o / / @c\\ \\@w\n"
+ " /_____________________/ / @c| \\@w\n"
+ " | | / @c\\___ \\_@w\n"
+ " | = = | / @c/ /@w\n"
+ " | = = | / @c/ __ (@w\n"
+ " |______________________|/ @c|___________/ \\)@w\n"
"@w",
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 'g': /* gray */
- printf("\033[0;37m");
- break;
- case 'G': /* green */
- printf("\033[0;32m");
- break;
- case 'c': /* cyan */
- printf("\033[0;36m");
- break;
- case 'w': /* white */
- printf("\033[1;37m");
- break;
- case 'y': /* yellow */
- printf("\033[0;33m");
- break;
- case 'r': /* red */
- printf("\033[0;31m");
- break;
- case 'b': /* blue */
- printf("\033[1;34m");
- break;
- }
- } else
- printf("%c", image[i][j]);
- }
- printf("\n");
- }
- printf("\033[0;39m");
-}
-
diff --git a/src/cnetz/main.c b/src/cnetz/main.c
index 265e433..f3b58c7 100644
--- a/src/cnetz/main.c
+++ b/src/cnetz/main.c
@@ -24,7 +24,7 @@
#include <errno.h>
#include "../libsample/sample.h"
#include "../libmobile/main_mobile.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "../libmobile/call.h"
#include "../anetz/freiton.h"
#include "../anetz/besetztton.h"
@@ -44,18 +44,20 @@ enum cnetz_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_OGK_SPK };
int measure_speed = 0;
double clock_speed[2] = { 0.0, 0.0 };
int set_clock_speed = 0;
-const char *flip_polarity = "auto";
+const char *flip_polarity = "";
int ms_power = 6; /* 1..8 */
int warteschlange = 1;
int challenge_valid;
uint64_t challenge;
int response_valid;
uint64_t response;
+uint32_t timeslots = 4; /* 1 up to 8 */
uint8_t fuz_nat = 1;
uint8_t fuz_fuvst = 4;
uint8_t fuz_rest = 66;
const char *fuz_name = NULL;
uint8_t kennung_fufst = 1; /* normal prio */
+uint8_t bahn_bs = 0; /* normal */
uint8_t authentifikationsbit = 0;
uint8_t ws_kennung = 0; /* no queue */
uint8_t fuvst_sperren = 0; /* no blocking registration/calls */
@@ -71,9 +73,11 @@ uint8_t reduzierung = 0; /* factor 4 */
uint8_t nachbar_prio = 0;
int8_t futln_sperre_start = -1; /* no blocking */
int8_t futln_sperre_end = -1; /* no range */
+int meldeinterval = 120; /* when to ask the phone about beeing alive */
+int meldeaufrufe = 3; /* how many times to ask phone about beeing alive */
enum demod_type demod = FSK_DEMOD_AUTO;
int metering = 20;
-double speech_deviation = 4000.0; /* best results with all my equipment */
+double speech_deviation = 2400.0; /* best results with older equipment (not C5) */
void print_help(const char *arg0)
{
@@ -81,6 +85,10 @@ void print_help(const char *arg0)
/* - - */
printf(" -T --channel-type <channel type> | list\n");
printf(" Give channel type, use 'list' to get a list. (default = '%s')\n", chan_type_short_name(chan_type[0]));
+ printf(" You must define at least one OgK at channel 131. This channel may be a\n");
+ printf(" a combined OgK+SpK channel, but this works with older phones only.\n");
+ printf(" You must define additionally one or more SpK, in order to make calls.\n");
+ printf(" You may define alternative OgK, the phones will attach to it then.\n");
printf(" -M --measure-speed\n");
printf(" Measures clock speed. THIS IS REQUIRED! See documentation!\n");
printf(" -C --clock-speed <rx ppm>,<tx ppm>\n");
@@ -94,15 +102,15 @@ void print_help(const char *arg0)
printf(" generates a negative signal rather than a positive one. If auto, the\n");
printf(" base station uses double time slots with alternating polarity.\n");
printf(" Once a mobile registers, the correct polarity is selected and used.\n");
- printf(" (default = %s)\n", flip_polarity);
- printf(" Note: This has no effect with SDR.\n");
+ printf(" (default = %s)\n", (flip_polarity[0]) ? flip_polarity : "auto");
+ printf(" Note: Correct polarity is selected for SDR by default.\n");
printf(" -P --ms-power <power level>\n");
printf(" Give power level of the mobile station: 1, 2, 4, 6, 8 (default = '%d')\n", ms_power);
printf(" 1 = 7.5-20 W; 2 = 4-8 W; 4 = 0.5-1 W; 6 = 50-125 mW; 8 = 2-10 mW\n");
printf(" Power level 8 starts with level 6 and is then reduced on SpK.\n");
printf(" -A --authentication <challenge>\n");
printf(" Enable authorization flag on the base station and use given challenge\n");
- printf(" as autorization random. Depending on the key inside the card you will\n");
+ printf(" as authorization random. Depending on the key inside the card you will\n");
printf(" get a response. Any response is accepted. Phone must have smart card!\n");
printf(" The challenge can be any 64 bit (hex) number like: 0x0123456789abcdef\n");
printf(" Note: Authentication is automatically enabled for the base station\n");
@@ -114,12 +122,18 @@ void print_help(const char *arg0)
printf(" Enable queue support. If no channel is available, calls will be kept\n");
printf(" in a queue for maximum of 60 seconds. (default = %d)\n", warteschlange);
printf(" -G --gebuehren <seconds> | 0\n");
- printf(" Increment metering counter every given number of seconds.\n");
+ printf(" Increment metering counter every given number of seconds.\n");
printf(" To turn off, use 0. (default = %d)\n", metering);
+ printf(" If metering pulses are sent via Osmo-CC interface, pulses are always\n");
+ printf(" increment metering counter. This overrides this option.\n");
printf(" -V --voice-deviation <2400..4000 Hz>\n");
- printf(" It is unclear what the actual voice deviation is. Please decrease, if\n");
- printf(" mobile's microphone is too loud and speaker is too quiet.\n");
+ printf(" It is unclear what the actual voice deviation is. Please increase, if\n");
+ printf(" mobile's earpiece is too quiet and the microphone is too loud.\n");
printf(" (default = %.0f)\n", speech_deviation);
+ printf(" -S --sysinfo timeslots=1|2|4|8\n");
+ printf(" Set number of timeslots of OgK broadcast. There are 32 time slots per\n");
+ printf(" frame, but only up to 8 slots can be used, because of processing\n");
+ printf(" delay. (default = %d)\n", timeslots);
printf(" -S --sysinfo fuz-nat=<nat>\n");
printf(" Set country ID of base station. All IDs were used inside Germany only.\n");
printf(" (default = %d)\n", fuz_nat);
@@ -139,10 +153,16 @@ void print_help(const char *arg0)
printf(" 2 = Higher priority base station.\n");
printf(" 3 = Highest priority base station.\n");
printf(" Note: Priority has no effect, because there is only one base station.\n");
- printf(" -A --sysinfo authentifikationsbit=auth>\n");
+ printf(" -S --sysinfo bahn-bs=<value>\n");
+ printf(" Set special tunnel base station mode for train mobile phones only.\n");
+ printf(" (default = %d)\n", kennung_fufst);
+ printf(" 0 = Disable (every phone is allowed)\n");
+ printf(" 1 = Enable (only train phones are allowed)\n");
+ printf(" Note: Enableing this will force priority to 0 (Test base station).\n");
+ printf(" -S --sysinfo auth=<auth>\n");
printf(" Enable authentication flag on the base station. Since we cannot\n");
printf(" authenticate, because we don't know the secret key and the algorithm,\n");
- printf(" we just accept any card. Useful get the vendor IDs of the phone.\n");
+ printf(" we just accept any card. Useful to get the vendor IDs of the phone.\n");
printf(" 0 = Disable. Even chip card phones behave like magnetic card phones.\n");
printf(" 1 = Enable. Chip card phones send their card ID.\n");
printf(" (default = %d)\n", authentifikationsbit);
@@ -211,6 +231,12 @@ void print_help(const char *arg0)
} else {
printf(" (default = %d-%d)\n", futln_sperre_start, futln_sperre_end);
}
+ printf(" -S --sysinfo meldeinterval=<seconds>\n");
+ printf(" Time to wait until pinging the phone wether it is still available.\n");
+ printf(" (default = %d)\n", meldeinterval);
+ printf(" -S --sysinfo meldeaufrufe=<count>\n");
+ printf(" Number of times we try to ping mobile until we assume it is gone.\n");
+ printf(" Use '0' for infinite tries. (default = %d)\n", meldeaufrufe);
printf(" -D --demod auto | slope | level\n");
printf(" Adjust demodulation algorithm. Use 'slope' to detect a level change\n");
printf(" by finding the highest slope of a bit transition. It is useful, if\n");
@@ -220,8 +246,7 @@ void print_help(const char *arg0)
printf(" requires a DC coupled signal, which is produced by SDR.\n");
printf(" Use 'auto' to select 'slope' for sound card input and 'level' for SDR\n");
printf(" input. (default = '%s')\n", (demod == FSK_DEMOD_LEVEL) ? "level" : (demod == FSK_DEMOD_SLOPE) ? "slope" : "auto");
- printf("\nstation-id: Give 7 digit station-id, you don't need to enter it for every\n");
- printf(" start of this program.\n");
+ main_mobile_print_station_id();
main_mobile_print_hotkeys();
printf("Press 'i' key to dump list of currently attached subscribers.\n");
}
@@ -341,6 +366,9 @@ static int handle_options(int short_option, int argi, char **argv)
return -EINVAL;
}
p++;
+ if (!strncasecmp(argv[argi], "timeslots=", p - argv[argi])) {
+ timeslots = atoi_limit(p, 1, 8);
+ } else
if (!strncasecmp(argv[argi], "fuz-nat=", p - argv[argi])) {
fuz_nat = atoi_limit(p, 0, 7);
} else
@@ -367,11 +395,14 @@ error_fuz:
fuz_rest = atoi_limit(p, 0, 255);
} else
if (!strncasecmp(argv[argi], "fuz-name=", p - argv[argi])) {
- fuz_name = strdup(p);
+ fuz_name = options_strdup(p);
} else
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
kennung_fufst = atoi_limit(p, 0, 3);
} else
+ if (!strncasecmp(argv[argi], "bahn-bs=", p - argv[argi])) {
+ bahn_bs = atoi_limit(p, 0, 1);
+ } else
if (!strncasecmp(argv[argi], "auth=", p - argv[argi])) {
authentifikationsbit = atoi_limit(p, 0, 1);
} else
@@ -425,6 +456,12 @@ error_fuz:
futln_sperre_end = atoi(q) & 0xf;
}
} else
+ if (!strncasecmp(argv[argi], "meldeinterval=", p - argv[argi])) {
+ meldeinterval = atoi_limit(p, 1, 20 * 60);
+ } else
+ if (!strncasecmp(argv[argi], "meldeaufrufe=", p - argv[argi])) {
+ meldeaufrufe = atoi_limit(p, 0, 1000000);
+ } else
{
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
return -EINVAL;
@@ -449,10 +486,24 @@ error_fuz:
return 1;
}
+static const struct number_lengths number_lengths[] = {
+ { 7, "regular number format" },
+ { 8, "extended number format" },
+ { 0, NULL }
+};
+
+static const char *number_prefixes[] = {
+ "0161xxxxxxx",
+ "0161xxxxxxxx",
+ "+49161xxxxxxx",
+ "+49161xxxxxxxx",
+ NULL
+};
+
int main(int argc, char *argv[])
{
int rc, argi;
- const char *station_id = "";
+ const char *station_id = NULL;
int mandatory = 0;
int polarity;
int teilnehmergruppensperre = 0;
@@ -466,11 +517,11 @@ int main(int argc, char *argv[])
init_station();
- main_mobile_init();
+ main_mobile_init("0123456789", number_lengths, number_prefixes, cnetz_number_valid);
/* handle options / config file */
add_options();
- rc = options_config_file("~/.osmocom/analog/cnetz.conf", handle_options);
+ rc = options_config_file(argc, argv, "~/.osmocom/analog/cnetz.conf", handle_options);
if (rc < 0)
return 0;
argi = options_command_line(argc, argv, handle_options);
@@ -479,10 +530,9 @@ int main(int argc, char *argv[])
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;
- }
+ rc = main_mobile_number_ask(station_id, "station ID");
+ if (rc)
+ return rc;
}
/* resolve name of base station */
@@ -501,18 +551,16 @@ int main(int argc, char *argv[])
return -EINVAL;
}
}
- /* set or complete name (in case of prefix was given) */
- fuz_name = get_station_name(fuz_nat, fuz_fuvst, fuz_rest);
if (!num_kanal) {
- printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", CNETZ_OGK_KANAL);
+ printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", CNETZ_STD_OGK_KANAL);
mandatory = 1;
}
if (use_sdr) {
- /* set audiodev */
+ /* set device */
for (i = 0; i < num_kanal; i++)
- audiodev[i] = "sdr";
- num_audiodev = num_kanal;
+ dsp_device[i] = "sdr";
+ num_device = num_kanal;
/* set channel types for more than 1 channel */
if (num_kanal > 1 && num_chan_type == 0) {
chan_type[0] = CHAN_TYPE_OGK;
@@ -521,9 +569,9 @@ int main(int argc, char *argv[])
num_chan_type = num_kanal;
}
}
- if (num_kanal == 1 && num_audiodev == 0)
- num_audiodev = 1; /* use default */
- if (num_kanal != num_audiodev) {
+ if (num_kanal == 1 && num_device == 0)
+ num_device = 1; /* use default */
+ if (num_kanal != num_device) {
fprintf(stderr, "You need to specify as many sound devices as you have channels.\n");
exit(0);
}
@@ -556,7 +604,13 @@ int main(int argc, char *argv[])
}
if (anzahl_gesperrter_teilnehmergruppen)
printf("Blocked subscriber with number's last 4 bits from 0x%x to 0x%x\n", teilnehmergruppensperre, (teilnehmergruppensperre + anzahl_gesperrter_teilnehmergruppen - 1) & 0xf);
- init_sysinfo(fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen);
+ switch(timeslots) {
+ case 1: timeslots=0x00000001; break;
+ case 2: timeslots=0x00010001; break;
+ case 4: timeslots=0x01010101; break;
+ default: timeslots=0x11111111;
+ }
+ init_sysinfo(timeslots, fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, bahn_bs, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen, meldeinterval, meldeaufrufe);
dsp_init();
rc = init_telegramm();
if (rc < 0) {
@@ -566,7 +620,7 @@ int main(int argc, char *argv[])
init_coding();
cnetz_init();
- /* check for mandatory OgK */
+ /* check for mandatory standard OgK */
for (i = 0; i < num_kanal; i++) {
if (chan_type[i] == CHAN_TYPE_OGK || chan_type[i] == CHAN_TYPE_OGK_SPK)
break;
@@ -610,7 +664,7 @@ int main(int argc, char *argv[])
polarity = 1; /* positive */
if (!strcmp(flip_polarity, "yes"))
polarity = -1; /* negative */
- if (use_sdr && polarity == 0)
+ if (use_sdr && !flip_polarity[0])
polarity = 1; /* SDR is always positive */
/* demodulation algorithm */
@@ -626,7 +680,7 @@ int main(int argc, char *argv[])
/* create transceiver instance */
for (i = 0; i < num_kanal; i++) {
- rc = cnetz_create(kanal[i], chan_type[i], audiodev[i], use_sdr, demod, samplerate, rx_gain, challenge_valid, challenge, response_valid, response, warteschlange, metering, speech_deviation, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback);
+ rc = cnetz_create(kanal[i], chan_type[i], dsp_device[i], use_sdr, demod, dsp_samplerate, rx_gain, tx_gain, challenge_valid, challenge, response_valid, response, warteschlange, metering, speech_deviation, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback);
if (rc < 0) {
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
goto fail;
@@ -638,7 +692,7 @@ int main(int argc, char *argv[])
}
}
- main_mobile(&quit, latency, interval, NULL, station_id, 7);
+ main_mobile_loop("cnetz", &quit, NULL, station_id);
fail:
flush_db();
@@ -648,8 +702,11 @@ fail:
cnetz_destroy(sender_head);
/* exits */
+ main_mobile_exit();
fm_exit();
+ options_free();
+
return 0;
}
diff --git a/src/cnetz/stations.c b/src/cnetz/stations.c
index 1293cda..4cbe292 100644
--- a/src/cnetz/stations.c
+++ b/src/cnetz/stations.c
@@ -7,2391 +7,2190 @@
/* The list of cell towers is ripped from BSA61 phone's firmware */
static struct cnetz_stations {
- char standort[64];
+ char long_name[32], name[8];
uint8_t nat, fuvst, rest;
- int in1991, in1999;
} cnetz_stations[] = {
-/* Standort Nat FuVST Rest 1991 1999 */
- { "Oberh.32", 1, 2, 1, 0, 1999, },
- { "Oberh. 0", 1, 2, 5, 0, 1999, },
- { "Wupp.18", 1, 2, 6, 0, 1999, },
- { "Oberh.21", 1, 2, 7, 1991, 1999, },
- { "Duisb.21", 1, 2, 8, 1991, 1999, },
- { "Heilighs", 1, 2, 9, 1991, 1999, },
- { "Essen 1", 1, 2, 10, 0, 1999, },
- { "Velb.Lan", 1, 2, 11, 1991, 1999, },
- { "Duisb.40", 1, 2, 12, 1991, 1999, },
- { "Bottrop0", 1, 2, 13, 1991, 1999, },
- { "Gelsenk1", 1, 2, 14, 1991, 1999, },
- { "Essen 35", 1, 2, 15, 1991, 1999, },
- { "Duisb.25", 1, 2, 16, 1991, 1999, },
- { "VelbNev2", 1, 2, 17, 1991, 1999, },
- { "Wupp. 30", 1, 2, 18, 1991, 1999, },
- { "Essen 28", 1, 2, 19, 1991, 1999, },
- { "Kirchhl4", 1, 2, 20, 0, 1999, },
- { "Gelsenk7", 1, 2, 21, 1991, 1999, },
- { "Wupp. 34", 1, 2, 22, 1991, 1999, },
- { "Wupp. 35", 1, 2, 23, 0, 1999, },
- { "Oberh.23", 1, 2, 24, 0, 1999, },
- { "Neviges4", 1, 2, 25, 0, 1999, },
- { "Duisb.42", 1, 2, 26, 0, 1999, },
- { "Rheinhsn", 1, 2, 27, 0, 1999, },
- { "Essen 12", 1, 2, 28, 0, 1999, },
- { "Homberg1", 1, 2, 29, 0, 1999, },
- { "ReesMehr", 1, 2, 30, 0, 1999, },
- { "Essen 13", 1, 2, 31, 1991, 1999, },
- { "Essen 15", 1, 2, 32, 1991, 1999, },
- { "Heiden 1", 1, 2, 33, 0, 1999, },
- { "Voerde 2", 1, 2, 34, 1991, 1999, },
- { "Duisb. 0", 1, 2, 35, 1991, 1999, },
- { "Velbert1", 1, 2, 36, 1991, 1999, },
- { "Oberh.26", 1, 2, 37, 1991, 1999, },
- { "Gelsnk58", 1, 2, 38, 0, 1999, },
- { "Essen 8", 1, 2, 39, 0, 1999, },
- { "Wupp. 8", 1, 2, 40, 0, 1999, },
- { "Oberh.18", 1, 2, 41, 0, 1999, },
- { "Oberh.30", 1, 2, 43, 0, 1999, },
- { "Wesel 0", 1, 2, 44, 0, 1999, },
- { "Borken 0", 1, 2, 45, 0, 1999, },
- { "Velen 20", 1, 2, 46, 0, 1999, },
- { "Bocholt0", 1, 2, 47, 0, 1999, },
- { "Huenxe 1", 1, 2, 48, 0, 1999, },
- { "Isselbg1", 1, 2, 49, 0, 1999, },
- { "EmElten1", 1, 2, 50, 0, 1999, },
- { "Bochum 3", 1, 2, 51, 0, 1999, },
- { "Dorsten0", 1, 2, 52, 0, 1999, },
- { "Schermb2", 1, 2, 53, 0, 1999, },
- { "Raesfeld", 1, 2, 54, 0, 1999, },
- { "Wupp. 4", 1, 2, 55, 0, 1999, },
- { "Hueckwg2", 1, 2, 57, 0, 1999, },
- { "Herne 1", 1, 2, 58, 0, 1999, },
- { "Bochum47", 1, 2, 59, 0, 1999, },
- { "Hattingn", 1, 2, 60, 0, 1999, },
- { "Sprockhv", 1, 2, 61, 0, 1999, },
- { "Gladbk20", 1, 2, 62, 0, 1999, },
- { "Ahaus 0", 1, 2, 63, 0, 1999, },
- { "Bochum 1", 1, 2, 64, 0, 1999, },
- { "Herten", 1, 2, 66, 0, 1999, },
- { "Oberh. 1", 1, 2, 68, 1991, 1999, },
- { "Wulfen 0", 1, 2, 70, 0, 1999, },
- { "Essen0Ke", 1, 2, 76, 1991, 1999, },
- { "Vreden 0", 1, 2, 79, 0, 1999, },
- { "Gronau 0", 1, 2, 81, 0, 1999, },
- { "Dinslak2", 1, 2, 82, 1991, 1999, },
- { "Bochum78", 1, 2, 84, 0, 1999, },
- { "Bochum 0", 1, 2, 88, 0, 1999, },
- { "Ob9 Bake", 1, 2, 89, 1991, 1999, },
- { "Coesfeld", 1, 2, 92, 0, 1999, },
- { "Schoepp1", 1, 2, 93, 0, 1999, },
- { "Stadtloh", 1, 2, 98, 0, 1999, },
- { "Wupp2Bak", 1, 2, 99, 1991, 1999, },
- { "Neuss 10", 2, 2, 1, 0, 1999, },
- { "Dssd57Me", 2, 2, 2, 0, 1999, },
- { "Neuss 7", 2, 2, 4, 0, 1999, },
- { "Ratingn5", 2, 2, 6, 0, 1999, },
- { "Solingn2", 2, 2, 7, 0, 1999, },
- { "Dssd 18", 2, 2, 8, 0, 1999, },
- { "Dssd 58", 2, 2, 9, 0, 1999, },
- { "Neuss 14", 2, 2, 10, 1991, 1999, },
- { "NeussNor", 2, 2, 11, 1991, 1999, },
- { "Dssd 30", 2, 2, 12, 1991, 1999, },
- { "Langenf3", 2, 2, 13, 0, 1999, },
- { "Dssd 75", 2, 2, 14, 0, 1999, },
- { "Mettman7", 2, 2, 15, 0, 1999, },
- { "Dssd 19", 2, 2, 17, 0, 1999, },
- { "Grevenb3", 2, 2, 18, 0, 1999, },
- { "Grevenb2", 2, 2, 19, 0, 1999, },
- { "Ratingn1", 2, 2, 20, 1991, 1999, },
- { "Dssd 40", 2, 2, 22, 0, 1999, },
- { "Neuss 8", 2, 2, 23, 1991, 1999, },
- { "Dssd 4", 2, 2, 24, 1991, 1999, },
- { "Hilden 6", 2, 2, 26, 1991, 1999, },
- { "Dssd 12", 2, 2, 27, 1991, 1999, },
- { "Ratingn3", 2, 2, 29, 0, 1999, },
- { "Remsch.4", 2, 2, 30, 0, 1999, },
- { "Krefeld4", 2, 2, 31, 0, 1999, },
- { "MeerbuL0", 2, 2, 33, 0, 1999, },
- { "Remsch.4", 2, 2, 34, 1991, 0, },
- { "Osterat1", 2, 2, 35, 0, 1999, },
- { "Krefeld5", 2, 2, 36, 0, 1999, },
- { "MeerbuB1", 2, 2, 37, 1991, 1999, },
- { "Dssd 27", 2, 2, 38, 1991, 1999, },
- { "Dssd 53", 2, 2, 39, 1991, 1999, },
- { "Dormag.", 2, 2, 40, 1991, 0, },
- { "Lev.Opl.", 2, 2, 41, 1991, 0, },
- { "Willich1", 2, 2, 42, 0, 1999, },
- { "Solingn1", 2, 2, 43, 1991, 1999, },
- { "Mgl 18", 2, 2, 44, 0, 1999, },
- { "Haan", 2, 2, 45, 0, 1999, },
- { "Krefeld7", 2, 2, 46, 0, 1999, },
- { "Dssd 9", 2, 2, 47, 0, 1999, },
- { "Dssd 2", 2, 2, 49, 0, 1999, },
- { "Langnf89", 2, 2, 52, 0, 1999, },
- { "Mettman2", 2, 2, 66, 1991, 1999, },
- { "Wupp. 23", 2, 2, 78, 0, 1999, },
- { "Dssd10Ba", 2, 2, 88, 1991, 1999, },
- { "Bursche.", 2, 2, 93, 1991, 0, },
- { "Aachen 9", 3, 2, 1, 0, 1999, },
- { "Krefld19", 3, 2, 2, 1991, 1999, },
- { "Mgl 60", 3, 2, 3, 0, 1999, },
- { "Mgl 3", 3, 2, 4, 1991, 1999, },
- { "Viersen4", 3, 2, 5, 1991, 1999, },
- { "Bedburg0", 3, 2, 8, 0, 1999, },
- { "Grev.Ka.", 3, 2, 11, 1991, 0, },
- { "Mgl.Rhy8", 3, 2, 13, 0, 1999, },
- { "Selfkant", 3, 2, 15, 0, 1999, },
- { "WillAnr0", 3, 2, 17, 0, 1999, },
- { "Wuersel2", 3, 2, 19, 0, 1999, },
- { "Mgl 8", 3, 2, 22, 0, 1999, },
- { "Huertgwd", 3, 2, 25, 1991, 0, },
- { "Langerw1", 3, 2, 26, 0, 1999, },
- { "Xanten 1", 3, 2, 27, 1991, 1999, },
- { "Wesel", 3, 2, 28, 1991, 0, },
- { "Kleve 7", 3, 2, 29, 1991, 1999, },
- { "Elten", 3, 2, 30, 1991, 0, },
- { "Geldern0", 3, 2, 31, 1991, 1999, },
- { "Moers 0", 3, 2, 32, 1991, 1999, },
- { "Viersen0", 3, 2, 33, 0, 1999, },
- { "Juechen1", 3, 2, 36, 0, 1999, },
- { "Nettetal", 3, 2, 40, 1991, 1999, },
- { "Viersen1", 3, 2, 42, 1991, 1999, },
- { "Schwalm9", 3, 2, 43, 1991, 1999, },
- { "Juechen4", 3, 2, 44, 1991, 1999, },
- { "MglRhey7", 3, 2, 45, 1991, 1999, },
- { "Stolbg.4", 3, 2, 46, 1991, 1999, },
- { "Stolbg.3", 3, 2, 47, 1991, 0, },
- { "Eschwei2", 3, 2, 48, 1991, 1999, },
- { "Alsdorf3", 3, 2, 49, 1991, 1999, },
- { "AaKornel", 3, 2, 50, 1991, 1999, },
- { "Aachn700", 3, 2, 51, 0, 1999, },
- { "Aachn120", 3, 2, 52, 1991, 1999, },
- { "Aachn500", 3, 2, 53, 1991, 1999, },
- { "Erkelenz", 3, 2, 54, 1991, 1999, },
- { "Schleidn", 3, 2, 56, 1991, 0, },
- { "Geilenk0", 3, 2, 57, 1991, 1999, },
- { "Heinsbg0", 3, 2, 58, 1991, 1999, },
- { "Juelich3", 3, 2, 59, 1991, 1999, },
- { "Simmerat", 3, 2, 61, 1991, 0, },
- { "Nettersh", 3, 2, 62, 1991, 0, },
- { "Kevelaer", 3, 2, 63, 0, 1999, },
- { "Straelen", 3, 2, 64, 1991, 1999, },
- { "NeukVluy", 3, 2, 65, 1991, 1999, },
- { "Bocholt0", 3, 2, 66, 1991, 0, },
- { "Kalkar 7", 3, 2, 67, 0, 1999, },
- { "Krefeld4", 3, 2, 69, 1991, 0, },
- { "Willich", 3, 2, 71, 1991, 0, },
- { "Wegberg", 3, 2, 77, 0, 1999, },
- { "Grev.br.", 3, 2, 79, 1991, 0, },
- { "HerzgRa2", 3, 2, 80, 0, 1999, },
- { "Kevela10", 3, 2, 81, 0, 1999, },
- { "Sonsbeck", 3, 2, 82, 0, 1999, },
- { "Mgl 401", 3, 2, 84, 0, 1999, },
- { "Aachen 1", 3, 2, 86, 1991, 1999, },
- { "Kempen 4", 3, 2, 87, 0, 1999, },
- { "Linnich1", 3, 2, 88, 0, 1999, },
- { "Goch 0", 3, 2, 90, 0, 1999, },
- { "Rheinbg2", 3, 2, 98, 0, 1999, },
- { "Aldenhov", 3, 2, 99, 0, 1999, },
- { "Dtmd3Bak", 4, 2, 1, 1991, 1999, },
- { "Gevelsb.", 4, 2, 12, 1991, 0, },
- { "Hagen 2", 4, 2, 13, 1991, 0, },
- { "Witten12", 4, 2, 14, 1991, 0, },
- { "Bochum 0", 4, 2, 17, 1991, 0, },
- { "Herne 1", 4, 2, 18, 1991, 0, },
- { "Holzwi.", 4, 2, 25, 1991, 0, },
- { "Cast.Ra.", 4, 2, 27, 1991, 0, },
- { "Dortm.10", 4, 2, 28, 1991, 0, },
- { "Lethma.7", 4, 2, 29, 1991, 0, },
- { "Witten10", 4, 2, 31, 1991, 0, },
- { "Luenen 0", 4, 2, 33, 1991, 0, },
- { "Boenen", 4, 2, 34, 1991, 0, },
- { "Iserlohn", 4, 2, 36, 1991, 0, },
- { "Menden11", 4, 2, 37, 1991, 0, },
- { "Kamen", 4, 2, 38, 1991, 0, },
- { "Werne", 4, 2, 39, 1991, 0, },
- { "Hamm", 4, 2, 40, 1991, 0, },
- { "Dtmd-Sc.", 4, 2, 49, 1991, 0, },
- { "Schwerte", 4, 2, 73, 1991, 0, },
- { "Recklhs.", 4, 2, 74, 1991, 0, },
- { "Datteln", 4, 2, 80, 1991, 0, },
- { "Wattensc", 4, 2, 83, 1991, 0, },
- { "Stiepel", 4, 2, 84, 1991, 0, },
- { "Altenbg0", 5, 2, 1, 0, 1999, },
- { "Lennest1", 5, 2, 2, 1991, 1999, },
- { "Attendo7", 5, 2, 3, 1991, 1999, },
- { "Marl 0", 5, 2, 4, 1991, 0, },
- { "NeheimH7", 5, 2, 5, 1991, 1999, },
- { "Muenst42", 5, 2, 6, 1991, 1999, },
- { "Marsberg", 5, 2, 7, 0, 1999, },
- { "Lippst.0", 5, 2, 8, 1991, 1999, },
- { "Roelvede", 5, 2, 9, 0, 1999, },
- { "Mesched7", 5, 2, 10, 0, 1999, },
- { "Hallenb7", 5, 2, 11, 0, 1999, },
- { "Soest 10", 5, 2, 12, 0, 1999, },
- { "Schalksm", 5, 2, 13, 0, 1999, },
- { "Olsberg7", 5, 2, 14, 0, 1999, },
- { "Ostbever", 5, 2, 15, 0, 1999, },
- { "Arnsberg", 5, 2, 16, 0, 1999, },
- { "Beckum 3", 5, 2, 17, 1991, 1999, },
- { "Sendenh", 5, 2, 18, 1991, 1999, },
- { "Altena 8", 5, 2, 19, 0, 1999, },
- { "Ahlen 0", 5, 2, 20, 0, 1999, },
- { "Luedinh2", 5, 2, 21, 1991, 1999, },
- { "Mesched1", 5, 2, 22, 1991, 1999, },
- { "Werl 0", 5, 2, 23, 1991, 1999, },
- { "Moehnese", 5, 2, 24, 1991, 1999, },
- { "SchmBoed", 5, 2, 25, 1991, 1999, },
- { "Winterbg", 5, 2, 26, 1991, 1999, },
- { "CastRaux", 5, 2, 27, 0, 1999, },
- { "MSNienbe", 5, 2, 28, 0, 1999, },
- { "Letmathe", 5, 2, 29, 0, 1999, },
- { "Lueden.2", 5, 2, 30, 1991, 1999, },
- { "Witten10", 5, 2, 31, 1991, 1999, },
- { "Meinerzh", 5, 2, 32, 1991, 1999, },
- { "Luenen 0", 5, 2, 33, 1991, 1999, },
- { "Plettenb", 5, 2, 34, 1991, 1999, },
- { "Werdohl7", 5, 2, 35, 1991, 1999, },
- { "Nottuln2", 5, 2, 36, 1991, 1999, },
- { "Telgte 0", 5, 2, 37, 1991, 1999, },
- { "Ruethen0", 5, 2, 38, 0, 1999, },
- { "Emsdettn", 5, 2, 39, 0, 1999, },
- { "OeldeStr", 5, 2, 40, 1991, 1999, },
- { "MSAlbach", 5, 2, 41, 1991, 1999, },
- { "Coesfeld", 5, 2, 42, 1991, 0, },
- { "Greven 0", 5, 2, 43, 1991, 1999, },
- { "Brechten", 5, 2, 44, 1991, 1999, },
- { "Dorlar 1", 5, 2, 45, 0, 1999, },
- { "Halver 6", 5, 2, 46, 0, 1999, },
- { "Herschd3", 5, 2, 47, 0, 1999, },
- { "Dtmd.230", 5, 2, 49, 0, 1999, },
- { "Aschebg2", 5, 2, 50, 0, 1999, },
- { "Warendf0", 5, 2, 51, 0, 1999, },
- { "Gevelsb7", 5, 2, 52, 0, 1999, },
- { "Duelmen0", 5, 2, 54, 0, 1999, },
- { "Sundern1", 5, 2, 55, 1991, 1999, },
- { "Bueren 1", 5, 2, 56, 1991, 1999, },
- { "Bril.Mes", 5, 2, 57, 1991, 1999, },
- { "Dtmd. 10", 5, 2, 58, 0, 1999, },
- { "Witten91", 5, 2, 59, 0, 1999, },
- { "Unna 3", 5, 2, 60, 0, 1999, },
- { "HagnDahl", 5, 2, 61, 0, 1999, },
- { "Haltern7", 5, 2, 62, 0, 1999, },
- { "Herdecke", 5, 2, 63, 0, 1999, },
- { "Boenen 0", 5, 2, 64, 0, 1999, },
- { "Holzwick", 5, 2, 65, 0, 1999, },
- { "Hamm 1", 5, 2, 66, 0, 1999, },
- { "Menden11", 5, 2, 67, 0, 1999, },
- { "Kamen 0", 5, 2, 68, 0, 1999, },
- { "Werne 0", 5, 2, 69, 0, 1999, },
- { "Waltrop1", 5, 2, 70, 0, 1999, },
- { "HammUent", 5, 2, 71, 0, 1999, },
- { "Hagen 2", 5, 2, 72, 0, 1999, },
- { "Schwert4", 5, 2, 73, 0, 1999, },
- { "Recklhs1", 5, 2, 74, 0, 1999, },
- { "Breckerf", 5, 2, 75, 0, 1999, },
- { "Balve 7", 5, 2, 76, 0, 1999, },
- { "Gevelsb5", 5, 2, 77, 0, 1999, },
- { "Dtmd. 85", 5, 2, 78, 0, 1999, },
- { "Iserlo13", 5, 2, 79, 0, 1999, },
- { "Datteln3", 5, 2, 80, 0, 1999, },
- { "Haltern2", 5, 2, 84, 0, 1999, },
- { "Hagen 9", 5, 2, 85, 0, 1999, },
- { "Witten12", 5, 2, 87, 0, 1999, },
- { "Schoepp.", 5, 2, 93, 1991, 0, },
- { "Herschd1", 5, 2, 94, 1991, 1999, },
- { "Marl 0", 5, 2, 96, 0, 1999, },
- { "Frechen0", 6, 2, 1, 0, 1999, },
- { "Kln35Mes", 6, 2, 2, 0, 1999, },
- { "BergGld4", 6, 2, 3, 0, 1999, },
- { "Niedkass", 6, 2, 4, 1991, 1999, },
- { "Kln 0", 6, 2, 5, 1991, 1999, },
- { "Kln 8 Ba", 6, 2, 6, 1991, 1999, },
- { "Bonn 460", 6, 2, 7, 0, 1999, },
- { "Kln 27", 6, 2, 8, 1991, 1999, },
- { "Merten 1", 6, 2, 9, 1991, 1999, },
- { "Frechen8", 6, 2, 10, 0, 1999, },
- { "KerpHorr", 6, 2, 11, 0, 1999, },
- { "Erftstad", 6, 2, 12, 1991, 1999, },
- { "Kln 34", 6, 2, 13, 0, 1999, },
- { "Pulheim0", 6, 2, 14, 1991, 1999, },
- { "KlnPrz50", 6, 2, 15, 1991, 1999, },
- { "Bergheim", 6, 2, 16, 1991, 1999, },
- { "Kln 860", 6, 2, 17, 0, 1999, },
- { "KwtObpl1", 6, 2, 18, 0, 1999, },
- { "Siegb.70", 6, 2, 19, 0, 1999, },
- { "Rommersk", 6, 2, 20, 1991, 0, },
- { "BergGld2", 6, 2, 21, 1991, 1999, },
- { "Kln 170", 6, 2, 22, 1991, 1999, },
- { "Kln 25", 6, 2, 23, 1991, 1999, },
- { "Kln 370", 6, 2, 24, 1991, 1999, },
- { "Kln 430", 6, 2, 25, 1991, 1999, },
- { "Kln 760", 6, 2, 26, 1991, 1999, },
- { "Kln 640", 6, 2, 27, 1991, 1999, },
- { "Kln 28", 6, 2, 28, 1991, 1999, },
- { "Bruehl99", 6, 2, 29, 1991, 1999, },
- { "KerpVill", 6, 2, 30, 0, 1999, },
- { "Kln 350", 6, 2, 31, 0, 1999, },
- { "Bonn 0", 6, 2, 33, 0, 1999, },
- { "Bonn 320", 6, 2, 34, 0, 1999, },
- { "Bonn 620", 6, 2, 35, 0, 1999, },
- { "Bonn 670", 6, 2, 36, 0, 1999, },
- { "Siegb.41", 6, 2, 37, 0, 1999, },
- { "Siegb.20", 6, 2, 38, 0, 1999, },
- { "Lohmar 2", 6, 2, 39, 0, 1999, },
- { "Siegb.0", 6, 2, 40, 0, 1999, },
- { "Lohmar 1", 6, 2, 41, 0, 1999, },
- { "Bonn 13", 6, 2, 42, 0, 1999, },
- { "Dueren30", 6, 2, 43, 0, 1999, },
- { "Heimbach", 6, 2, 44, 0, 1999, },
- { "Huertgw4", 6, 2, 45, 0, 1999, },
- { "KerpBuir", 6, 2, 46, 0, 1999, },
- { "Monschau", 6, 2, 47, 0, 1999, },
- { "Hennef 1", 6, 2, 48, 0, 1999, },
- { "Nideggen", 6, 2, 49, 0, 1999, },
- { "Zuelpich", 6, 2, 50, 0, 1999, },
- { "Rheinba2", 6, 2, 51, 0, 1999, },
- { "Euskir.4", 6, 2, 52, 0, 1999, },
- { "WeilersW", 6, 2, 53, 0, 1999, },
- { "BadMstEi", 6, 2, 54, 0, 1999, },
- { "Mechern4", 6, 2, 55, 0, 1999, },
- { "Schleid1", 6, 2, 56, 0, 1999, },
- { "KwtObpl0", 6, 2, 57, 0, 1999, },
- { "Noerveni", 6, 2, 58, 0, 1999, },
- { "Dormagn7", 6, 2, 60, 0, 1999, },
- { "Simmerat", 6, 2, 61, 0, 1999, },
- { "Nettersh", 6, 2, 62, 0, 1999, },
- { "SchlGem3", 6, 2, 63, 0, 1999, },
- { "Wermelsk", 6, 2, 64, 0, 1999, },
- { "Bursch.3", 6, 2, 65, 0, 1999, },
- { "Wesseli0", 6, 2, 66, 1991, 1999, },
- { "Huerth 0", 6, 2, 67, 1991, 1999, },
- { "Roesrat2", 6, 2, 68, 1991, 1999, },
- { "Bursch10", 6, 2, 69, 0, 1999, },
- { "Kln 23", 6, 2, 70, 1991, 1999, },
- { "Dormagen", 6, 2, 71, 0, 1999, },
- { "Bonn 2", 6, 2, 72, 0, 1999, },
- { "RommersK", 6, 2, 73, 0, 1999, },
- { "Bonn 630", 6, 2, 76, 0, 1999, },
- { "Bensberg", 6, 2, 78, 1991, 1999, },
- { "Frechen", 6, 2, 81, 1991, 0, },
- { "Leverk0", 6, 2, 91, 1991, 1999, },
- { "Overath5", 7, 2, 1, 1991, 1999, },
- { "Dierdorf", 7, 2, 2, 1991, 1999, },
- { "Koen./Ob", 7, 2, 3, 1991, 0, },
- { "Daun_4", 7, 2, 4, 1991, 1999, },
- { "Much 1", 7, 2, 6, 0, 1999, },
- { "Saffig10", 7, 2, 7, 1991, 1999, },
- { "GummBa40", 7, 2, 8, 0, 1999, },
- { "Asbach10", 7, 2, 9, 0, 1999, },
- { "Eitorf 2", 7, 2, 10, 0, 1999, },
- { "Windhgn", 7, 2, 11, 1991, 1999, },
- { "BdHonn80", 7, 2, 12, 1991, 1999, },
- { "Nuembr10", 7, 2, 13, 1991, 1999, },
- { "Kobl. 10", 7, 2, 14, 1991, 1999, },
- { "HoehrGre", 7, 2, 15, 1991, 1999, },
- { "Montab.3", 7, 2, 16, 0, 1999, },
- { "Vettels.", 7, 2, 17, 1991, 0, },
- { "Weibern2", 7, 2, 18, 1991, 1999, },
- { "BdMarie1", 7, 2, 19, 1991, 1999, },
- { "BdBertri", 7, 2, 20, 1991, 1999, },
- { "BlankeA5", 7, 2, 21, 0, 1999, },
- { "Wissen 2", 7, 2, 22, 0, 1999, },
- { "Betzdorf", 7, 2, 23, 1991, 1999, },
- { "Eschenb.", 7, 2, 24, 1991, 0, },
- { "Wendn186", 7, 2, 26, 0, 1999, },
- { "Puderb.3", 7, 2, 28, 0, 1999, },
- { "Kuerten3", 7, 2, 30, 1991, 1999, },
- { "BdHonn.0", 7, 2, 31, 1991, 1999, },
- { "Euskir.4", 7, 2, 32, 1991, 0, },
- { "Wipperf2", 7, 2, 33, 0, 1999, },
- { "Kuerten1", 7, 2, 34, 1991, 1999, },
- { "GummBa.0", 7, 2, 35, 0, 1999, },
- { "Bonn 670", 7, 2, 36, 1991, 0, },
- { "Windeck2", 7, 2, 37, 1991, 1999, },
- { "BdNeuena", 7, 2, 38, 1991, 1999, },
- { "Linz 4", 7, 2, 39, 0, 1999, },
- { "Lennestd", 7, 2, 40, 1991, 0, },
- { "Kreuztal", 7, 2, 41, 1991, 1999, },
- { "Bonn 13", 7, 2, 42, 1991, 0, },
- { "BdBerleb", 7, 2, 43, 1991, 1999, },
- { "BdLaasph", 7, 2, 44, 0, 1999, },
- { "Nethphen", 7, 2, 45, 0, 1999, },
- { "Olpe 0", 7, 2, 47, 0, 1999, },
- { "DrolshgB", 7, 2, 48, 0, 1999, },
- { "Hilchenb", 7, 2, 49, 0, 1999, },
- { "Freudnbg", 7, 2, 50, 0, 1999, },
- { "Burbach3", 7, 2, 51, 0, 1999, },
- { "WaldbrBd", 7, 2, 52, 0, 1999, },
- { "EllenzP2", 7, 2, 53, 0, 1999, },
- { "Insul 2", 7, 2, 54, 0, 1999, },
- { "Linz 2", 7, 2, 55, 0, 1999, },
- { "WildbgH1", 7, 2, 56, 0, 1999, },
- { "Kelberg3", 7, 2, 57, 0, 1999, },
- { "Kesseli1", 7, 2, 58, 0, 1999, },
- { "Eckenh.3", 7, 2, 59, 0, 1999, },
- { "Rengsdf4", 7, 2, 60, 0, 1999, },
- { "Mendig 3", 7, 2, 61, 0, 1999, },
- { "Cochem 1", 7, 2, 62, 0, 1999, },
- { "Mayen 3", 7, 2, 63, 0, 1999, },
- { "Neuwied2", 7, 2, 64, 0, 1999, },
- { "Hachenbg", 7, 2, 65, 0, 1999, },
- { "Westerbg", 7, 2, 66, 0, 1999, },
- { "Asbach 5", 7, 2, 67, 0, 1999, },
- { "Loef 1", 7, 2, 68, 0, 1999, },
- { "Engelsk6", 7, 2, 69, 0, 1999, },
- { "Altenki0", 7, 2, 70, 0, 1999, },
- { "Siegen15", 7, 2, 71, 0, 1999, },
- { "Bonn 2 K", 7, 2, 72, 1991, 0, },
- { "NeunkSe1", 7, 2, 73, 0, 1999, },
- { "Ochtend2", 7, 2, 74, 0, 1999, },
- { "Weilers.", 7, 2, 77, 1991, 0, },
- { "Bad Ems1", 7, 2, 79, 0, 1999, },
- { "Marienh1", 7, 2, 80, 0, 1999, },
- { "GummBa16", 7, 2, 82, 0, 1999, },
- { "FlammerF", 7, 2, 83, 0, 1999, },
- { "Waldbro1", 7, 2, 84, 0, 1999, },
- { "Bendorf1", 7, 2, 85, 0, 1999, },
- { "Engelsk3", 7, 2, 86, 0, 1999, },
- { "Selters2", 7, 2, 87, 0, 1999, },
- { "Adenau 7", 7, 2, 88, 0, 1999, },
- { "KaisEsch", 7, 2, 89, 0, 1999, },
- { "Nassau 1", 7, 2, 90, 0, 1999, },
- { "BdMarie2", 7, 2, 91, 0, 1999, },
- { "Antweil1", 7, 2, 92, 0, 1999, },
- { "Ruppich3", 7, 2, 93, 0, 1999, },
- { "Lindlar1", 7, 2, 95, 0, 1999, },
- { "Siegen 1", 7, 2, 96, 1991, 1999, },
- { "GummBa13", 7, 2, 97, 1991, 1999, },
- { "Lohmar 1", 7, 2, 98, 1991, 0, },
- { "Rheinbr0", 7, 2, 99, 0, 1999, },
- { "Raegelin", 1, 3, 1, 1991, 1999, },
- { "Rostock", 1, 3, 2, 1991, 0, },
- { "Fuerstnb", 1, 3, 3, 1991, 1999, },
- { "Massow", 1, 3, 4, 1991, 1999, },
- { "Beeskow", 1, 3, 5, 0, 1999, },
- { "Finowfur", 1, 3, 6, 0, 1999, },
- { "Bernau 6", 1, 3, 7, 0, 1999, },
- { "Ziesar 0", 1, 3, 8, 1991, 1999, },
- { "Wittenbg", 1, 3, 9, 1991, 1999, },
- { "WerderHv", 1, 3, 10, 1991, 1999, },
- { "Seelow 0", 1, 3, 11, 1991, 1999, },
- { "Tresebur", 1, 3, 12, 0, 1999, },
- { "Briesen", 1, 3, 13, 0, 1999, },
- { "Perlebg5", 1, 3, 14, 0, 1999, },
- { "Mnchebg4", 1, 3, 15, 0, 1999, },
- { "Herzfeld", 1, 3, 16, 0, 1999, },
- { "Storkow4", 1, 3, 17, 0, 1999, },
- { "Neubra14", 1, 3, 18, 0, 1999, },
- { "Treuenbr", 1, 3, 19, 0, 1999, },
- { "Prenzlau", 1, 3, 20, 0, 1999, },
- { "Pasewalk", 1, 3, 22, 0, 1999, },
- { "NaumbgRi", 1, 3, 23, 0, 1999, },
- { "Ratheno4", 1, 3, 24, 0, 1999, },
- { "BApitzSt", 1, 3, 26, 0, 1999, },
- { "Jaegerst", 1, 3, 27, 0, 1999, },
- { "Templin2", 1, 3, 28, 0, 1999, },
- { "Luckenw2", 1, 3, 29, 0, 1999, },
- { "Lehnin 0", 1, 3, 30, 0, 1999, },
- { "Frankf10", 1, 3, 31, 0, 1999, },
- { "Michendf", 1, 3, 32, 0, 1999, },
- { "Trebbin2", 1, 3, 33, 0, 1999, },
- { "Gramzow0", 1, 3, 35, 0, 1999, },
- { "BdFreien", 1, 3, 36, 0, 1999, },
- { "Falknhg4", 1, 3, 37, 0, 1999, },
- { "Fuerstw7", 1, 3, 38, 0, 1999, },
- { "Angermue", 1, 3, 39, 0, 1999, },
- { "Wittsto5", 1, 3, 40, 0, 1999, },
- { "Dambeck2", 1, 3, 41, 0, 1999, },
- { "Neuzelle", 1, 3, 42, 0, 1999, },
- { "Raben 1", 1, 3, 43, 0, 1999, },
- { "Toepchin", 1, 3, 44, 0, 1999, },
- { "Brandenb", 1, 3, 45, 0, 1999, },
- { "Jueterbo", 1, 3, 46, 0, 1999, },
- { "Krahne", 1, 3, 47, 0, 1999, },
- { "Lieberos", 1, 3, 48, 0, 1999, },
- { "Wiesenbu", 1, 3, 49, 0, 1999, },
- { "Mirow 1", 1, 3, 50, 0, 1999, },
- { "Rhinow 1", 1, 3, 51, 0, 1999, },
- { "Rheinsb3", 1, 3, 52, 0, 1999, },
- { "Petkus 3", 1, 3, 53, 0, 1999, },
- { "Blanken1", 1, 3, 54, 0, 1999, },
- { "Neustrel", 1, 3, 55, 0, 1999, },
- { "Greiffen", 1, 3, 57, 0, 1999, },
- { "Pritzwal", 1, 3, 58, 0, 1999, },
- { "Schwedt6", 1, 3, 59, 0, 1999, },
- { "Schmoell", 1, 3, 62, 0, 1999, },
- { "Woldegk4", 1, 3, 65, 0, 1999, },
- { "Neurupp6", 1, 3, 66, 0, 1999, },
- { "Belzig 2", 1, 3, 67, 0, 1999, },
- { "Gransee1", 1, 3, 69, 0, 1999, },
- { "Kyritz 4", 1, 3, 70, 0, 1999, },
- { "GrDoelln", 1, 3, 71, 0, 1999, },
- { "Premnitz", 1, 3, 72, 0, 1999, },
- { "Gloewen2", 1, 3, 73, 0, 1999, },
- { "Luebben2", 1, 3, 74, 0, 1999, },
- { "Bestense", 1, 3, 76, 0, 1999, },
- { "Pausin 1", 1, 3, 77, 0, 1999, },
- { "Golssen0", 1, 3, 78, 0, 1999, },
- { "Luebenau", 1, 3, 79, 0, 1999, },
- { "AltMahls", 1, 3, 80, 0, 1999, },
- { "Eichhors", 1, 3, 81, 0, 1999, },
- { "Muehlnbk", 1, 3, 83, 0, 1999, },
- { "Hennings", 1, 3, 84, 0, 1999, },
- { "Ludwigsf", 1, 3, 86, 0, 1999, },
- { "Ruedersd", 1, 3, 87, 0, 1999, },
- { "Strausbg", 1, 3, 88, 0, 1999, },
- { "Zossen", 1, 3, 89, 0, 1999, },
- { "Mahlow 4", 1, 3, 90, 0, 1999, },
- { "Bernau 3", 1, 3, 91, 0, 1999, },
- { "Oranienb", 1, 3, 92, 0, 1999, },
- { "Falkense", 1, 3, 93, 0, 1999, },
- { "Liebenwa", 1, 3, 94, 0, 1999, },
- { "Eberswal", 1, 3, 96, 0, 1999, },
- { "Erkner 5", 1, 3, 97, 0, 1999, },
- { "KWusterh", 1, 3, 98, 0, 1999, },
- { "Fichtenw", 1, 3, 99, 0, 1999, },
- { "B23 Bake", 2, 3, 1, 1991, 1999, },
- { "Schoenho", 2, 3, 2, 1991, 1999, },
- { "Ruegener", 2, 3, 3, 1991, 1999, },
- { "Habersaa", 2, 3, 4, 1991, 1999, },
- { "Stresema", 2, 3, 5, 1991, 1999, },
- { "Wilkestr", 2, 3, 6, 1991, 1999, },
- { "Skalitze", 2, 3, 7, 1991, 1999, },
- { "Luederit", 2, 3, 8, 1991, 1999, },
- { "Erasmuss", 2, 3, 9, 1991, 1999, },
- { "Winterfe", 2, 3, 10, 1991, 1999, },
- { "Wernerwe", 2, 3, 11, 1991, 1999, },
- { "KMarxStr", 2, 3, 12, 1991, 1999, },
- { "Oranienb", 2, 3, 13, 1991, 1999, },
- { "AugustVi", 2, 3, 14, 1991, 1999, },
- { "Rathauss", 2, 3, 15, 1991, 1999, },
- { "Schmarge", 2, 3, 16, 1991, 1999, },
- { "Tempelho", 2, 3, 17, 1991, 1999, },
- { "Hanneman", 2, 3, 18, 1991, 1999, },
- { "Streitst", 2, 3, 19, 1991, 1999, },
- { "Kettinge", 2, 3, 20, 1991, 1999, },
- { "Forststr", 2, 3, 21, 1991, 1999, },
- { "Hindenbu", 2, 3, 22, 1991, 1999, },
- { "Lobeckst", 2, 3, 23, 1991, 1999, },
- { "AltStral", 2, 3, 24, 0, 1999, },
- { "Schaefer", 2, 3, 25, 0, 1999, },
- { "Elsastr", 2, 3, 28, 0, 1999, },
- { "FranzJac", 2, 3, 29, 1991, 1999, },
- { "Schnellr", 2, 3, 30, 0, 1999, },
- { "KoepeniA", 2, 3, 31, 0, 1999, },
- { "Amanlisw", 2, 3, 32, 0, 1999, },
- { "BitterSt", 2, 3, 33, 0, 1999, },
- { "ErnstBar", 2, 3, 34, 0, 1999, },
- { "Flankens", 2, 3, 35, 0, 1999, },
- { "LilliHen", 2, 3, 36, 1991, 1999, },
- { "Buchholz", 2, 3, 37, 0, 1999, },
- { "RudowChs", 2, 3, 38, 0, 1999, },
- { "OGeschke", 2, 3, 39, 0, 1999, },
- { "Rochstr", 2, 3, 40, 1991, 1999, },
- { "EReuterP", 2, 3, 41, 0, 1999, },
- { "Birkholz", 2, 3, 44, 1991, 0, },
- { "Schoenef", 2, 3, 48, 0, 1999, },
- { "Coppistr", 2, 3, 49, 1991, 1999, },
- { "Prenzlau", 2, 3, 57, 1991, 1999, },
- { "Lieberma", 2, 3, 58, 1991, 1999, },
- { "Herzberg", 2, 3, 59, 1991, 1999, },
- { "Masurena", 2, 3, 60, 1991, 1999, },
- { "Scholzpl", 2, 3, 61, 1991, 1999, },
- { "Flotowst", 2, 3, 64, 0, 1999, },
- { "Breitest", 2, 3, 65, 0, 1999, },
- { "KMarxAle", 2, 3, 70, 0, 1999, },
- { "AVUS", 2, 3, 95, 0, 1999, },
- { "Kaatsch1", 2, 3, 97, 1991, 1999, },
- { "Kaatsch2", 2, 3, 98, 1991, 1999, },
- { "B.Schaef", 2, 3, 99, 1991, 0, },
- { "Teicha 2", 3, 3, 1, 1991, 1999, },
- { "Greifenh", 3, 3, 2, 0, 1999, },
- { "Mrkranst", 3, 3, 4, 0, 1999, },
- { "Groitsch", 3, 3, 6, 0, 1999, },
- { "Graefenh", 3, 3, 7, 0, 1999, },
- { "Liebertw", 3, 3, 8, 0, 1999, },
- { "Torgau 4", 3, 3, 9, 0, 1999, },
- { "Bitterf", 3, 3, 10, 0, 1999, },
- { "Oschatz", 3, 3, 11, 0, 1999, },
- { "L-Sttz", 3, 3, 12, 0, 1999, },
- { "Halle 15", 3, 3, 13, 0, 1999, },
- { "Grimma 6", 3, 3, 14, 0, 1999, },
- { "Weissenf", 3, 3, 15, 0, 1999, },
- { "L-Uni", 3, 3, 16, 0, 1999, },
- { "L-Doelz", 3, 3, 17, 0, 1999, },
- { "L-Gaschw", 3, 3, 18, 0, 1999, },
- { "L-Lausen", 3, 3, 19, 0, 1999, },
- { "L-Seehsn", 3, 3, 20, 0, 1999, },
- { "L-Schkeu", 3, 3, 21, 0, 1999, },
- { "Koethen8", 3, 3, 22, 0, 1999, },
- { "Brandis2", 3, 3, 23, 0, 1999, },
- { "Delitzs1", 3, 3, 24, 0, 1999, },
- { "L-Holz", 3, 3, 25, 0, 1999, },
- { "Nebra 3", 3, 3, 26, 0, 1999, },
- { "Zeitz 9", 3, 3, 27, 0, 1999, },
- { "Querfurt", 3, 3, 28, 0, 1999, },
- { "Cobbelsd", 3, 3, 36, 0, 1999, },
- { "L-Stahm", 3, 3, 37, 0, 1999, },
- { "Altenbrg", 3, 3, 38, 0, 1999, },
- { "L-Connew", 3, 3, 40, 0, 1999, },
- { "L-Taucha", 3, 3, 41, 0, 1999, },
- { "L-Eutri", 3, 3, 42, 0, 1999, },
- { "L-Schoen", 3, 3, 43, 0, 1999, },
- { "Dommitz1", 3, 3, 44, 0, 1999, },
- { "L-Adler", 3, 3, 45, 0, 1999, },
- { "Naumburg", 3, 3, 46, 0, 1999, },
- { "L-Gohlis", 3, 3, 47, 0, 1999, },
- { "H-Seeben", 3, 3, 48, 0, 1999, },
- { "Sangerh", 3, 3, 49, 0, 1999, },
- { "H-Bruckd", 3, 3, 50, 0, 1999, },
- { "Colditz", 3, 3, 52, 0, 1999, },
- { "Hartha 1", 3, 3, 56, 0, 1999, },
- { "Dessau S", 3, 3, 58, 0, 1999, },
- { "Eisleben", 3, 3, 59, 0, 1999, },
- { "H-Teutsc", 3, 3, 60, 0, 1999, },
- { "H-Silber", 3, 3, 61, 0, 1999, },
- { "H-Neu", 3, 3, 62, 0, 1999, },
- { "Mersebrg", 3, 3, 63, 0, 1999, },
- { "Schmoell", 3, 3, 70, 0, 1999, },
- { "Eilenbrg", 3, 3, 71, 0, 1999, },
- { "Hayn 2", 3, 3, 72, 0, 1999, },
- { "Dessau 1", 3, 3, 73, 0, 1999, },
- { "Borna 0", 3, 3, 74, 0, 1999, },
- { "Belgern", 3, 3, 75, 0, 1999, },
- { "Hettstdt", 3, 3, 76, 0, 1999, },
- { "BDueben5", 3, 3, 77, 0, 1999, },
- { "H-Peiss", 3, 3, 78, 0, 1999, },
- { "H-Heide", 3, 3, 79, 0, 1999, },
- { "Oelzsch1", 3, 3, 80, 0, 1999, },
- { "Doebeln", 3, 3, 81, 0, 1999, },
- { "Coswig A", 3, 3, 82, 0, 1999, },
- { "Mockreh", 3, 3, 83, 0, 1999, },
- { "L-Leutsc", 3, 3, 84, 0, 1999, },
- { "Hohenmoe", 3, 3, 85, 0, 1999, },
- { "Wittenbg", 3, 3, 86, 0, 1999, },
- { "BdDuerrn", 3, 3, 87, 0, 1999, },
- { "Kropstd", 3, 3, 88, 0, 1999, },
- { "L-Markle", 3, 3, 89, 0, 1999, },
- { "D-Gompi", 4, 3, 1, 1991, 1999, },
- { "Crinitz", 4, 3, 2, 0, 1999, },
- { "D-Dachs", 4, 3, 3, 0, 1999, },
- { "Weisswas", 4, 3, 4, 0, 1999, },
- { "Drebkau1", 4, 3, 5, 0, 1999, },
- { "Senftenb", 4, 3, 7, 0, 1999, },
- { "Radeburg", 4, 3, 8, 0, 1999, },
- { "Meissen5", 4, 3, 9, 0, 1999, },
- { "Pirna 7", 4, 3, 10, 0, 1999, },
- { "Koenigsw", 4, 3, 11, 0, 1999, },
- { "D-Radeb", 4, 3, 12, 0, 1999, },
- { "D-Postpl", 4, 3, 13, 0, 1999, },
- { "Pulsnitz", 4, 3, 14, 0, 1999, },
- { "Loebau 5", 4, 3, 15, 0, 1999, },
- { "Neukirch", 4, 3, 16, 0, 1999, },
- { "Nst-Ung", 4, 3, 17, 0, 1999, },
- { "Goerlitz", 4, 3, 18, 0, 1999, },
- { "Zittau 5", 4, 3, 19, 0, 1999, },
- { "Altenbg", 4, 3, 20, 0, 1999, },
- { "Riesa 4", 4, 3, 21, 0, 1999, },
- { "Burkau 2", 4, 3, 22, 0, 1999, },
- { "D-Goenns", 4, 3, 23, 0, 1999, },
- { "Jessen 2", 4, 3, 24, 0, 1999, },
- { "Dippold", 4, 3, 25, 0, 1999, },
- { "D-Heiden", 4, 3, 26, 0, 1999, },
- { "Hoyersw", 4, 3, 27, 0, 1999, },
- { "D-Goppel", 4, 3, 28, 0, 1999, },
- { "D-Dorfh", 4, 3, 29, 0, 1999, },
- { "D-Stries", 4, 3, 30, 0, 1999, },
- { "Elsterw5", 4, 3, 31, 0, 1999, },
- { "Sprembg", 4, 3, 33, 0, 1999, },
- { "D-Klotzs", 4, 3, 34, 0, 1999, },
- { "Herzberg", 4, 3, 35, 0, 1999, },
- { "D-Prohli", 4, 3, 36, 0, 1999, },
- { "Niesky 4", 4, 3, 37, 0, 1999, },
- { "D-Neust", 4, 3, 39, 0, 1999, },
- { "Burkhard", 4, 3, 40, 0, 1999, },
- { "Guben 2", 4, 3, 41, 0, 1999, },
- { "Bautzen", 4, 3, 42, 0, 1999, },
- { "BdSchand", 4, 3, 43, 0, 1999, },
- { "Forst 2", 4, 3, 44, 0, 1999, },
- { "Bischofw", 4, 3, 45, 0, 1999, },
- { "Cottbus8", 4, 3, 46, 0, 1999, },
- { "Ortrand", 4, 3, 47, 0, 1999, },
- { "Tharandt", 4, 3, 48, 0, 1999, },
- { "Drachhau", 4, 3, 49, 0, 1999, },
- { "Kamenz 5", 4, 3, 51, 0, 1999, },
- { "Grossenh", 4, 3, 52, 0, 1999, },
- { "Lommatz", 4, 3, 54, 0, 1999, },
- { "Pirna 5", 4, 3, 55, 0, 1999, },
- { "Glashuet", 4, 3, 56, 0, 1999, },
- { "Coswig 4", 4, 3, 57, 0, 1999, },
- { "Wilsdruf", 4, 3, 59, 0, 1999, },
- { "Finster3", 4, 3, 60, 0, 1999, },
- { "Neugersd", 4, 3, 61, 0, 1999, },
- { "Uhyst 1", 4, 3, 64, 0, 1999, },
- { "Pulsnit6", 4, 3, 66, 0, 1999, },
- { "Doberlug", 4, 3, 88, 0, 1999, },
- { "Klettb", 5, 3, 1, 1991, 1999, },
- { "Grossfa1", 5, 3, 2, 1991, 1999, },
- { "Zella-Me", 5, 3, 3, 1991, 1999, },
- { "Juechsen", 5, 3, 4, 1991, 1999, },
- { "Grossbr", 5, 3, 5, 1991, 1999, },
- { "Eisenb 6", 5, 3, 6, 0, 1999, },
- { "Schleusi", 5, 3, 7, 0, 1999, },
- { "Eisenbg4", 5, 3, 8, 0, 1999, },
- { "Gera 11", 5, 3, 9, 0, 1999, },
- { "H.Reuth", 5, 3, 10, 0, 1999, },
- { "Jena 5", 5, 3, 11, 0, 1999, },
- { "N-Kleina", 5, 3, 12, 0, 1999, },
- { "Saalburg", 5, 3, 13, 0, 1999, },
- { "Jena 6", 5, 3, 14, 0, 1999, },
- { "Ruhla 4", 5, 3, 15, 0, 1999, },
- { "Creuzbrg", 5, 3, 16, 0, 1999, },
- { "Nordhsn", 5, 3, 17, 0, 1999, },
- { "Camburg", 5, 3, 18, 0, 1999, },
- { "BdFranke", 5, 3, 19, 0, 1999, },
- { "Gera 13", 5, 3, 20, 0, 1999, },
- { "Sondersh", 5, 3, 21, 0, 1999, },
- { "Hermsdf", 5, 3, 22, 0, 1999, },
- { "Weimar14", 5, 3, 23, 0, 1999, },
- { "E-Schwer", 5, 3, 24, 0, 1999, },
- { "Arnsger", 5, 3, 25, 0, 1999, },
- { "Arnstadt", 5, 3, 26, 0, 1999, },
- { "Suhl 2", 5, 3, 27, 0, 1999, },
- { "B Koesen", 5, 3, 29, 0, 1999, },
- { "Hildburg", 5, 3, 30, 0, 1999, },
- { "Ilmenau", 5, 3, 31, 0, 1999, },
- { "E-Flug", 5, 3, 32, 0, 1999, },
- { "E-Fuchs", 5, 3, 33, 0, 1999, },
- { "E-Andrea", 5, 3, 34, 0, 1999, },
- { "E-Chami", 5, 3, 35, 0, 1999, },
- { "NeuhausR", 5, 3, 36, 0, 1999, },
- { "Meininge", 5, 3, 37, 0, 1999, },
- { "E-FZA", 5, 3, 38, 0, 1999, },
- { "E-EVST 4", 5, 3, 39, 0, 1999, },
- { "Muehlhsn", 5, 3, 40, 0, 1999, },
- { "Blankenh", 5, 3, 41, 0, 1999, },
- { "Schmalka", 5, 3, 42, 0, 1999, },
- { "Heuthen", 5, 3, 43, 0, 1999, },
- { "Kaltenn", 5, 3, 44, 0, 1999, },
- { "Berga 1", 5, 3, 45, 0, 1999, },
- { "Oberhof", 5, 3, 46, 0, 1999, },
- { "Poessn", 5, 3, 47, 0, 1999, },
- { "Apolda 2", 5, 3, 48, 0, 1999, },
- { "BdLaSalz", 5, 3, 49, 0, 1999, },
- { "Soemmerd", 5, 3, 50, 0, 1999, },
- { "Triebes", 5, 3, 51, 0, 1999, },
- { "Lobenst", 5, 3, 52, 0, 1999, },
- { "Rudolst", 5, 3, 53, 0, 1999, },
- { "Schleiz", 5, 3, 54, 0, 1999, },
- { "Stadtrod", 5, 3, 55, 0, 1999, },
- { "Wernshsn", 5, 3, 56, 0, 1999, },
- { "Steinb-H", 5, 3, 58, 0, 1999, },
- { "Geisa 3", 5, 3, 59, 0, 1999, },
- { "Bleiche7", 5, 3, 60, 0, 1999, },
- { "Inselsbg", 5, 3, 61, 0, 1999, },
- { "Steinach", 5, 3, 62, 0, 1999, },
- { "Stadtilm", 5, 3, 63, 0, 1999, },
- { "Waltersh", 5, 3, 65, 0, 1999, },
- { "Gotha 6", 5, 3, 66, 0, 1999, },
- { "Eisenach", 5, 3, 67, 0, 1999, },
- { "Kahla 1", 5, 3, 68, 0, 1999, },
- { "Heiligst", 5, 3, 69, 0, 1999, },
- { "Thimmend", 5, 3, 70, 0, 1999, },
- { "Buttelst", 5, 3, 71, 0, 1999, },
- { "Koenigse", 5, 3, 72, 0, 1999, },
- { "Erfurt30", 5, 3, 73, 0, 1999, },
- { "Schoenbr", 5, 3, 74, 0, 1999, },
- { "Kindelbr", 5, 3, 75, 0, 1999, },
- { "Schlothe", 5, 3, 79, 0, 1999, },
- { "Bischofs", 5, 3, 91, 0, 1999, },
- { "Ludwigst", 5, 3, 92, 0, 1999, },
- { "Unsleben", 5, 3, 93, 0, 1999, },
- { "M-Sudenb", 6, 3, 1, 0, 1999, },
- { "M-Cracau", 6, 3, 2, 0, 1999, },
- { "M-Neust", 6, 3, 3, 0, 1999, },
- { "M-Bied", 6, 3, 4, 0, 1999, },
- { "M-Olvens", 6, 3, 5, 0, 1999, },
- { "M-Buckau", 6, 3, 6, 0, 1999, },
- { "Moeser 1", 6, 3, 7, 0, 1999, },
- { "M-Mitte", 6, 3, 8, 0, 1999, },
- { "M-Schoen", 6, 3, 9, 0, 1999, },
- { "Leitzkau", 6, 3, 10, 0, 1999, },
- { "Stendal", 6, 3, 11, 0, 1999, },
- { "Haldensl", 6, 3, 12, 0, 1999, },
- { "Oschersl", 6, 3, 13, 0, 1999, },
- { "Werniger", 6, 3, 14, 0, 1999, },
- { "Halberst", 6, 3, 15, 0, 1999, },
- { "Erxleben", 6, 3, 16, 0, 1999, },
- { "Altengra", 6, 3, 17, 0, 1999, },
- { "Genthin", 6, 3, 18, 0, 1999, },
- { "Burg 0", 6, 3, 19, 0, 1999, },
- { "Lindau A", 6, 3, 20, 0, 1999, },
- { "Kamern 2", 6, 3, 21, 0, 1999, },
- { "Niedernd", 6, 3, 22, 0, 1999, },
- { "Egeln", 6, 3, 23, 0, 1999, },
- { "Burg 5", 6, 3, 24, 0, 1999, },
- { "Fleetm 1", 6, 3, 25, 0, 1999, },
- { "Dolle 1", 6, 3, 26, 0, 1999, },
- { "Osterbg", 6, 3, 27, 0, 1999, },
- { "Frose", 6, 3, 28, 0, 1999, },
- { "Harzger", 6, 3, 29, 0, 1999, },
- { "Koennern", 6, 3, 30, 0, 1999, },
- { "Elbinger", 6, 3, 31, 0, 1999, },
- { "Wanzlebe", 6, 3, 32, 0, 1999, },
- { "Moorsleb", 6, 3, 33, 0, 1999, },
- { "Tangerm", 6, 3, 34, 0, 1999, },
- { "Bernburg", 6, 3, 35, 0, 1999, },
- { "Salzwdel", 6, 3, 36, 0, 1999, },
- { "Zerbst 4", 6, 3, 39, 0, 1999, },
- { "Aschersl", 6, 3, 48, 0, 1999, },
- { "Tangerh", 6, 3, 49, 0, 1999, },
- { "Kloetze", 6, 3, 52, 0, 1999, },
- { "Mieste", 6, 3, 55, 0, 1999, },
- { "Thale", 6, 3, 88, 0, 1999, },
- { "Seehsn", 6, 3, 93, 0, 1999, },
- { "Blankenb", 6, 3, 95, 0, 1999, },
- { "Gardel", 6, 3, 96, 0, 1999, },
- { "Gernrode", 6, 3, 97, 0, 1999, },
- { "Hasself", 6, 3, 98, 0, 1999, },
- { "Baerenst", 7, 3, 1, 0, 1999, },
- { "Auerbach", 7, 3, 2, 0, 1999, },
- { "BdElster", 7, 3, 3, 0, 1999, },
- { "Marienbg", 7, 3, 4, 0, 1999, },
- { "C-Toten", 7, 3, 5, 0, 1999, },
- { "Reichenb", 7, 3, 6, 0, 1999, },
- { "Bergen 1", 7, 3, 7, 0, 1999, },
- { "Rochlitz", 7, 3, 8, 0, 1999, },
- { "C-Reich", 7, 3, 9, 0, 1999, },
- { "Frankenb", 7, 3, 10, 0, 1999, },
- { "Ebersbru", 7, 3, 11, 0, 1999, },
- { "Schwarzb", 7, 3, 12, 0, 1999, },
- { "Freiberg", 7, 3, 13, 0, 1999, },
- { "Frauenst", 7, 3, 14, 0, 1999, },
- { "Glauchau", 7, 3, 15, 0, 1999, },
- { "Plauen", 7, 3, 16, 0, 1999, },
- { "Werdau", 7, 3, 17, 0, 1999, },
- { "Mittweid", 7, 3, 18, 0, 1999, },
- { "Zschopau", 7, 3, 19, 0, 1999, },
- { "C-BKH", 7, 3, 20, 0, 1999, },
- { "C-Hecker", 7, 3, 21, 0, 1999, },
- { "C-Landr", 7, 3, 22, 0, 1999, },
- { "Nossen 5", 7, 3, 23, 0, 1999, },
- { "C-Leuker", 7, 3, 24, 0, 1999, },
- { "C-Numer", 7, 3, 25, 0, 1999, },
- { "Hainich1", 7, 3, 26, 0, 1999, },
- { "Zwoenitz", 7, 3, 27, 0, 1999, },
- { "Zwickau", 7, 3, 28, 0, 1999, },
- { "C-28Usti", 7, 3, 29, 0, 1999, },
- { "Floeha 4", 7, 3, 30, 0, 1999, },
- { "Crimmi", 7, 3, 31, 0, 1999, },
- { "Eibenst", 7, 3, 32, 0, 1999, },
- { "C-Center", 7, 3, 33, 0, 1999, },
- { "Olbernh", 7, 3, 35, 0, 1999, },
- { "Hartenst", 7, 3, 36, 0, 1999, },
- { "Greiz 2", 7, 3, 37, 0, 1999, },
- { "Penig 2", 7, 3, 38, 0, 1999, },
- { "Thalheim", 7, 3, 39, 0, 1999, },
- { "Reinfeld", 1, 4, 3, 1991, 1999, },
- { "Hemmoor1", 1, 4, 4, 1991, 0, },
- { "Cuxhaven", 1, 4, 5, 1991, 0, },
- { "Bremen38", 1, 4, 6, 1991, 0, },
- { "VerdenWa", 1, 4, 7, 1991, 0, },
- { "Hoya 1", 1, 4, 8, 1991, 0, },
- { "Gudow 10", 1, 4, 9, 1991, 1999, },
- { "Travemue", 1, 4, 10, 1991, 1999, },
- { "Kiel 2", 1, 4, 11, 1991, 1999, },
- { "Fleckeby", 1, 4, 12, 1991, 0, },
- { "Vechta L", 1, 4, 14, 1991, 0, },
- { "Jever 0", 1, 4, 15, 1991, 0, },
- { "Rendsbur", 1, 4, 17, 1991, 1999, },
- { "Nortorf4", 1, 4, 18, 0, 1999, },
- { "Freienwi", 1, 4, 19, 1991, 1999, },
- { "Westerld", 1, 4, 20, 1991, 1999, },
- { "Bremerh.", 1, 4, 21, 1991, 0, },
- { "Heide 2", 1, 4, 22, 1991, 1999, },
- { "Henstedt", 1, 4, 23, 1991, 1999, },
- { "Bredsted", 1, 4, 24, 1991, 1999, },
- { "Leer 1", 1, 4, 25, 1991, 0, },
- { "Krum.Gr.", 1, 4, 26, 1991, 0, },
- { "Hamberg.", 1, 4, 28, 1991, 0, },
- { "Bassum 3", 1, 4, 29, 1991, 0, },
- { "Brunsbue", 1, 4, 30, 1991, 1999, },
- { "Luebeck2", 1, 4, 31, 1991, 1999, },
- { "Luebeck4", 1, 4, 32, 0, 1999, },
- { "Itzehoe2", 1, 4, 36, 0, 1999, },
- { "Findorff", 1, 4, 37, 1991, 0, },
- { "Ritterhu", 1, 4, 38, 1991, 0, },
- { "Delmenho", 1, 4, 39, 1991, 0, },
- { "Glueckst", 1, 4, 40, 1991, 1999, },
- { "Weyhe 0", 1, 4, 41, 1991, 0, },
- { "Tenever", 1, 4, 42, 1991, 0, },
- { "Lilienth", 1, 4, 43, 1991, 0, },
- { "Ploen 2", 1, 4, 44, 0, 1999, },
- { "Hude 0", 1, 4, 45, 1991, 0, },
- { "Fehmarn1", 1, 4, 46, 0, 1999, },
- { "Oldenbu1", 1, 4, 47, 1991, 0, },
- { "Oldenbu0", 1, 4, 48, 1991, 0, },
- { "GrKneten", 1, 4, 49, 1991, 0, },
- { "Hartenho", 1, 4, 50, 0, 1999, },
- { "Luenebg.", 1, 4, 51, 1991, 0, },
- { "DaeHagen", 1, 4, 52, 0, 1999, },
- { "Luebeck9", 1, 4, 53, 0, 1999, },
- { "Egestorf", 1, 4, 54, 1991, 0, },
- { "Ulzburg4", 1, 4, 55, 1991, 1999, },
- { "Luebek23", 1, 4, 56, 1991, 1999, },
- { "Schoenwa", 1, 4, 57, 1991, 1999, },
- { "Ratzebur", 1, 4, 58, 1991, 1999, },
- { "Schwarzb", 1, 4, 59, 1991, 1999, },
- { "Stade", 1, 4, 60, 1991, 0, },
- { "Elmshorn", 1, 4, 61, 1991, 1999, },
- { "Eckrnfd5", 1, 4, 62, 0, 1999, },
- { "Osterjor", 1, 4, 63, 1991, 0, },
- { "Wedel 9", 1, 4, 64, 1991, 0, },
- { "Norden 0", 1, 4, 65, 1991, 0, },
- { "Husum 0", 1, 4, 66, 1991, 1999, },
- { "Walle", 1, 4, 67, 1991, 0, },
- { "Woltmers", 1, 4, 68, 1991, 0, },
- { "Grolland", 1, 4, 69, 1991, 0, },
- { "Huckelri", 1, 4, 70, 1991, 0, },
- { "Hochh.Wi", 1, 4, 71, 1991, 0, },
- { "Marne 0", 1, 4, 72, 1991, 1999, },
- { "Neumuens", 1, 4, 73, 0, 1999, },
- { "Kloecknr", 1, 4, 74, 1991, 0, },
- { "HochDuen", 1, 4, 75, 1991, 0, },
- { "Suederlu", 1, 4, 76, 1991, 1999, },
- { "Ippener0", 1, 4, 77, 1991, 0, },
- { "Hatten10", 1, 4, 79, 1991, 0, },
- { "Kirchtim", 1, 4, 80, 1991, 0, },
- { "Garding1", 1, 4, 81, 1991, 1999, },
- { "Hohenfel", 1, 4, 82, 0, 1999, },
- { "Ahrensb1", 1, 4, 83, 0, 1999, },
- { "Edewecht", 1, 4, 84, 1991, 0, },
- { "Berne 0", 1, 4, 85, 1991, 0, },
- { "Schlesw4", 1, 4, 86, 0, 1999, },
- { "Bremervo", 1, 4, 87, 1991, 0, },
- { "Osterhol", 1, 4, 88, 1991, 0, },
- { "Wangerla", 1, 4, 89, 1991, 0, },
- { "Wankendf", 1, 4, 90, 1991, 1999, },
- { "Varel 1", 1, 4, 92, 1991, 0, },
- { "Friesoyt", 1, 4, 93, 1991, 0, },
- { "Wyk", 1, 4, 94, 0, 1999, },
- { "BdSegebe", 1, 4, 95, 1991, 1999, },
- { "Kappeln1", 1, 4, 96, 1991, 1999, },
- { "Helgolan", 1, 4, 97, 1991, 0, },
- { "Suelfeld", 1, 4, 99, 0, 1999, },
- { "HH22Bake", 2, 4, 1, 1991, 1999, },
- { "Buxtehud", 2, 4, 2, 1991, 1999, },
- { "Buchholz", 2, 4, 3, 0, 1999, },
- { "Egestorf", 2, 4, 4, 0, 1999, },
- { "Luenebu3", 2, 4, 5, 0, 1999, },
- { "Marxen 2", 2, 4, 6, 0, 1999, },
- { "Wulfsn10", 2, 4, 8, 0, 1999, },
- { "Pinnebg7", 2, 4, 9, 0, 1999, },
- { "Barsbuet", 2, 4, 10, 0, 1999, },
- { "Poppenbu", 2, 4, 11, 0, 1999, },
- { "Allermoe", 2, 4, 12, 0, 1999, },
- { "Harburg", 2, 4, 13, 1991, 1999, },
- { "Sauensik", 2, 4, 14, 0, 1999, },
- { "Betzendf", 2, 4, 15, 0, 1999, },
- { "Poppenbu", 2, 4, 16, 1991, 0, },
- { "Tostedt0", 2, 4, 17, 1991, 1999, },
- { "PhilipsM", 2, 4, 18, 0, 1999, },
- { "Klockman", 2, 4, 24, 0, 1999, },
- { "Bauerbgw", 2, 4, 25, 0, 1999, },
- { "Trittau", 2, 4, 26, 0, 1999, },
- { "Postamt2", 2, 4, 27, 1991, 1999, },
- { "Wandsbek", 2, 4, 28, 0, 1999, },
- { "Schulgar", 2, 4, 30, 1991, 1999, },
- { "Altona", 2, 4, 31, 1991, 1999, },
- { "FH Seefa", 2, 4, 32, 1991, 1999, },
- { "FernVst", 2, 4, 33, 1991, 1999, },
- { "Hoheluft", 2, 4, 34, 1991, 1999, },
- { "Modezent", 2, 4, 35, 1991, 1999, },
- { "Langnhor", 2, 4, 36, 0, 1999, },
- { "AchternB", 2, 4, 37, 1991, 1999, },
- { "Finkenwd", 2, 4, 38, 1991, 1999, },
- { "Waltersh", 2, 4, 39, 1991, 1999, },
- { "Wilhelms", 2, 4, 40, 1991, 1999, },
- { "Rotenbuo", 2, 4, 41, 1991, 1999, },
- { "Hamm", 2, 4, 42, 1991, 1999, },
- { "Steilsho", 2, 4, 43, 1991, 1999, },
- { "Ammersbk", 2, 4, 44, 0, 1999, },
- { "NeuWulms", 2, 4, 47, 1991, 1999, },
- { "Seevetal", 2, 4, 48, 1991, 1999, },
- { "Rosengar", 2, 4, 49, 1991, 1999, },
- { "RLindeWg", 2, 4, 50, 1991, 1999, },
- { "Elmshorn", 2, 4, 51, 1991, 0, },
- { "Norderst", 2, 4, 52, 1991, 1999, },
- { "FA4BBz26", 2, 4, 53, 1991, 1999, },
- { "Randowst", 2, 4, 54, 0, 1999, },
- { "Marschac", 2, 4, 56, 0, 1999, },
- { "Harsefld", 2, 4, 57, 1991, 0, },
- { "Winsen 0", 2, 4, 58, 1991, 1999, },
- { "Ahrensbu", 2, 4, 60, 1991, 1999, },
- { "Wittsmoo", 2, 4, 62, 1991, 0, },
- { "Wedel 11", 2, 4, 64, 0, 1999, },
- { "HH Phi.M", 2, 4, 65, 1991, 0, },
- { "HH Radow", 2, 4, 66, 1991, 0, },
- { "Marmstor", 2, 4, 68, 0, 1999, },
- { "Hollenst", 2, 4, 69, 0, 1999, },
- { "Uetersn2", 2, 4, 70, 0, 1999, },
- { "Schiffdf", 3, 4, 1, 0, 1999, },
- { "Emden 0", 3, 4, 2, 0, 1999, },
- { "Bd Zwahn", 3, 4, 4, 0, 1999, },
- { "Wardenbu", 3, 4, 5, 0, 1999, },
- { "HB38Bake", 3, 4, 6, 0, 1999, },
- { "VerWal 1", 3, 4, 7, 0, 1999, },
- { "Hoya 1", 3, 4, 8, 0, 1999, },
- { "HeesBoit", 3, 4, 9, 0, 1999, },
- { "Aurich", 3, 4, 10, 0, 1999, },
- { "Borkum 0", 3, 4, 11, 0, 1999, },
- { "Doerpen0", 3, 4, 12, 0, 1999, },
- { "Vechta-L", 3, 4, 14, 0, 1999, },
- { "Jever 0", 3, 4, 15, 0, 1999, },
- { "Rotenbur", 3, 4, 16, 0, 1999, },
- { "Wilhelmh", 3, 4, 18, 0, 1999, },
- { "Cuxhaven", 3, 4, 23, 0, 1999, },
- { "Harsefel", 3, 4, 24, 0, 1999, },
- { "Leer 1", 3, 4, 25, 0, 1999, },
- { "Helgolan", 3, 4, 26, 0, 1999, },
- { "Hemmoor1", 3, 4, 27, 0, 1999, },
- { "Hambergn", 3, 4, 28, 0, 1999, },
- { "Bassum 3", 3, 4, 29, 0, 1999, },
- { "Stade 1", 3, 4, 30, 0, 1999, },
- { "Bremen 0", 3, 4, 31, 0, 1999, },
- { "Ottersbg", 3, 4, 33, 0, 1999, },
- { "Visselho", 3, 4, 34, 0, 1999, },
- { "Westerst", 3, 4, 35, 0, 1999, },
- { "Findorf", 3, 4, 37, 0, 1999, },
- { "Ritterhu", 3, 4, 38, 0, 1999, },
- { "Delmenho", 3, 4, 39, 0, 1999, },
- { "Stuhr", 3, 4, 40, 0, 1999, },
- { "Weyhe 0", 3, 4, 41, 0, 1999, },
- { "TeneverH", 3, 4, 42, 0, 1999, },
- { "Lilienth", 3, 4, 43, 0, 1999, },
- { "Hude 0", 3, 4, 45, 0, 1999, },
- { "Oldenbu1", 3, 4, 47, 0, 1999, },
- { "Oldenbu0", 3, 4, 48, 0, 1999, },
- { "Norden 0", 3, 4, 65, 0, 1999, },
- { "Walle", 3, 4, 67, 0, 1999, },
- { "Woltmers", 3, 4, 68, 0, 1999, },
- { "Grolland", 3, 4, 69, 0, 1999, },
- { "Huckelri", 3, 4, 70, 0, 1999, },
- { "HidWisch", 3, 4, 71, 0, 1999, },
- { "Kloecknr", 3, 4, 74, 0, 1999, },
- { "GrohnerD", 3, 4, 75, 0, 1999, },
- { "GrIppenr", 3, 4, 77, 0, 1999, },
- { "Sulingen", 3, 4, 78, 0, 1999, },
- { "Hatten10", 3, 4, 79, 0, 1999, },
- { "Zeven 2", 3, 4, 80, 0, 1999, },
- { "Berne 0", 3, 4, 85, 0, 1999, },
- { "Bremervo", 3, 4, 87, 0, 1999, },
- { "Osterhol", 3, 4, 88, 0, 1999, },
- { "Wangerla", 3, 4, 89, 0, 1999, },
- { "Wildesha", 3, 4, 90, 0, 1999, },
- { "Langeoog", 3, 4, 91, 0, 1999, },
- { "Varel 1", 3, 4, 92, 0, 1999, },
- { "Friesoyt", 3, 4, 93, 0, 1999, },
- { "Kirchlin", 3, 4, 94, 0, 1999, },
- { "Papenbur", 3, 4, 95, 0, 1999, },
- { "Cloppenb", 3, 4, 96, 0, 1999, },
- { "WittmBur", 3, 4, 98, 0, 1999, },
- { "BDoberan", 4, 4, 1, 0, 1999, },
- { "Crivitz3", 4, 4, 2, 0, 1999, },
- { "Wolgast3", 4, 4, 3, 0, 1999, },
- { "Schwaan3", 4, 4, 4, 0, 1999, },
- { "Rostok26", 4, 4, 5, 0, 1999, },
- { "Tessin 3", 4, 4, 6, 0, 1999, },
- { "Broderst", 4, 4, 7, 0, 1999, },
- { "Grimmen", 4, 4, 8, 0, 1999, },
- { "Sassnitz", 4, 4, 9, 0, 1999, },
- { "Rostok10", 4, 4, 10, 0, 1999, },
- { "Tribsees", 4, 4, 11, 0, 1999, },
- { "Barth 3", 4, 4, 12, 0, 1999, },
- { "Stralsun", 4, 4, 13, 0, 1999, },
- { "Rostok11", 4, 4, 14, 0, 1999, },
- { "Ribnitz", 4, 4, 15, 0, 1999, },
- { "Kroeplin", 4, 4, 16, 0, 1999, },
- { "Greifswa", 4, 4, 17, 0, 1999, },
- { "Bergen", 4, 4, 18, 0, 1999, },
- { "Guestrow", 4, 4, 19, 0, 1999, },
- { "Schwer20", 4, 4, 20, 0, 1999, },
- { "Bennin 1", 4, 4, 21, 0, 1999, },
- { "Ludwlust", 4, 4, 24, 0, 1999, },
- { "Parchim5", 4, 4, 25, 0, 1999, },
- { "Bernitt1", 4, 4, 26, 0, 1999, },
- { "Wittenb2", 4, 4, 27, 0, 1999, },
- { "Wismar 6", 4, 4, 28, 0, 1999, },
- { "GrGodem1", 4, 4, 29, 0, 1999, },
- { "Sternber", 4, 4, 30, 0, 1999, },
- { "Camps 6", 4, 4, 31, 0, 1999, },
- { "Schwer 4", 4, 4, 32, 0, 1999, },
- { "Rastow 2", 4, 4, 33, 0, 1999, },
- { "Marnitz2", 4, 4, 34, 0, 1999, },
- { "Goldberg", 4, 4, 35, 0, 1999, },
- { "Grevesm5", 4, 4, 36, 0, 1999, },
- { "Gamelin1", 4, 4, 37, 0, 1999, },
- { "Redefin", 4, 4, 38, 0, 1999, },
- { "Roggendf", 4, 4, 39, 0, 1999, },
- { "Heringsd", 4, 4, 40, 0, 1999, },
- { "Torgelow", 4, 4, 42, 0, 1999, },
- { "Zuessow", 4, 4, 43, 0, 1999, },
- { "Lalendor", 4, 4, 44, 0, 1999, },
- { "Krakow 4", 4, 4, 45, 0, 1999, },
- { "Goehren2", 4, 4, 46, 0, 1999, },
- { "Anklam 2", 4, 4, 47, 0, 1999, },
- { "Burow 1", 4, 4, 48, 0, 1999, },
- { "Waren 5", 4, 4, 49, 0, 1999, },
- { "Jarmen 7", 4, 4, 52, 0, 1999, },
- { "Malchin5", 4, 4, 53, 0, 1999, },
- { "Friedld3", 4, 4, 56, 0, 1999, },
- { "Stavenh0", 4, 4, 57, 0, 1999, },
- { "Ueckerm3", 4, 4, 58, 0, 1999, },
- { "Schoenb5", 4, 4, 65, 0, 1999, },
- { "Demmin 0", 4, 4, 66, 0, 1999, },
- { "Altenkn7", 4, 4, 99, 0, 1999, },
- { "BadOeyn0", 1, 5, 2, 0, 1999, },
- { "BadSalz5", 1, 5, 3, 0, 1999, },
- { "Bohmte 0", 1, 5, 4, 0, 1999, },
- { "Buende 2", 1, 5, 5, 0, 1999, },
- { "Delbruek", 1, 5, 6, 0, 1999, },
- { "Extertal", 1, 5, 7, 0, 1999, },
- { "BadPyrm1", 1, 5, 9, 1991, 1999, },
- { "Luedge R", 1, 5, 10, 1991, 1999, },
- { "Ibbenbue", 1, 5, 11, 1991, 1999, },
- { "Bramsche", 1, 5, 12, 1991, 1999, },
- { "Barnst.0", 1, 5, 13, 0, 1999, },
- { "Herford4", 1, 5, 14, 0, 1999, },
- { "Luebbeke", 1, 5, 16, 1991, 1999, },
- { "Lingen 0", 1, 5, 17, 1991, 1999, },
- { "Bielefd0", 1, 5, 18, 0, 1999, },
- { "Lindern", 1, 5, 19, 1991, 1999, },
- { "Oerlingh", 1, 5, 20, 1991, 1999, },
- { "Guetersl", 1, 5, 21, 1991, 0, },
- { "GtlohFr0", 1, 5, 22, 1991, 1999, },
- { "Paderbrn", 1, 5, 23, 1991, 1999, },
- { "Hoevelhf", 1, 5, 24, 1991, 1999, },
- { "Lemgo 2", 1, 5, 25, 1991, 1999, },
- { "BdIburg2", 1, 5, 26, 1991, 1999, },
- { "Dissen 1", 1, 5, 27, 1991, 1999, },
- { "Melle 1", 1, 5, 28, 1991, 1999, },
- { "Fuersten", 1, 5, 29, 1991, 1999, },
- { "BdBenth2", 1, 5, 30, 1991, 1999, },
- { "Uchte 0", 1, 5, 32, 0, 1999, },
- { "BlfJoell", 1, 5, 33, 0, 1999, },
- { "BdLippsp", 1, 5, 34, 0, 1999, },
- { "Steinhgn", 1, 5, 35, 0, 1999, },
- { "Spenge 0", 1, 5, 37, 0, 1999, },
- { "Berge 0", 1, 5, 38, 0, 1999, },
- { "Minden 0", 1, 5, 40, 0, 1999, },
- { "Osnabr 8", 1, 5, 41, 0, 1999, },
- { "Osnabr 0", 1, 5, 42, 0, 1999, },
- { "Rahden 0", 1, 5, 44, 0, 1999, },
- { "Rheda-Wb", 1, 5, 45, 0, 1999, },
- { "Emlichhm", 1, 5, 48, 0, 1999, },
- { "Tecklenb", 1, 5, 50, 0, 1999, },
- { "Blomberg", 1, 5, 52, 0, 1999, },
- { "BDriburg", 1, 5, 54, 0, 1999, },
- { "Harsewin", 1, 5, 55, 0, 1999, },
- { "HornBadM", 1, 5, 56, 0, 1999, },
- { "Nordhorn", 1, 5, 59, 0, 1999, },
- { "Gtloh 0", 1, 5, 60, 0, 1999, },
- { "Damme 1", 1, 5, 61, 1991, 1999, },
- { "Meppen 0", 1, 5, 62, 1991, 1999, },
- { "Rheine 0", 1, 5, 63, 1991, 1999, },
- { "Bielefd1", 1, 5, 92, 1991, 1999, },
- { "Minden 2", 1, 5, 95, 1991, 1999, },
- { "Han 790", 2, 5, 1, 0, 1999, },
- { "Barsingh", 2, 5, 2, 1991, 1999, },
- { "Bergen 1", 2, 5, 3, 1991, 1999, },
- { "Celle 0", 2, 5, 4, 1991, 1999, },
- { "Salzhmdf", 2, 5, 5, 1991, 1999, },
- { "Peine 1", 2, 5, 6, 1991, 1999, },
- { "Sibbess1", 2, 5, 7, 1991, 1999, },
- { "Brswg 3", 2, 5, 9, 1991, 1999, },
- { "Wietze 2", 2, 5, 10, 1991, 1999, },
- { "Wolfsbg1", 2, 5, 11, 1991, 1999, },
- { "Sprakens", 2, 5, 12, 1991, 1999, },
- { "Wesendf", 2, 5, 13, 0, 1999, },
- { "Alfeld40", 2, 5, 14, 1991, 1999, },
- { "Mori.Fr.", 2, 5, 15, 1991, 0, },
- { "Zierenb.", 2, 5, 16, 1991, 0, },
- { "Semmenst", 2, 5, 17, 1991, 1999, },
- { "HildBoer", 2, 5, 18, 1991, 1999, },
- { "Eschede", 2, 5, 19, 1991, 1999, },
- { "Loccum 0", 2, 5, 21, 0, 1999, },
- { "Zernien", 2, 5, 22, 1991, 1999, },
- { "Gartow 1", 2, 5, 23, 1991, 1999, },
- { "Bispin41", 2, 5, 24, 0, 1999, },
- { "Hann. 4", 2, 5, 26, 1991, 1999, },
- { "Gradestr", 2, 5, 27, 1991, 1999, },
- { "NeueLand", 2, 5, 28, 1991, 1999, },
- { "StudWH", 2, 5, 29, 1991, 1999, },
- { "LinGilde", 2, 5, 30, 1991, 1999, },
- { "Hanomag", 2, 5, 31, 1991, 1999, },
- { "Uetze", 2, 5, 32, 1991, 1999, },
- { "Garbsen", 2, 5, 33, 1991, 1999, },
- { "Wedemark", 2, 5, 34, 1991, 1999, },
- { "Burgwdl0", 2, 5, 35, 1991, 1999, },
- { "Schwarm", 2, 5, 36, 0, 1999, },
- { "Lehrte 2", 2, 5, 37, 1991, 1999, },
- { "Sarstedt", 2, 5, 38, 1991, 1999, },
- { "Ronnenbg", 2, 5, 39, 1991, 1999, },
- { "Walsrode", 2, 5, 40, 1991, 1999, },
- { "Gifhorn0", 2, 5, 41, 1991, 1999, },
- { "Hitzack1", 2, 5, 42, 0, 1999, },
- { "Hildeshm", 2, 5, 43, 0, 1999, },
- { "Bleckede", 2, 5, 44, 0, 1999, },
- { "Einbeck2", 2, 5, 46, 0, 1999, },
- { "Brswg701", 2, 5, 48, 0, 1999, },
- { "Hameln10", 2, 5, 49, 1991, 1999, },
- { "Schnever", 2, 5, 50, 0, 1999, },
- { "Helmstdt", 2, 5, 51, 1991, 1999, },
- { "Han 610", 2, 5, 52, 0, 1999, },
- { "Herzberg", 2, 5, 53, 1991, 0, },
- { "Brswg 36", 2, 5, 54, 1991, 1999, },
- { "Stadthgn", 2, 5, 55, 0, 1999, },
- { "Nienburg", 2, 5, 58, 1991, 1999, },
- { "Linsburg", 2, 5, 60, 1991, 1999, },
- { "Springe3", 2, 5, 61, 0, 1999, },
- { "Han 860", 2, 5, 62, 1991, 1999, },
- { "Eschersh", 2, 5, 63, 0, 1999, },
- { "Holle 40", 2, 5, 64, 0, 1999, },
- { "Munster1", 2, 5, 65, 1991, 1999, },
- { "Bgdf-Ehl", 2, 5, 66, 0, 1999, },
- { "Salzg 40", 2, 5, 67, 1991, 1999, },
- { "Burgdorf", 2, 5, 68, 1991, 1999, },
- { "Seesen 1", 2, 5, 69, 1991, 1999, },
- { "Kreiens1", 2, 5, 70, 0, 1999, },
- { "Kassel", 2, 5, 72, 1991, 0, },
- { "Eschwege", 2, 5, 73, 1991, 0, },
- { "Obernk 2", 2, 5, 74, 1991, 1999, },
- { "Melsung5", 2, 5, 75, 1991, 0, },
- { "Uelzen 3", 2, 5, 76, 1991, 1999, },
- { "Jerxheim", 2, 5, 78, 1991, 1999, },
- { "Wunstorf", 2, 5, 80, 0, 1999, },
- { "Brome 0", 2, 5, 82, 0, 1999, },
- { "Salzg 0", 2, 5, 84, 0, 1999, },
- { "Wendebg", 2, 5, 85, 0, 1999, },
- { "Han 730", 2, 5, 86, 1991, 1999, },
- { "Soltau 2", 2, 5, 87, 0, 1999, },
- { "Irxleben", 2, 5, 88, 1991, 0, },
- { "Claustal", 2, 5, 90, 0, 1999, },
- { "Goslar41", 2, 5, 91, 0, 1999, },
- { "Koenigsl", 2, 5, 92, 0, 1999, },
- { "Torfhaus", 2, 5, 93, 0, 1999, },
- { "Einbeck2", 2, 5, 94, 1991, 0, },
- { "Sibb2 DB", 2, 5, 95, 0, 1999, },
- { "HanMesse", 2, 5, 97, 0, 1999, },
- { "Hoever", 2, 5, 98, 0, 1999, },
- { "Homberg1", 3, 5, 1, 0, 1999, },
- { "Morschen", 3, 5, 2, 0, 1999, },
- { "Spangenb", 3, 5, 3, 0, 1999, },
- { "Baunatal", 3, 5, 5, 0, 1999, },
- { "Korbach0", 3, 5, 8, 0, 1999, },
- { "Arolsen0", 3, 5, 9, 0, 1999, },
- { "Zierenb3", 3, 5, 10, 0, 1999, },
- { "Hofgeism", 3, 5, 11, 0, 1999, },
- { "BKarlshf", 3, 5, 12, 0, 1999, },
- { "Fritzlar", 3, 5, 13, 0, 1999, },
- { "Warburg2", 3, 5, 14, 0, 1999, },
- { "Willebad", 3, 5, 15, 0, 1999, },
- { "Gtngn 2", 3, 5, 17, 0, 1999, },
- { "Moringen", 3, 5, 18, 0, 1999, },
- { "Zierenb1", 3, 5, 19, 0, 1999, },
- { "Grossalm", 3, 5, 21, 0, 1999, },
- { "Kassel 1", 3, 5, 22, 0, 1999, },
- { "Herzberg", 3, 5, 25, 0, 1999, },
- { "Neuhaus2", 3, 5, 26, 0, 1999, },
- { "Rosdrf40", 3, 5, 27, 0, 1999, },
- { "Osterrod", 3, 5, 28, 0, 1999, },
- { "Eschwege", 3, 5, 30, 0, 1999, },
- { "Sontra 2", 3, 5, 31, 0, 1999, },
- { "Melsgn5", 3, 5, 32, 0, 1999, },
- { "Muenden2", 3, 5, 33, 0, 1999, },
- { "Rehagn40", 3, 5, 34, 0, 1999, },
- { "BSachsa1", 3, 5, 35, 0, 1999, },
- { "Muenden3", 3, 5, 38, 0, 1999, },
- { "Northeim", 3, 5, 39, 0, 1999, },
- { "Vellmar", 3, 5, 41, 0, 1999, },
- { "Brnlage", 3, 5, 43, 0, 1999, },
- { "Waldkapl", 3, 5, 44, 0, 1999, },
- { "Edertal", 3, 5, 45, 0, 1999, },
- { "Brakel 2", 3, 5, 46, 0, 1999, },
- { "HessLich", 3, 5, 47, 0, 1999, },
- { "Duderst", 3, 5, 48, 0, 1999, },
- { "BSAllend", 3, 5, 49, 0, 1999, },
- { "BWildngn", 3, 5, 51, 0, 1999, },
- { "Woelfte", 3, 5, 54, 0, 1999, },
- { "Kalefeld", 3, 5, 55, 0, 1999, },
- { "Kassel 4", 3, 5, 56, 0, 1999, },
- { "Buchbg99", 3, 5, 58, 0, 1999, },
- { "Worms_7", 1, 6, 1, 1991, 1999, },
- { "Westhofn", 1, 6, 2, 1991, 1999, },
- { "Benshm_0", 1, 6, 3, 1991, 1999, },
- { "Waibstdt", 1, 6, 4, 1991, 1999, },
- { "Seeheim2", 1, 6, 5, 1991, 1999, },
- { "Mosbach6", 1, 6, 6, 1991, 1999, },
- { "Eberbach", 1, 6, 7, 1991, 1999, },
- { "Lambrech", 1, 6, 8, 1991, 1999, },
- { "Weidenth", 1, 6, 9, 1991, 1999, },
- { "BdKrznch", 1, 6, 10, 1991, 1999, },
- { "Annweile", 1, 6, 11, 1991, 1999, },
- { "Wilhelms", 1, 6, 12, 1991, 1999, },
- { "Alzey_1", 1, 6, 13, 1991, 1999, },
- { "Mudau 1", 1, 6, 14, 1991, 1999, },
- { "Klautern", 1, 6, 15, 1991, 1999, },
- { "Pirmas.", 1, 6, 16, 1991, 0, },
- { "Konken 3", 1, 6, 17, 1991, 0, },
- { "BdBergza", 1, 6, 22, 1991, 1999, },
- { "Kell", 1, 6, 23, 1991, 0, },
- { "Wiesloch", 1, 6, 24, 0, 1999, },
- { "Hockenhm", 1, 6, 25, 1991, 1999, },
- { "Beerfldn", 1, 6, 26, 1991, 1999, },
- { "Hardberg", 1, 6, 27, 0, 1999, },
- { "Ahorn 1", 1, 6, 28, 0, 1999, },
- { "Scheffle", 1, 6, 29, 0, 1999, },
- { "Michlstd", 1, 6, 30, 1991, 1999, },
- { "Friedrfd", 1, 6, 31, 1991, 1999, },
- { "Lindnfls", 1, 6, 32, 1991, 1999, },
- { "Sob.Eck.", 1, 6, 33, 1991, 0, },
- { "Moeckmue", 1, 6, 34, 1991, 1999, },
- { "Meishm_6", 1, 6, 35, 1991, 1999, },
- { "Odernhm", 1, 6, 36, 1991, 1999, },
- { "Guntbl_3", 1, 6, 37, 1991, 1999, },
- { "Flonheim", 1, 6, 38, 1991, 1999, },
- { "Neutsch", 1, 6, 40, 1991, 1999, },
- { "Gerolste", 1, 6, 41, 1991, 0, },
- { "Schoena3", 1, 6, 42, 0, 1999, },
- { "Neckarg1", 1, 6, 43, 0, 1999, },
- { "Neckarg2", 1, 6, 44, 0, 1999, },
- { "Meckeshm", 1, 6, 45, 0, 1999, },
- { "Schoenau", 1, 6, 46, 1991, 1999, },
- { "Lebach 3", 1, 6, 47, 1991, 0, },
- { "Sulzbh10", 1, 6, 48, 1991, 0, },
- { "Voelklin", 1, 6, 49, 1991, 0, },
- { "Hardheim", 1, 6, 51, 0, 1999, },
- { "Buchen 0", 1, 6, 52, 0, 1999, },
- { "Maxdorf0", 1, 6, 53, 0, 1999, },
- { "Guntbl_1", 1, 6, 54, 0, 1999, },
- { "Bensh_13", 1, 6, 55, 1991, 1999, },
- { "Weinheim", 1, 6, 56, 0, 1999, },
- { "Winwlr_2", 1, 6, 57, 0, 1999, },
- { "Winwlr_8", 1, 6, 58, 0, 1999, },
- { "Neustadt", 1, 6, 60, 1991, 1999, },
- { "LU 505", 1, 6, 61, 1991, 1999, },
- { "Speyer 5", 1, 6, 62, 1991, 1999, },
- { "Landau 8", 1, 6, 63, 1991, 1999, },
- { "Heidelbg", 1, 6, 64, 1991, 1999, },
- { "Dahn_3", 1, 6, 65, 0, 1999, },
- { "Schwetzi", 1, 6, 66, 1991, 1999, },
- { "Ladenbg6", 1, 6, 67, 1991, 1999, },
- { "Lamperth", 1, 6, 68, 1991, 1999, },
- { "Pfeiffer", 1, 6, 69, 1991, 1999, },
- { "Neuhofen", 1, 6, 70, 1991, 1999, },
- { "Ilveshm", 1, 6, 71, 1991, 1999, },
- { "DiakoKrH", 1, 6, 72, 1991, 1999, },
- { "GrosKrWe", 1, 6, 73, 1991, 1999, },
- { "K.M.Wein", 1, 6, 74, 1991, 0, },
- { "Maimarkt", 1, 6, 75, 1991, 1999, },
- { "Siloturm", 1, 6, 76, 1991, 1999, },
- { "Kaeferta", 1, 6, 77, 1991, 1999, },
- { "Viernhm", 1, 6, 78, 1991, 1999, },
- { "Neunki.", 1, 6, 79, 1991, 0, },
- { "Mettl.M.", 1, 6, 80, 1991, 0, },
- { "Zweibrue", 1, 6, 82, 1991, 0, },
- { "Adelshei", 1, 6, 83, 0, 1999, },
- { "Gernsh_4", 1, 6, 84, 0, 1999, },
- { "Alsenz_7", 1, 6, 85, 0, 1999, },
- { "Frankent", 1, 6, 86, 1991, 1999, },
- { "Gruenstd", 1, 6, 87, 1991, 1999, },
- { "BdDuerk2", 1, 6, 88, 1991, 1999, },
- { "BdDuerk0", 1, 6, 89, 0, 1999, },
- { "Khmbolan", 1, 6, 90, 0, 1999, },
- { "Hasmersh", 1, 6, 91, 0, 1999, },
- { "EnkAlsnb", 1, 6, 93, 0, 1999, },
- { "Miltnbg2", 1, 6, 94, 0, 1999, },
- { "Miltnbg4", 1, 6, 95, 0, 1999, },
- { "Rockhsn", 1, 6, 96, 0, 1999, },
- { "DB Pfing", 1, 6, 97, 1991, 1999, },
- { "MA4 Bake", 1, 6, 99, 1991, 1999, },
- { "F16_INIT", 2, 6, 1, 1991, 1999, },
- { "Dieburg", 2, 6, 2, 0, 1999, },
- { "GrUmstdt", 2, 6, 3, 0, 1999, },
- { "Brensbch", 2, 6, 4, 0, 1999, },
- { "Heusenst", 2, 6, 5, 0, 1999, },
- { "Floershm", 2, 6, 6, 0, 1999, },
- { "Gr-Gerau", 2, 6, 7, 0, 1999, },
- { "Langen", 2, 6, 8, 1991, 1999, },
- { "Moerf-Wal", 2, 6, 9, 1991, 1999, },
- { "Rodgau", 2, 6, 10, 1991, 1999, },
- { "Darmst21", 2, 6, 11, 0, 1999, },
- { "Darmst_2", 2, 6, 12, 0, 1999, },
- { "Reusselsh", 2, 6, 13, 0, 1999, },
- { "Hofh-Wal", 2, 6, 15, 0, 1999, },
- { "Eppst_2", 2, 6, 16, 0, 1999, },
- { "Wiesb_1", 2, 6, 17, 0, 1999, },
- { "Wiesb_33", 2, 6, 18, 0, 1999, },
- { "Wiesb_34", 2, 6, 19, 0, 1999, },
- { "Wiesb_35", 2, 6, 20, 0, 1999, },
- { "Klstrbch", 2, 6, 21, 0, 1999, },
- { "Mnz_Kstl", 2, 6, 22, 0, 1999, },
- { "Mainz_3", 2, 6, 23, 0, 1999, },
- { "Mainz_4", 2, 6, 24, 0, 1999, },
- { "Mainz_5", 2, 6, 25, 0, 1999, },
- { "Mainz_26", 2, 6, 26, 0, 1999, },
- { "Niedrhsn", 2, 6, 27, 0, 1999, },
- { "Eppst_1", 2, 6, 28, 0, 1999, },
- { "Roedrmk7", 2, 6, 30, 0, 1999, },
- { "Kastell2", 2, 6, 31, 0, 1999, },
- { "Lorch_3", 2, 6, 32, 0, 1999, },
- { "Oppenhm", 2, 6, 34, 0, 1999, },
- { "Pfungstd", 2, 6, 35, 0, 1999, },
- { "BadSoden", 2, 6, 36, 1991, 1999, },
- { "Kronberg", 2, 6, 37, 1991, 1999, },
- { "F-Zeil", 2, 6, 38, 1991, 1999, },
- { "F-Rohmer", 2, 6, 39, 1991, 1999, },
- { "F-Raimnd", 2, 6, 40, 1991, 1999, },
- { "F-Giess", 2, 6, 41, 1991, 1999, },
- { "Koenigst", 2, 6, 42, 1991, 1999, },
- { "F-DanzPl", 2, 6, 43, 1991, 1999, },
- { "NeuIsnbg", 2, 6, 44, 1991, 1999, },
- { "F-StbHhl", 2, 6, 45, 1991, 1999, },
- { "Kriftel", 2, 6, 46, 1991, 1999, },
- { "Kelkheim", 2, 6, 47, 1991, 1999, },
- { "Oberursl", 2, 6, 48, 1991, 1999, },
- { "F-Berkhm", 2, 6, 49, 1991, 1999, },
- { "F-Diestw", 2, 6, 50, 1991, 1999, },
- { "F-MnzLSt", 2, 6, 51, 1991, 1999, },
- { "F-Lyoner", 2, 6, 52, 1991, 1999, },
- { "F-Oeser", 2, 6, 53, 1991, 1999, },
- { "BdVilbel", 2, 6, 54, 1991, 1999, },
- { "F-Orber", 2, 6, 55, 1991, 1999, },
- { "F-Flughf", 2, 6, 56, 1991, 1999, },
- { "Lorch_4", 2, 6, 58, 0, 1999, },
- { "OF-Jahns", 2, 6, 61, 1991, 1999, },
- { "Nastaett", 2, 6, 62, 0, 1999, },
- { "Babenhsn", 2, 6, 63, 0, 1999, },
- { "ObRamstd", 2, 6, 65, 0, 1999, },
- { "Breuberg", 2, 6, 66, 0, 1999, },
- { "ObrWesel", 2, 6, 72, 0, 1999, },
- { "Pfalzfd", 2, 6, 73, 0, 1999, },
- { "Rhnboell", 2, 6, 74, 0, 1999, },
- { "Ruedeshm", 2, 6, 75, 0, 1999, },
- { "Eltville", 2, 6, 76, 0, 1999, },
- { "Wintrbch", 2, 6, 77, 0, 1999, },
- { "Boppard", 2, 6, 78, 0, 1999, },
- { "OF-Krkhs", 2, 6, 79, 1991, 1999, },
- { "Strombg", 2, 6, 80, 0, 1999, },
- { "Trebur1", 2, 6, 81, 0, 1999, },
- { "Ffm Sued", 2, 6, 83, 0, 1999, },
- { "MainTaZ", 2, 6, 84, 0, 1999, },
- { "BHombg0", 3, 6, 1, 0, 1999, },
- { "Friedb1", 3, 6, 2, 1991, 1999, },
- { "Schottn", 3, 6, 3, 1991, 1999, },
- { "Gelnhsn", 3, 6, 4, 1991, 1999, },
- { "BSchwa3", 3, 6, 5, 0, 1999, },
- { "Friedb0", 3, 6, 6, 1991, 1999, },
- { "Biedk_2", 3, 6, 7, 1991, 1999, },
- { "Biedk_3", 3, 6, 10, 0, 1999, },
- { "Birstein", 3, 6, 11, 1991, 1999, },
- { "Weibersb", 3, 6, 12, 1991, 1999, },
- { "Kalbach1", 3, 6, 13, 0, 1999, },
- { "Driedorf", 3, 6, 14, 0, 1999, },
- { "Lich_2", 3, 6, 15, 1991, 1999, },
- { "Mz 3", 3, 6, 16, 1991, 0, },
- { "Hilders", 3, 6, 17, 1991, 1999, },
- { "Frankbg", 3, 6, 18, 1991, 1999, },
- { "Friedwd", 3, 6, 19, 1991, 1999, },
- { "Mz Kaste", 3, 6, 20, 1991, 0, },
- { "Hanau_1", 3, 6, 21, 1991, 1999, },
- { "Gemuen1", 3, 6, 22, 1991, 1999, },
- { "Gruenbg0", 3, 6, 23, 1991, 1999, },
- { "Hanau_7", 3, 6, 24, 1991, 1999, },
- { "Hungen2", 3, 6, 25, 1991, 1999, },
- { "Gemnden1", 3, 6, 26, 1991, 1999, },
- { "Biebert", 3, 6, 27, 1991, 1999, },
- { "Marburg", 3, 6, 28, 1991, 1999, },
- { "HainaKl", 3, 6, 29, 1991, 1999, },
- { "Weilbg6", 3, 6, 30, 1991, 1999, },
- { "Fulda_3", 3, 6, 31, 1991, 1999, },
- { "Bd_Hersf", 3, 6, 32, 1991, 1999, },
- { "Schlue_3", 3, 6, 33, 1991, 1999, },
- { "Neuenst", 3, 6, 34, 1991, 1999, },
- { "Ebersbg", 3, 6, 35, 1991, 1999, },
- { "Lautrbch", 3, 6, 36, 1991, 1999, },
- { "Gruenbg1", 3, 6, 37, 0, 1999, },
- { "Ortenbg", 3, 6, 38, 0, 1999, },
- { "Alsfeld", 3, 6, 39, 1991, 1999, },
- { "Altenstd", 3, 6, 40, 1991, 0, },
- { "Katzelnb", 3, 6, 41, 1991, 1999, },
- { "Babenhs3", 3, 6, 42, 1991, 0, },
- { "Aarbgn_1", 3, 6, 43, 1991, 1999, },
- { "Aarberg3", 3, 6, 44, 1991, 0, },
- { "BSchwa_2", 3, 6, 45, 1991, 1999, },
- { "Schlabad", 3, 6, 46, 1991, 1999, },
- { "Lich_Eb", 3, 6, 47, 1991, 1999, },
- { "AB14Hoes", 3, 6, 48, 0, 1999, },
- { "Schwlmst", 3, 6, 50, 1991, 1999, },
- { "Nentrhsn", 3, 6, 51, 1991, 1999, },
- { "Reichlsh", 3, 6, 52, 0, 1999, },
- { "Woelfshm", 3, 6, 53, 0, 1999, },
- { "Limburg", 3, 6, 54, 1991, 1999, },
- { "Rotenbg", 3, 6, 55, 0, 1999, },
- { "Burgsinn", 3, 6, 56, 0, 1999, },
- { "Schlitz", 3, 6, 57, 0, 1999, },
- { "Wildeck", 3, 6, 58, 0, 1999, },
- { "Friedrdf", 3, 6, 59, 1991, 1999, },
- { "Taunuss", 3, 6, 60, 1991, 1999, },
- { "Giessen0", 3, 6, 61, 1991, 1999, },
- { "Linden_5", 3, 6, 62, 1991, 1999, },
- { "Breitnbc", 3, 6, 63, 0, 1999, },
- { "BdBrueck", 3, 6, 64, 0, 1999, },
- { "Buseck_6", 3, 6, 65, 0, 1999, },
- { "Eckhhsn", 3, 6, 66, 0, 1999, },
- { "Steinau", 3, 6, 68, 1991, 1999, },
- { "Nidda_3", 3, 6, 69, 0, 1999, },
- { "Braunfls", 3, 6, 70, 0, 1999, },
- { "Lselbold", 3, 6, 71, 1991, 1999, },
- { "Usingen", 3, 6, 72, 0, 1999, },
- { "Ehringsh", 3, 6, 74, 0, 1999, },
- { "Seligstd", 3, 6, 75, 0, 1999, },
- { "BdNauhm2", 3, 6, 77, 0, 1999, },
- { "AB11Gail", 3, 6, 78, 0, 1999, },
- { "AB13Glat", 3, 6, 79, 0, 1999, },
- { "GrAuheim", 3, 6, 80, 0, 1999, },
- { "Dillenbg", 3, 6, 81, 1991, 1999, },
- { "Eschenbg", 3, 6, 82, 1991, 1999, },
- { "Herlesh1", 3, 6, 83, 1991, 1999, },
- { "Idstein", 3, 6, 84, 1991, 1999, },
- { "Herborn", 3, 6, 85, 1991, 1999, },
- { "Selters", 3, 6, 86, 1991, 1999, },
- { "BadCambg", 3, 6, 87, 1991, 1999, },
- { "Karben1", 3, 6, 88, 0, 1999, },
- { "Lohr 2", 3, 6, 89, 0, 1999, },
- { "Neuhof", 3, 6, 90, 1991, 1999, },
- { "Esselbac", 3, 6, 91, 0, 1999, },
- { "Moembris", 3, 6, 92, 0, 1999, },
- { "Obernbu1", 3, 6, 93, 0, 1999, },
- { "Wetzlar", 3, 6, 94, 0, 1999, },
- { "Guxhgn 1", 3, 6, 95, 0, 1999, },
- { "Ndraula", 3, 6, 96, 0, 1999, },
- { "Huenfeld", 3, 6, 97, 0, 1999, },
- { "Wiesen 1", 3, 6, 98, 0, 1999, },
- { "Faulbach", 3, 6, 99, 0, 1999, },
- { "Saarbr_2", 4, 6, 1, 0, 1999, },
- { "Welschb", 4, 6, 2, 0, 1999, },
- { "Hallschl", 4, 6, 3, 0, 1999, },
- { "Marpngn", 4, 6, 4, 0, 1999, },
- { "Konz", 4, 6, 5, 0, 1999, },
- { "Simmern3", 4, 6, 7, 0, 1999, },
- { "Saarloui", 4, 6, 8, 0, 1999, },
- { "Saarbr_5", 4, 6, 9, 0, 1999, },
- { "Perl 1", 4, 6, 11, 0, 1999, },
- { "Gemuendn", 4, 6, 13, 0, 1999, },
- { "Pirmasns", 4, 6, 16, 0, 1999, },
- { "Konken_3", 4, 6, 17, 0, 1999, },
- { "GlMnchwl", 4, 6, 18, 0, 1999, },
- { "RbchStgn", 4, 6, 19, 0, 1999, },
- { "Lndstuhl", 4, 6, 20, 0, 1999, },
- { "Weilerb", 4, 6, 21, 0, 1999, },
- { "Trier_1", 4, 6, 22, 0, 1999, },
- { "Kell_1", 4, 6, 23, 0, 1999, },
- { "Blieskst", 4, 6, 24, 0, 1999, },
- { "Bernk-Ks", 4, 6, 25, 0, 1999, },
- { "Pruem_2", 4, 6, 26, 0, 1999, },
- { "Idar-Ob", 4, 6, 27, 0, 1999, },
- { "Brchmbch", 4, 6, 28, 0, 1999, },
- { "Dellfeld", 4, 6, 30, 0, 1999, },
- { "Homburg0", 4, 6, 31, 0, 1999, },
- { "Kastell3", 4, 6, 32, 0, 1999, },
- { "SchbKueb", 4, 6, 33, 0, 1999, },
- { "StWendel", 4, 6, 34, 0, 1999, },
- { "Heuswlr", 4, 6, 35, 0, 1999, },
- { "Saarbr_1", 4, 6, 36, 0, 1999, },
- { "Neumg_Dr", 4, 6, 37, 0, 1999, },
- { "Bitburg", 4, 6, 38, 0, 1999, },
- { "Wolfstn", 4, 6, 39, 0, 1999, },
- { "Saarburg", 4, 6, 40, 0, 1999, },
- { "Gerolstn", 4, 6, 41, 0, 1999, },
- { "Kirn_7", 4, 6, 44, 0, 1999, },
- { "Merzig_3", 4, 6, 46, 0, 1999, },
- { "Lebach_3", 4, 6, 47, 0, 1999, },
- { "Sulzbach", 4, 6, 48, 0, 1999, },
- { "Voelklng", 4, 6, 49, 0, 1999, },
- { "Zweibrck", 4, 6, 50, 0, 1999, },
- { "Buedlich", 4, 6, 54, 0, 1999, },
- { "Klblittd", 4, 6, 56, 0, 1999, },
- { "Meishm_7", 4, 6, 59, 0, 1999, },
- { "HWeidtal", 4, 6, 60, 0, 1999, },
- { "Dillingn", 4, 6, 61, 0, 1999, },
- { "Thleiwlr", 4, 6, 62, 0, 1999, },
- { "Trulben2", 4, 6, 64, 0, 1999, },
- { "Kirchbg1", 4, 6, 78, 0, 1999, },
- { "Neunkrch", 4, 6, 79, 0, 1999, },
- { "Mettlach", 4, 6, 80, 0, 1999, },
- { "Beuron 1", 1, 7, 1, 1991, 1999, },
- { "AlLaufn1", 1, 7, 2, 1991, 1999, },
- { "Oberndf3", 1, 7, 3, 1991, 1999, },
- { "Schwenni", 1, 7, 4, 1991, 1999, },
- { "Rottweil", 1, 7, 5, 1991, 1999, },
- { "AlEbing2", 1, 7, 6, 1991, 1999, },
- { "Baiersb1", 1, 7, 7, 1991, 1999, },
- { "Balingn1", 1, 7, 8, 1991, 1999, },
- { "Gosheim1", 1, 7, 9, 1991, 1999, },
- { "Tuttlin2", 1, 7, 10, 1991, 1999, },
- { "Konstan0", 1, 7, 11, 1991, 1999, },
- { "Waldbg 2", 1, 7, 12, 1991, 1999, },
- { "Deggenh3", 1, 7, 13, 1991, 1999, },
- { "Sigmari4", 1, 7, 14, 1991, 1999, },
- { "Donaues5", 1, 7, 15, 1991, 1999, },
- { "Singen 0", 1, 7, 16, 1991, 1999, },
- { "Klettga6", 1, 7, 17, 1991, 1999, },
- { "Rickenb1", 1, 7, 18, 1991, 1999, },
- { "Bodman 3", 1, 7, 19, 1991, 1999, },
- { "Sauldf 1", 1, 7, 20, 1991, 1999, },
- { "Hilzingn", 1, 7, 21, 0, 1999, },
- { "Stockac6", 1, 7, 22, 1991, 1999, },
- { "Aichste2", 1, 7, 23, 1991, 1999, },
- { "Voehrnb4", 1, 7, 24, 1991, 1999, },
- { "Radolfzl", 1, 7, 25, 1991, 1999, },
- { "Schoemb2", 1, 7, 26, 1991, 1999, },
- { "Nagold 0", 1, 7, 27, 1991, 1999, },
- { "Rottenb3", 1, 7, 28, 1991, 1999, },
- { "Heching6", 1, 7, 29, 1991, 1999, },
- { "Ammerbu2", 1, 7, 30, 1991, 1999, },
- { "Allensb1", 1, 7, 31, 1991, 1999, },
- { "Villin10", 1, 7, 32, 1991, 1999, },
- { "Tiegen 0", 1, 7, 33, 1991, 1999, },
- { "Mengen 1", 1, 7, 34, 1991, 1999, },
- { "BdSchus1", 1, 7, 35, 1991, 1999, },
- { "Ravensb0", 1, 7, 36, 1991, 1999, },
- { "Friedrh0", 1, 7, 37, 1991, 1999, },
- { "Nagold 1", 1, 7, 38, 1991, 1999, },
- { "Baiersb3", 1, 7, 39, 0, 1999, },
- { "Grafnhsn", 1, 7, 40, 0, 1999, },
- { "BadSaeck", 1, 7, 41, 1991, 1999, },
- { "Immensta", 1, 7, 42, 1991, 1999, },
- { "Altenst2", 1, 7, 43, 1991, 1999, },
- { "St.Georg", 1, 7, 44, 1991, 1999, },
- { "Sulz 3", 1, 7, 45, 1991, 1999, },
- { "Murg2 CH", 1, 7, 46, 1991, 1999, },
- { "Tengen 2", 1, 7, 47, 1991, 1999, },
- { "Waldshut", 1, 7, 48, 1991, 1999, },
- { "Leutkir0", 1, 7, 49, 1991, 1999, },
- { "Triberg2", 1, 7, 50, 1991, 1999, },
- { "Furtwan2", 1, 7, 51, 1991, 1999, },
- { "Tettnang", 1, 7, 52, 1991, 1999, },
- { "Ostrach2", 1, 7, 53, 1991, 1999, },
- { "Haigerl0", 1, 7, 54, 1991, 1999, },
- { "Laichi41", 1, 7, 55, 1991, 0, },
- { "Alpirsb4", 1, 7, 56, 1991, 1999, },
- { "Pfullen1", 1, 7, 57, 1991, 1999, },
- { "Rottwei7", 1, 7, 58, 1991, 1999, },
- { "Guenzb70", 1, 7, 59, 1991, 0, },
- { "Baiersb2", 1, 7, 60, 0, 1999, },
- { "BdWurza1", 1, 7, 61, 1991, 1999, },
- { "Wangen 1", 1, 7, 62, 1991, 1999, },
- { "Markdf 1", 1, 7, 63, 1991, 1999, },
- { "Burladi1", 1, 7, 64, 0, 1999, },
- { "Gammerti", 1, 7, 65, 0, 1999, },
- { "Kissleg2", 1, 7, 66, 1991, 1999, },
- { "Kressbr3", 1, 7, 67, 1991, 1999, },
- { "Freuden0", 1, 7, 69, 0, 1999, },
- { "Geisingn", 1, 7, 70, 1991, 1999, },
- { "Isny 0", 1, 7, 71, 1991, 1999, },
- { "Schelkli", 1, 7, 72, 1991, 0, },
- { "Deggin71", 1, 7, 73, 1991, 0, },
- { "Ochsenha", 1, 7, 74, 1991, 0, },
- { "Ulm D2", 1, 7, 76, 1991, 0, },
- { "Ulm D126", 1, 7, 77, 1991, 0, },
- { "Langenau", 1, 7, 78, 1991, 0, },
- { "Schramb1", 1, 7, 79, 0, 1999, },
- { "Blaustei", 1, 7, 80, 1991, 0, },
- { "Nersinge", 1, 7, 81, 1991, 0, },
- { "Ulm D151", 1, 7, 82, 1991, 0, },
- { "Blaube41", 1, 7, 83, 1991, 0, },
- { "Ulm D172", 1, 7, 84, 1991, 0, },
- { "Ulm D141", 1, 7, 85, 1991, 0, },
- { "Erbach41", 1, 7, 86, 1991, 0, },
- { "Eigelt.2", 1, 7, 87, 1991, 1999, },
- { "Weissenh", 1, 7, 88, 1991, 0, },
- { "Ehingen1", 1, 7, 89, 1991, 0, },
- { "Laupheim", 1, 7, 90, 1991, 0, },
- { "Illertis", 1, 7, 91, 1991, 0, },
- { "Biberbac", 1, 7, 92, 1991, 0, },
- { "Talheim4", 1, 7, 93, 1991, 1999, },
- { "Heiligb0", 1, 7, 94, 1991, 1999, },
- { "Spaichi3", 1, 7, 95, 1991, 1999, },
- { "Blumbg5", 1, 7, 96, 1991, 1999, },
- { "Lindau 7", 1, 7, 97, 1991, 0, },
- { "Obertal2", 1, 7, 98, 0, 1999, },
- { "Engen 4", 1, 7, 99, 0, 1999, },
- { "Besighm", 2, 7, 1, 0, 1999, },
- { "Adelberg", 2, 7, 2, 0, 1999, },
- { "Wildberg", 2, 7, 3, 0, 1999, },
- { "Tuebing7", 2, 7, 4, 1991, 1999, },
- { "Backnang", 2, 7, 5, 0, 1999, },
- { "Goeppin0", 2, 7, 6, 0, 1999, },
- { "Weilhm 1", 2, 7, 7, 0, 1999, },
- { "Tuebing6", 2, 7, 8, 1991, 1999, },
- { "Reutlin0", 2, 7, 10, 1991, 1999, },
- { "Metzing4", 2, 7, 12, 1991, 1999, },
- { "Trochte2", 2, 7, 13, 1991, 1999, },
- { "Ebersbch", 2, 7, 14, 0, 1999, },
- { "Marbac41", 2, 7, 15, 0, 1999, },
- { "BdLiebzl", 2, 7, 16, 0, 1999, },
- { "BdUrach2", 2, 7, 17, 1991, 1999, },
- { "Lichtst2", 2, 7, 18, 1991, 1999, },
- { "Muensin1", 2, 7, 19, 1991, 1999, },
- { "Suessen0", 2, 7, 20, 0, 1999, },
- { "Weinsbg0", 2, 7, 21, 0, 1999, },
- { "Wendli18", 2, 7, 22, 0, 1999, },
- { "Gomadin1", 2, 7, 23, 1991, 1999, },
- { "Backng43", 2, 7, 24, 0, 1999, },
- { "Maulbr42", 2, 7, 25, 0, 1999, },
- { "Ditzing5", 2, 7, 26, 0, 1999, },
- { "Neuens41", 2, 7, 27, 0, 1999, },
- { "Nksulm72", 2, 7, 28, 0, 1999, },
- { "Heilbr41", 2, 7, 29, 0, 1999, },
- { "S41Mitte", 2, 7, 30, 1991, 1999, },
- { "Schwai42", 2, 7, 31, 0, 1999, },
- { "S31Bahnp", 2, 7, 32, 1991, 1999, },
- { "Heilbr 1", 2, 7, 33, 0, 1999, },
- { "Besigh42", 2, 7, 34, 0, 1999, },
- { "S580Merc", 2, 7, 35, 1991, 1999, },
- { "Waiblin3", 2, 7, 36, 1991, 1999, },
- { "Winnend0", 2, 7, 37, 1991, 1999, },
- { "Bracken1", 2, 7, 38, 0, 1999, },
- { "Waiblin4", 2, 7, 39, 1991, 1999, },
- { "Leonbg41", 2, 7, 40, 0, 1999, },
- { "S582 Kas", 2, 7, 41, 1991, 1999, },
- { "BdWimp41", 2, 7, 42, 0, 1999, },
- { "S45 Essl", 2, 7, 43, 1991, 1999, },
- { "Calw 3", 2, 7, 44, 1991, 1999, },
- { "Loewnstn", 2, 7, 45, 0, 1999, },
- { "Sindelfi", 2, 7, 46, 1991, 1999, },
- { "S26Moehr", 2, 7, 47, 1991, 1999, },
- { "S62 Vaih", 2, 7, 48, 1991, 1999, },
- { "WeildStd", 2, 7, 49, 1991, 1999, },
- { "Leonbg 5", 2, 7, 50, 1991, 1999, },
- { "SchwGmd2", 2, 7, 51, 1991, 1999, },
- { "S10Maybc", 2, 7, 52, 1991, 1999, },
- { "Schornd0", 2, 7, 53, 0, 1999, },
- { "Muench51", 2, 7, 54, 1991, 1999, },
- { "Vaihing1", 2, 7, 55, 1991, 1999, },
- { "S589Flug", 2, 7, 56, 1991, 1999, },
- { "Waldenb3", 2, 7, 57, 1991, 1999, },
- { "Ludwbg 2", 2, 7, 58, 1991, 1999, },
- { "S7 FMT", 2, 7, 59, 1991, 1999, },
- { "Plochgn1", 2, 7, 60, 1991, 1999, },
- { "S49Muens", 2, 7, 61, 1991, 1999, },
- { "S0 FA1", 2, 7, 62, 1991, 1999, },
- { "S344Denk", 2, 7, 63, 1991, 1999, },
- { "Ludwbg 3", 2, 7, 64, 1991, 1999, },
- { "Sachse42", 2, 7, 65, 1991, 1999, },
- { "S361Schb", 2, 7, 66, 1991, 1999, },
- { "Vaihin45", 2, 7, 67, 1991, 1999, },
- { "Moensh43", 2, 7, 68, 1991, 1999, },
- { "Ntenzlin", 2, 7, 69, 0, 1999, },
- { "Echterdi", 2, 7, 70, 0, 1999, },
- { "Gomaring", 2, 7, 71, 0, 1999, },
- { "Beilstei", 2, 7, 72, 0, 1999, },
- { "Spraitba", 2, 7, 74, 0, 1999, },
- { "Sulzbach", 2, 7, 75, 0, 1999, },
- { "Lenningn", 2, 7, 76, 0, 1999, },
- { "BadBoll0", 2, 7, 77, 0, 1999, },
- { "Heilbr18", 2, 7, 79, 0, 1999, },
- { "Weinsb42", 2, 7, 80, 0, 1999, },
- { "Lorch 1", 2, 7, 82, 0, 1999, },
- { "Nuerti41", 2, 7, 87, 1991, 1999, },
- { "Marbch71", 2, 7, 89, 1991, 1999, },
- { "Kirchhm0", 2, 7, 90, 1991, 1999, },
- { "Remseck1", 2, 7, 91, 0, 1999, },
- { "Ehningn4", 2, 7, 92, 1991, 1999, },
- { "Ksrsbch1", 2, 7, 93, 0, 1999, },
- { "Neuffen0", 2, 7, 94, 0, 1999, },
- { "DB Oderd", 2, 7, 96, 0, 1999, },
- { "DB Markg", 2, 7, 97, 0, 1999, },
- { "BdnBdn 5", 3, 7, 1, 1991, 1999, },
- { "Pforzhm7", 3, 7, 2, 1991, 1999, },
- { "Loerrac4", 3, 7, 3, 1991, 1999, },
- { "Badenwr1", 3, 7, 4, 1991, 1999, },
- { "Titisee4", 3, 7, 5, 1991, 1999, },
- { "Vogtsbg1", 3, 7, 6, 1991, 1999, },
- { "Grenzach", 3, 7, 7, 0, 1999, },
- { "Hausach1", 3, 7, 8, 1991, 1999, },
- { "Willsta1", 3, 7, 9, 1991, 1999, },
- { "BdHerrn3", 3, 7, 10, 1991, 1999, },
- { "Hagsfeld", 3, 7, 11, 0, 1999, },
- { "Rastatt6", 3, 7, 12, 1991, 1999, },
- { "FrbgTien", 3, 7, 13, 0, 1999, },
- { "Gaggena0", 3, 7, 14, 1991, 1999, },
- { "Efringen", 3, 7, 15, 0, 1999, },
- { "Lichten0", 3, 7, 16, 1991, 1999, },
- { "Eppingn2", 3, 7, 17, 1991, 1999, },
- { "BdRappe0", 3, 7, 18, 1991, 1999, },
- { "Kirchar2", 3, 7, 19, 1991, 1999, },
- { "Oberkir3", 3, 7, 20, 0, 1999, },
- { "Oppenau2", 3, 7, 21, 0, 1999, },
- { "Offenbg0", 3, 7, 22, 0, 1999, },
- { "Lahr 0", 3, 7, 23, 1991, 1999, },
- { "Ettenhm3", 3, 7, 24, 1991, 1999, },
- { "Achern 2", 3, 7, 25, 0, 1999, },
- { "Schwana0", 3, 7, 26, 1991, 1999, },
- { "OberdFle", 3, 7, 27, 0, 1999, },
- { "Pforzhm2", 3, 7, 28, 1991, 1999, },
- { "Freibg51", 3, 7, 29, 1991, 1999, },
- { "Denzlgn0", 3, 7, 30, 1991, 1999, },
- { "Schopfhe", 3, 7, 31, 0, 1999, },
- { "Gengenba", 3, 7, 32, 0, 1999, },
- { "Kirchzn4", 3, 7, 33, 1991, 1999, },
- { "Karlsbad", 3, 7, 34, 1991, 0, },
- { "Waldkch0", 3, 7, 35, 1991, 1999, },
- { "Emmendn0", 3, 7, 36, 1991, 1999, },
- { "Pforzh71", 3, 7, 37, 0, 1999, },
- { "Rheinfe0", 3, 7, 38, 0, 1999, },
- { "BrUntgro", 3, 7, 39, 0, 1999, },
- { "Loerrach", 3, 7, 40, 0, 1999, },
- { "Walzbct1", 3, 7, 41, 1991, 1999, },
- { "KA0 HPA", 3, 7, 42, 1991, 1999, },
- { "Oestrgn1", 3, 7, 43, 1991, 1999, },
- { "KA1 Mba", 3, 7, 44, 1991, 1999, },
- { "Neureut", 3, 7, 45, 1991, 1999, },
- { "Siemens", 3, 7, 46, 1991, 1999, },
- { "Eichstet", 3, 7, 47, 1991, 1999, },
- { "Tho.Mann", 3, 7, 48, 1991, 1999, },
- { "Schlieng", 3, 7, 49, 1991, 1999, },
- { "KlrhDurl", 3, 7, 50, 1991, 0, },
- { "Durmers0", 3, 7, 51, 1991, 1999, },
- { "Malsch 2", 3, 7, 52, 1991, 1999, },
- { "Bruchsal", 3, 7, 53, 1991, 1999, },
- { "Soellngn", 3, 7, 54, 0, 1999, },
- { "Freibg58", 3, 7, 55, 0, 1999, },
- { "Freibg11", 3, 7, 56, 0, 1999, },
- { "Sinshm 7", 3, 7, 57, 1991, 1999, },
- { "Schluchs", 3, 7, 58, 0, 1999, },
- { "Bdn-Bdn0", 3, 7, 59, 0, 1999, },
- { "BdSchoe5", 3, 7, 60, 1991, 1999, },
- { "Linknhm3", 3, 7, 61, 0, 1999, },
- { "BdnBdn 4", 3, 7, 62, 0, 1999, },
- { "St.Blas1", 3, 7, 63, 1991, 1999, },
- { "Wiesloch", 3, 7, 65, 1991, 0, },
- { "Kehl 0", 3, 7, 66, 0, 1999, },
- { "Marxzell", 3, 7, 67, 0, 1999, },
- { "Bretten3", 3, 7, 68, 1991, 1999, },
- { "Muellhm7", 3, 7, 70, 0, 1999, },
- { "Stockach", 3, 7, 73, 1991, 0, },
- { "Sulzburg", 3, 7, 75, 1991, 1999, },
- { "Neuenbg1", 3, 7, 76, 1991, 1999, },
- { "Landau 2", 3, 7, 77, 1991, 1999, },
- { "Forbach4", 3, 7, 79, 0, 1999, },
- { "Germersh", 3, 7, 80, 0, 1999, },
- { "Waghaeu2", 3, 7, 81, 1991, 1999, },
- { "Rheinst3", 3, 7, 82, 1991, 1999, },
- { "Woerth 0", 3, 7, 83, 1991, 1999, },
- { "Ruelzhm3", 3, 7, 84, 1991, 1999, },
- { "Zell iW1", 3, 7, 85, 0, 1999, },
- { "Todtnau3", 3, 7, 86, 1991, 1999, },
- { "Maulbr41", 3, 7, 87, 0, 1999, },
- { "Koenigs2", 3, 7, 88, 1991, 1999, },
- { "Buehl0", 3, 7, 90, 1991, 1999, },
- { "Schoena2", 3, 7, 91, 0, 1999, },
- { "Karlsbd2", 3, 7, 92, 1991, 1999, },
- { "Kenzing3", 3, 7, 93, 0, 1999, },
- { "Schoemb1", 3, 7, 95, 1991, 1999, },
- { "Wildbad3", 3, 7, 96, 1991, 1999, },
- { "Enzkloe1", 3, 7, 97, 1991, 1999, },
- { "Abtsgm41", 4, 7, 1, 0, 1999, },
- { "Bopfingn", 4, 7, 2, 0, 1999, },
- { "Weiker41", 4, 7, 3, 0, 1999, },
- { "Heidenh2", 4, 7, 4, 0, 1999, },
- { "Lauterst", 4, 7, 5, 0, 1999, },
- { "Niedstet", 4, 7, 6, 0, 1999, },
- { "SHASulzd", 4, 7, 7, 0, 1999, },
- { "Gaildf42", 4, 7, 8, 0, 1999, },
- { "Mainhdt1", 4, 7, 9, 0, 1999, },
- { "Schoen41", 4, 7, 10, 0, 1999, },
- { "SchHall0", 4, 7, 11, 0, 1999, },
- { "BdMerge2", 4, 7, 12, 0, 1999, },
- { "Forchtb1", 4, 7, 14, 0, 1999, },
- { "Oehrin41", 4, 7, 15, 0, 1999, },
- { "BdMerg41", 4, 7, 16, 0, 1999, },
- { "Cregling", 4, 7, 17, 0, 1999, },
- { "Braunsba", 4, 7, 18, 0, 1999, },
- { "Schopflo", 4, 7, 19, 0, 1999, },
- { "Kuenzels", 4, 7, 20, 0, 1999, },
- { "Lonsee41", 4, 7, 21, 0, 1999, },
- { "Laichign", 4, 7, 22, 0, 1999, },
- { "Fichtnau", 4, 7, 24, 0, 1999, },
- { "Crailsh2", 4, 7, 25, 0, 1999, },
- { "Untrgroe", 4, 7, 26, 0, 1999, },
- { "Wiesenst", 4, 7, 27, 0, 1999, },
- { "Geislin0", 4, 7, 32, 0, 1999, },
- { "Riedlgn2", 4, 7, 33, 0, 1999, },
- { "Aichste3", 4, 7, 37, 0, 1999, },
- { "Ukochn41", 4, 7, 38, 0, 1999, },
- { "Ellwang1", 4, 7, 40, 0, 1999, },
- { "Gerstetn", 4, 7, 41, 0, 1999, },
- { "Heubach1", 4, 7, 45, 0, 1999, },
- { "Lonsee 1", 4, 7, 46, 0, 1999, },
- { "Nereshm1", 4, 7, 47, 0, 1999, },
- { "Lauchhm", 4, 7, 48, 0, 1999, },
- { "Nersingn", 4, 7, 49, 0, 1999, },
- { "Schnelld", 4, 7, 50, 0, 1999, },
- { "Ebnat 41", 4, 7, 51, 0, 1999, },
- { "Jungingn", 4, 7, 53, 0, 1999, },
- { "Laichi41", 4, 7, 55, 0, 1999, },
- { "Aalen 42", 4, 7, 57, 0, 1999, },
- { "Herbrech", 4, 7, 68, 0, 1999, },
- { "UL1 Bake", 4, 7, 70, 0, 1999, },
- { "Schoen43", 4, 7, 71, 0, 1999, },
- { "Schelkl1", 4, 7, 72, 0, 1999, },
- { "Deggin71", 4, 7, 73, 0, 1999, },
- { "Ochsenh1", 4, 7, 74, 0, 1999, },
- { "Giengen", 4, 7, 75, 0, 1999, },
- { "Seligwlr", 4, 7, 76, 0, 1999, },
- { "Boefingn", 4, 7, 77, 0, 1999, },
- { "Langena1", 4, 7, 78, 0, 1999, },
- { "Oehring3", 4, 7, 79, 0, 1999, },
- { "Blaust41", 4, 7, 80, 0, 1999, },
- { "Ulm 151", 4, 7, 82, 0, 1999, },
- { "Blaube41", 4, 7, 83, 0, 1999, },
- { "Ulm 172", 4, 7, 84, 0, 1999, },
- { "Ulm 141", 4, 7, 85, 0, 1999, },
- { "Erbach41", 4, 7, 86, 0, 1999, },
- { "Senden 0", 4, 7, 87, 0, 1999, },
- { "Weisenh0", 4, 7, 88, 0, 1999, },
- { "Lauphm 0", 4, 7, 90, 0, 1999, },
- { "Illerti0", 4, 7, 91, 0, 1999, },
- { "Biberac6", 4, 7, 92, 0, 1999, },
- { "Ehingen0", 4, 7, 93, 0, 1999, },
- { "Langenb1", 4, 7, 95, 0, 1999, },
- { "Weisweil", 6, 7, 99, 1991, 0, },
- { "Oammerga", 1, 8, 1, 0, 1999, },
- { "Schwinde", 1, 8, 2, 0, 1999, },
- { "BdAiblin", 1, 8, 3, 0, 1999, },
- { "Teisendf", 1, 8, 4, 1991, 1999, },
- { "Miesbach", 1, 8, 5, 0, 1999, },
- { "Oberaudf", 1, 8, 6, 0, 1999, },
- { "Ramsau 1", 1, 8, 7, 1991, 1999, },
- { "Reit iWi", 1, 8, 8, 1991, 1999, },
- { "BdReich2", 1, 8, 9, 1991, 1999, },
- { "Landau 3", 1, 8, 10, 1991, 1999, },
- { "Tann 2", 1, 8, 11, 1991, 1999, },
- { "Neufahrn", 1, 8, 12, 0, 1999, },
- { "Attenkir", 1, 8, 13, 0, 1999, },
- { "Olching", 1, 8, 14, 1991, 1999, },
- { "Seeshaup", 1, 8, 15, 0, 1999, },
- { "Wolfrats", 1, 8, 16, 1991, 1999, },
- { "Starnbe5", 1, 8, 17, 1991, 1999, },
- { "Tittmoni", 1, 8, 18, 1991, 1999, },
- { "Herrschi", 1, 8, 19, 1991, 1999, },
- { "Icking", 1, 8, 20, 1991, 1999, },
- { "BdReich1", 1, 8, 21, 1991, 1999, },
- { "Passau11", 1, 8, 22, 1991, 1999, },
- { "Pfarrkir", 1, 8, 23, 1991, 1999, },
- { "Anger", 1, 8, 24, 1991, 1999, },
- { "Obernzel", 1, 8, 25, 1991, 1999, },
- { "Hohenpbg", 1, 8, 26, 1991, 1999, },
- { "Garmisch", 1, 8, 27, 1991, 1999, },
- { "Grainet", 1, 8, 28, 1991, 1999, },
- { "Glonn 1", 1, 8, 29, 1991, 1999, },
- { "Taufkirc", 1, 8, 30, 0, 1999, },
- { "Freyung1", 1, 8, 31, 1991, 1999, },
- { "Mainburg", 1, 8, 32, 0, 1999, },
- { "Diessen2", 1, 8, 33, 0, 1999, },
- { "Berchtes", 1, 8, 34, 1991, 1999, },
- { "Ffeldbr2", 1, 8, 35, 0, 1999, },
- { "Neufinsi", 1, 8, 36, 0, 1999, },
- { "Murnau70", 1, 8, 37, 0, 1999, },
- { "Landsber", 1, 8, 38, 0, 1999, },
- { "Dingolf2", 1, 8, 39, 0, 1999, },
- { "Grafing", 1, 8, 40, 1991, 1999, },
- { "Muehldf", 1, 8, 41, 0, 1999, },
- { "Grassau2", 1, 8, 42, 0, 1999, },
- { "Ergoldsb", 1, 8, 43, 0, 1999, },
- { "Weyarn 3", 1, 8, 44, 0, 1999, },
- { "Hausham", 1, 8, 45, 0, 1999, },
- { "Freising", 1, 8, 46, 0, 1999, },
- { "Kochel 4", 1, 8, 47, 0, 1999, },
- { "Woerth 1", 1, 8, 48, 0, 1999, },
- { "Holzki62", 1, 8, 49, 0, 1999, },
- { "Dachau91", 1, 8, 50, 0, 1999, },
- { "Flughafn", 1, 8, 51, 0, 1999, },
- { "Petershs", 1, 8, 52, 1991, 1999, },
- { "Roehrmos", 1, 8, 53, 1991, 1999, },
- { "Ruhpold1", 1, 8, 54, 1991, 1999, },
- { "Geltendf", 1, 8, 55, 0, 1999, },
- { "Trostber", 1, 8, 56, 0, 1999, },
- { "Dorfen 1", 1, 8, 57, 1991, 1999, },
- { "Neufins.", 1, 8, 58, 1991, 0, },
- { "Dachau 3", 1, 8, 59, 1991, 1999, },
- { "Vilsbibg", 1, 8, 60, 1991, 1999, },
- { "Mallersd", 1, 8, 61, 0, 1999, },
- { "Mammendf", 1, 8, 62, 0, 1999, },
- { "Traunstn", 1, 8, 63, 1991, 1999, },
- { "MSchwab0", 1, 8, 64, 0, 1999, },
- { "Bernbeur", 1, 8, 65, 1991, 1999, },
- { "Landshut", 1, 8, 66, 1991, 1999, },
- { "Holzki 3", 1, 8, 67, 1991, 1999, },
- { "Rosenhm", 1, 8, 68, 1991, 1999, },
- { "Schnaits", 1, 8, 69, 1991, 1999, },
- { "Waakirch", 1, 8, 70, 1991, 1999, },
- { "Wasserbg", 1, 8, 71, 1991, 1999, },
- { "Prien", 1, 8, 72, 1991, 1999, },
- { "Waldkrai", 1, 8, 73, 1991, 1999, },
- { "Burghaus", 1, 8, 74, 1991, 1999, },
- { "Kirchsee", 1, 8, 75, 1991, 1999, },
- { "Ffeldbr0", 1, 8, 76, 0, 1999, },
- { "Moosinni", 1, 8, 77, 0, 1999, },
- { "Sulzemos", 1, 8, 78, 0, 1999, },
- { "Vilshofn", 1, 8, 79, 0, 1999, },
- { "BayrZell", 1, 8, 80, 0, 1999, },
- { "Reischac", 1, 8, 81, 0, 1999, },
- { "Simbach2", 1, 8, 84, 0, 1999, },
- { "Hauzenbg", 1, 8, 85, 0, 1999, },
- { "Sindlsdf", 1, 8, 86, 0, 1999, },
- { "Zolling", 1, 8, 90, 0, 1999, },
- { "Griesbch", 1, 8, 91, 0, 1999, },
- { "Kochel 1", 1, 8, 92, 0, 1999, },
- { "Isen 1", 1, 8, 93, 1991, 1999, },
- { "Tegernse", 1, 8, 94, 0, 1999, },
- { "Gangkofn", 1, 8, 95, 0, 1999, },
- { "Lenggrie", 1, 8, 96, 0, 1999, },
- { "Mitteln.", 1, 8, 97, 1991, 0, },
- { "Augsburg", 1, 8, 98, 1991, 0, },
- { "Pfeffenh", 1, 8, 99, 1991, 1999, },
- { "Planegg", 2, 8, 2, 0, 1999, },
- { "Studentn", 2, 8, 3, 0, 1999, },
- { "Ahornstr", 2, 8, 4, 0, 1999, },
- { "Oberhach", 2, 8, 5, 0, 1999, },
- { "Saurlach", 2, 8, 6, 0, 1999, },
- { "Vaterst1", 2, 8, 10, 0, 1999, },
- { "M18 Bake", 2, 8, 29, 1991, 1999, },
- { "Blumenst", 2, 8, 30, 1991, 1999, },
- { "Isabella", 2, 8, 31, 1991, 1999, },
- { "Arabella", 2, 8, 32, 1991, 1999, },
- { "Kirchens", 2, 8, 33, 1991, 1999, },
- { "Werinher", 2, 8, 34, 1991, 1999, },
- { "Blutenbu", 2, 8, 37, 1991, 1999, },
- { "Neuherbe", 2, 8, 38, 1991, 1999, },
- { "Am Luess", 2, 8, 39, 1991, 1999, },
- { "Rennbahn", 2, 8, 40, 1991, 1999, },
- { "HeinrLue", 2, 8, 41, 1991, 1999, },
- { "Seybotst", 2, 8, 42, 1991, 1999, },
- { "Baierbst", 2, 8, 43, 1991, 1999, },
- { "M.HansGW", 2, 8, 44, 1991, 0, },
- { "Winfried", 2, 8, 45, 1991, 1999, },
- { "M.Bresla", 2, 8, 46, 1991, 0, },
- { "M.Feldmo", 2, 8, 47, 1991, 0, },
- { "Thalkirc", 2, 8, 48, 1991, 1999, },
- { "PhRidler", 2, 8, 49, 1991, 1999, },
- { "M.Unterf", 2, 8, 50, 1991, 0, },
- { "Garching", 2, 8, 52, 0, 1999, },
- { "Gilching", 2, 8, 54, 0, 1999, },
- { "Germerin", 2, 8, 55, 1991, 1999, },
- { "Untersch", 2, 8, 57, 0, 1999, },
- { "Hoehenki", 2, 8, 58, 0, 1999, },
- { "Baierbrn", 2, 8, 61, 0, 1999, },
- { "Stiftsbo", 2, 8, 84, 0, 1999, },
- { "Alzeyers", 2, 8, 85, 0, 1999, },
- { "Augsbg 1", 3, 8, 1, 0, 1999, },
- { "Augsbg 3", 3, 8, 2, 0, 1999, },
- { "Augsbg10", 3, 8, 3, 0, 1999, },
- { "Pfronten", 3, 8, 4, 0, 1999, },
- { "Dilling0", 3, 8, 5, 0, 1999, },
- { "Affing 2", 3, 8, 6, 0, 1999, },
- { "Aichach", 3, 8, 7, 0, 1999, },
- { "Eichstae", 3, 8, 8, 0, 1999, },
- { "Dirlewng", 3, 8, 9, 0, 1999, },
- { "Eurasbg1", 3, 8, 10, 0, 1999, },
- { "Buchloe1", 3, 8, 11, 0, 1999, },
- { "Krumbach", 3, 8, 12, 0, 1999, },
- { "Meiting0", 3, 8, 13, 0, 1999, },
- { "Mittelnf", 3, 8, 14, 0, 1999, },
- { "Schrobhs", 3, 8, 15, 0, 1999, },
- { "Schwabmn", 3, 8, 16, 0, 1999, },
- { "Thannhsn", 3, 8, 17, 0, 1999, },
- { "Welden 3", 3, 8, 18, 0, 1999, },
- { "Ziemetsh", 3, 8, 19, 0, 1999, },
- { "Guenzb70", 3, 8, 20, 0, 1999, },
- { "Oberstd0", 3, 8, 21, 0, 1999, },
- { "Nesslwan", 3, 8, 22, 0, 1999, },
- { "Neuburg1", 3, 8, 23, 0, 1999, },
- { "Obrstauf", 3, 8, 24, 0, 1999, },
- { "Groenbch", 3, 8, 25, 0, 1999, },
- { "Zusmars2", 3, 8, 26, 0, 1999, },
- { "Fuessen2", 3, 8, 27, 0, 1999, },
- { "Lindau 1", 3, 8, 28, 0, 1999, },
- { "Augsbg 2", 3, 8, 29, 0, 1999, },
- { "Augsb907", 3, 8, 30, 0, 1999, },
- { "Stammham", 3, 8, 33, 0, 1999, },
- { "Ottobeu3", 3, 8, 34, 0, 1999, },
- { "Pfaffen5", 3, 8, 35, 0, 1999, },
- { "Pfaffen0", 3, 8, 36, 0, 1999, },
- { "Burgau 0", 3, 8, 37, 0, 1999, },
- { "Schweitk", 3, 8, 38, 0, 1999, },
- { "IngolZuc", 3, 8, 39, 0, 1999, },
- { "Vohburg1", 3, 8, 40, 0, 1999, },
- { "Wolnzach", 3, 8, 41, 0, 1999, },
- { "Tapfheim", 3, 8, 42, 0, 1999, },
- { "Unterrin", 3, 8, 43, 0, 1999, },
- { "Kaisheim", 3, 8, 44, 0, 1999, },
- { "Altensta", 3, 8, 51, 0, 1999, },
- { "Aitrang2", 3, 8, 52, 0, 1999, },
- { "Babenhsn", 3, 8, 54, 0, 1999, },
- { "Gruenenb", 3, 8, 55, 0, 1999, },
- { "Immensta", 3, 8, 57, 0, 1999, },
- { "Kaufbeur", 3, 8, 58, 0, 1999, },
- { "Memmingn", 3, 8, 59, 0, 1999, },
- { "Oguenzbg", 3, 8, 61, 0, 1999, },
- { "Sonthofn", 3, 8, 67, 0, 1999, },
- { "Weiler 1", 3, 8, 68, 0, 1999, },
- { "Wiggensb", 3, 8, 70, 0, 1999, },
- { "Neuburg", 3, 8, 78, 0, 1999, },
- { "Poernbch", 3, 8, 81, 0, 1999, },
- { "Arnstein", 1, 9, 1, 0, 1999, },
- { "BdSteben", 1, 9, 2, 0, 1999, },
- { "Bayr.Eis", 1, 9, 3, 0, 1999, },
- { "Berg 2", 1, 9, 4, 0, 1999, },
- { "Rottendf", 1, 9, 5, 0, 1999, },
- { "Werneck2", 1, 9, 6, 0, 1999, },
- { "Bayreuth", 1, 9, 7, 0, 1999, },
- { "Kulmbach", 1, 9, 8, 0, 1999, },
- { "Trockau", 1, 9, 9, 1991, 0, },
- { "Pressig", 1, 9, 10, 0, 1999, },
- { "Bi.gruen", 1, 9, 11, 0, 1999, },
- { "Hof 2", 1, 9, 12, 1991, 1999, },
- { "Kist 1", 1, 9, 13, 0, 1999, },
- { "Bodenwhr", 1, 9, 14, 0, 1999, },
- { "Burgleng", 1, 9, 15, 0, 1999, },
- { "Burgwind", 1, 9, 16, 0, 1999, },
- { "Buttenhm", 1, 9, 17, 0, 1999, },
- { "Iphofen", 1, 9, 18, 1991, 1999, },
- { "Cham", 1, 9, 19, 0, 1999, },
- { "Tauberbh", 1, 9, 20, 1991, 1999, },
- { "Unterple", 1, 9, 21, 1991, 1999, },
- { "Uettingn", 1, 9, 22, 1991, 1999, },
- { "Erbendor", 1, 9, 23, 0, 1999, },
- { "Deggendf", 1, 9, 24, 0, 1999, },
- { "ObThulb3", 1, 9, 25, 0, 1999, },
- { "Laaber", 1, 9, 26, 0, 1999, },
- { "Seubersd", 1, 9, 27, 0, 1999, },
- { "Riedenbu", 1, 9, 28, 0, 1999, },
- { "Obwerrn", 1, 9, 29, 0, 1999, },
- { "Abensber", 1, 9, 31, 0, 1999, },
- { "Hemau", 1, 9, 32, 0, 1999, },
- { "Hirschau", 1, 9, 33, 0, 1999, },
- { "Hofheim", 1, 9, 34, 0, 1999, },
- { "Karlstdt", 1, 9, 35, 0, 1999, },
- { "Kelheim", 1, 9, 36, 0, 1999, },
- { "Bamberg6", 1, 9, 37, 0, 1999, },
- { "Obaurach", 1, 9, 38, 0, 1999, },
- { "Pfarrwei", 1, 9, 39, 0, 1999, },
- { "Kirchlau", 1, 9, 40, 0, 1999, },
- { "Schessli", 1, 9, 41, 0, 1999, },
- { "Zapfendf", 1, 9, 42, 0, 1999, },
- { "Beratzhs", 1, 9, 43, 0, 1999, },
- { "Rehau 1", 1, 9, 44, 0, 1999, },
- { "NeustdCO", 1, 9, 45, 0, 1999, },
- { "Kronach", 1, 9, 46, 0, 1999, },
- { "Langquai", 1, 9, 47, 0, 1999, },
- { "Amberg", 1, 9, 48, 0, 1999, },
- { "Pleystei", 1, 9, 49, 0, 1999, },
- { "LaudaKoe", 1, 9, 50, 0, 1999, },
- { "Lichtenf", 1, 9, 51, 0, 1999, },
- { "Muenners", 1, 9, 53, 0, 1999, },
- { "Meeder", 1, 9, 54, 0, 1999, },
- { "BdKissin", 1, 9, 55, 0, 1999, },
- { "Hammelbu", 1, 9, 56, 1991, 1999, },
- { "Mktheid2", 1, 9, 59, 0, 1999, },
- { "Straubin", 1, 9, 60, 0, 1999, },
- { "Schoefwg", 1, 9, 61, 0, 1999, },
- { "Koetztin", 1, 9, 62, 0, 1999, },
- { "Illschwa", 1, 9, 64, 0, 1999, },
- { "Oberbach", 1, 9, 66, 0, 1999, },
- { "Oberviec", 1, 9, 67, 0, 1999, },
- { "Ochsnft3", 1, 9, 68, 0, 1999, },
- { "Pfatter", 1, 9, 69, 0, 1999, },
- { "Regensb1", 1, 9, 70, 0, 1999, },
- { "Regensb4", 1, 9, 71, 0, 1999, },
- { "Schweinf", 1, 9, 72, 0, 1999, },
- { "Selb 1", 1, 9, 73, 0, 1999, },
- { "Stallwan", 1, 9, 74, 0, 1999, },
- { "BdKoenig", 1, 9, 75, 0, 1999, },
- { "Alladorf", 1, 9, 76, 0, 1999, },
- { "Tirschen", 1, 9, 77, 0, 1999, },
- { "Waldmuen", 1, 9, 78, 0, 1999, },
- { "Weiden", 1, 9, 79, 0, 1999, },
- { "WGamburg", 1, 9, 80, 0, 1999, },
- { "Wiesenth", 1, 9, 81, 0, 1999, },
- { "Wuerzbg2", 1, 9, 82, 0, 1999, },
- { "Wunsiedl", 1, 9, 83, 0, 1999, },
- { "Zell2 OF", 1, 9, 84, 0, 1999, },
- { "Trockau1", 1, 9, 85, 0, 1999, },
- { "Mitterfs", 1, 9, 87, 0, 1999, },
- { "Nabburg2", 1, 9, 88, 0, 1999, },
- { "Obernses", 1, 9, 90, 0, 1999, },
- { "Roding 1", 1, 9, 91, 0, 1999, },
- { "Gerchsh1", 1, 9, 93, 0, 1999, },
- { "Coburg", 1, 9, 94, 0, 1999, },
- { "DB Karls", 1, 9, 96, 0, 1999, },
- { "DB Wuerz", 1, 9, 97, 0, 1999, },
- { "Waldsass", 1, 9, 98, 0, 1999, },
- { "Zell 1BW", 1, 9, 99, 0, 1999, },
- { "Nuernbg0", 2, 9, 1, 0, 1999, },
- { "Miltenb.", 2, 9, 2, 1991, 0, },
- { "Unterri.", 2, 9, 3, 1991, 0, },
- { "N5 Bake", 2, 9, 4, 1991, 1999, },
- { "Nennslin", 2, 9, 5, 1991, 1999, },
- { "Betzenst", 2, 9, 6, 1991, 1999, },
- { "Alladorf", 2, 9, 7, 1991, 0, },
- { "Zell", 2, 9, 8, 1991, 0, },
- { "Schnaitt", 2, 9, 9, 1991, 1999, },
- { "Wiesent.", 2, 9, 11, 1991, 0, },
- { "Regensb.", 2, 9, 12, 1991, 0, },
- { "Hemau", 2, 9, 13, 1991, 0, },
- { "Rothenbu", 2, 9, 14, 1991, 1999, },
- { "Buttenh.", 2, 9, 15, 1991, 0, },
- { "Hofheim", 2, 9, 16, 1991, 0, },
- { "Meeder", 2, 9, 17, 1991, 0, },
- { "Weiden", 2, 9, 18, 1991, 0, },
- { "Roth 0", 2, 9, 19, 1991, 1999, },
- { "Altdorf", 2, 9, 20, 1991, 1999, },
- { "Feucht", 2, 9, 21, 0, 1999, },
- { "Bischof.", 2, 9, 22, 1991, 0, },
- { "Ansbach", 2, 9, 23, 1991, 1999, },
- { "Deggend.", 2, 9, 25, 1991, 0, },
- { "Bay.Eis.", 2, 9, 26, 1991, 0, },
- { "OPD", 2, 9, 27, 1991, 1999, },
- { "Marienbg", 2, 9, 28, 1991, 1999, },
- { "Nbg Thus", 2, 9, 29, 1991, 0, },
- { "BfArbeit", 2, 9, 30, 1991, 1999, },
- { "HeizKW", 2, 9, 31, 1991, 1999, },
- { "Eschenbc", 2, 9, 32, 0, 1999, },
- { "M.Verlag", 2, 9, 33, 1991, 1999, },
- { "Lauf", 2, 9, 34, 1991, 1999, },
- { "Postbaur", 2, 9, 35, 1991, 1999, },
- { "Schwaba5", 2, 9, 36, 1991, 1999, },
- { "HerzogAu", 2, 9, 37, 1991, 1999, },
- { "Langenzn", 2, 9, 38, 1991, 1999, },
- { "Erlangn1", 2, 9, 39, 1991, 1999, },
- { "Kronach", 2, 9, 40, 1991, 0, },
- { "FuerthCi", 2, 9, 41, 0, 1999, },
- { "Stadeln", 2, 9, 42, 0, 1999, },
- { "Tr.Adler", 2, 9, 43, 1991, 1999, },
- { "Siegelsd", 2, 9, 44, 1991, 1999, },
- { "Rosstal", 2, 9, 45, 1991, 1999, },
- { "ER98 GWE", 2, 9, 46, 0, 1999, },
- { "Burglen.", 2, 9, 47, 1991, 0, },
- { "Cham", 2, 9, 48, 1991, 0, },
- { "SulzbRos", 2, 9, 49, 0, 1999, },
- { "Obervie.", 2, 9, 50, 1991, 0, },
- { "Eckental", 2, 9, 51, 0, 1999, },
- { "Gemuend.", 2, 9, 52, 1991, 0, },
- { "Pumpwerk", 2, 9, 53, 0, 1999, },
- { "Wendelst", 2, 9, 54, 0, 1999, },
- { "Schweinf", 2, 9, 55, 1991, 0, },
- { "ER60Tenn", 2, 9, 56, 0, 1999, },
- { "Wunsied.", 2, 9, 57, 1991, 0, },
- { "BPolizei", 2, 9, 58, 0, 1999, },
- { "Hessdorf", 2, 9, 60, 0, 1999, },
- { "Treuchtl", 2, 9, 61, 0, 1999, },
- { "Solnhofn", 2, 9, 62, 0, 1999, },
- { "Pommelsb", 2, 9, 63, 0, 1999, },
- { "Neustadt", 2, 9, 64, 1991, 1999, },
- { "Langenfd", 2, 9, 65, 1991, 1999, },
- { "AlbThaer", 2, 9, 66, 0, 1999, },
- { "Graefenb", 2, 9, 67, 0, 1999, },
- { "Hoechstd", 2, 9, 68, 0, 1999, },
- { "Ebermann", 2, 9, 69, 0, 1999, },
- { "Schwaba0", 2, 9, 70, 0, 1999, },
- { "Uffenhm", 2, 9, 71, 0, 1999, },
- { "Wilherms", 2, 9, 72, 0, 1999, },
- { "Thalmae2", 2, 9, 73, 0, 1999, },
- { "Wittelsh", 2, 9, 74, 0, 1999, },
- { "Windsbac", 2, 9, 76, 0, 1999, },
- { "Gunzenhs", 2, 9, 78, 0, 1999, },
- { "Allersbg", 2, 9, 79, 0, 1999, },
- { "Wiesentl", 2, 9, 80, 0, 1999, },
- { "Esselb.", 2, 9, 81, 1991, 0, },
- { "Forchhei", 2, 9, 82, 0, 1999, },
- { "Heilsbrn", 2, 9, 85, 0, 1999, },
- { "Altenbg", 2, 9, 86, 0, 1999, },
- { "Muehlhsn", 2, 9, 88, 0, 1999, },
- { "Kelheim", 2, 9, 91, 1991, 0, },
- { "Kipfenbg", 2, 9, 93, 0, 1999, },
- { "Burgbern", 2, 9, 94, 1991, 1999, },
- { "Lichtenf", 2, 9, 98, 1991, 0, },
- { "Greding", 2, 9, 99, 1991, 1999, },
- { "FTZ Example",1, 1, 38, 1991, 0, }, /* use in FTZ standard as example */
- { "", 0, 0, 0, 0, 0, },
+/* Langer-Name Kurzer Name, Nat FuVST Rest */
+ { "Oberhausen 32", "OB32", 1, 2, 1, },
+ { "Oberhausen 0 <prov.>", "OB0", 1, 2, 5, },
+ { "Wuppertal 18", "WUP18", 1, 2, 6, },
+ { "Oberhausen 21", "OB21", 1, 2, 7, },
+ { "Duisburg 21", "DUI21", 1, 2, 8, },
+ { "Heiligenhaus 0", "HEIL0", 1, 2, 9, },
+ { "Essen 1 <Fernmeldeamt>", "ES1", 1, 2, 10, },
+ { "Velbert-Langenberg 2", "VELL2", 1, 2, 11, },
+ { "Duisburg 40 <Ers.f.OB16>", "DUI40", 1, 2, 12, },
+ { "Bottrop 0", "BOT0", 1, 2, 13, },
+ { "Gelsenkirchen 1", "GSK1", 1, 2, 14, },
+ { "Essen 35", "ES35X", 1, 2, 15, },
+ { "Duisburg 25", "DUI25", 1, 2, 16, },
+ { "Velbert-Neviges", "VELN", 1, 2, 17, },
+ { "Wuppertal 30", "WUP30", 1, 2, 18, },
+ { "Essen 28 (Borbeck)", "ESBCK", 1, 2, 19, },
+ { "Kirchhellen 4", "KIRCH", 1, 2, 20, },
+ { "Gelsenkirchen 7", "GSK7", 1, 2, 21, },
+ { "Wuppertal 34", "WUP34", 1, 2, 22, },
+ { "Wuppertal 35 <Rheinshagen>", "WUPE11", 1, 2, 23, },
+ { "Oberhausen 23", "OB23", 1, 2, 24, },
+ { "Velbert-Neviges 4", "WFRTH3", 1, 2, 25, },
+ { "Duisburg 42 <Ers.f.DUI39>", "DUI42", 1, 2, 26, },
+ { "Rheinhausen 0", "RHSN0", 1, 2, 27, },
+ { "Essen 12", "ES12", 1, 2, 28, },
+ { "Homberg 1", "HOMB1", 1, 2, 29, },
+ { "Rees-Mehr 0", "REME0", 1, 2, 30, },
+ { "Essen 13", "ES13", 1, 2, 31, },
+ { "Essen 15", "ES15", 1, 2, 32, },
+ { "Heiden 1", "HEID0", 1, 2, 33, },
+ { "Voerde 2", "VOER2", 1, 2, 34, },
+ { "Duisburg 0", "DUI0", 1, 2, 35, },
+ { "Velbert 1 <20 Grad geneigt>", "VEL1", 1, 2, 36, },
+ { "Oberhausen 26", "OB26", 1, 2, 37, },
+ { "Gelsenkirchen 58", "GSK58", 1, 2, 38, },
+ { "Essen 8", "ES8", 1, 2, 39, },
+ { "Wuppertal 8 (Hahnerberg)", "WUP8", 1, 2, 40, },
+ { "Oberhausen 18 (Heimaterde)", "OB18", 1, 2, 41, },
+ { "Oberhausen 30 (Osterfeld)", "OB30", 1, 2, 43, },
+ { "Wesel 0 <Mischbake>", "WSL", 1, 2, 44, },
+ { "Borken 0", "BOR0", 1, 2, 45, },
+ { "Velen 20", "RSDF", 1, 2, 46, },
+ { "Bocholt 0", "BOH0", 1, 2, 47, },
+ { "Huenxe 1", "HXE0", 1, 2, 48, },
+ { "Isselburg 1", "ISSB99", 1, 2, 49, },
+ { "Emmerich-Elten 1", "ELT1X", 1, 2, 50, },
+ { "Bochum-Wattenscheid 3", "BOC3", 1, 2, 51, },
+ { "Dorsten 0", "DSTN0", 1, 2, 52, },
+ { "Schermbeck 2", "SBCK", 1, 2, 53, },
+ { "Raesfeld 2 (Erle)", "RAEF0", 1, 2, 54, },
+ { "Wuppertal 4 (Beyenburg)", "WUP4", 1, 2, 55, },
+ { "Hueckeswagen 2", "HUECK1", 1, 2, 57, },
+ { "Herne 1", "HER", 1, 2, 58, },
+ { "Bochum 47", "BOC47", 1, 2, 59, },
+ { "Hattingen 9 (Holthausen)", "HATT", 1, 2, 60, },
+ { "Sprockhoevel 71 (12Grad gen.)", "HATT71", 1, 2, 61, },
+ { "Gladbeck 20", "GLAD20", 1, 2, 62, },
+ { "Ahaus 0", "AH0", 1, 2, 63, },
+ { "Bochum 1 <Ant. 20 grad gen.>", "BOC1", 1, 2, 64, },
+ { "Herten 0.80D1 <Zeche Ewald>", "HERT", 1, 2, 66, },
+ { "Oberhausen 1", "OB1", 1, 2, 68, },
+ { "Dorsten-Wulfen 0", "DORS0", 1, 2, 70, },
+ { "Essen 0 (Kettwig)", "ESKTW", 1, 2, 76, },
+ { "Vreden 0", "VRDN0", 1, 2, 79, },
+ { "Gronau 0", "GRON0", 1, 2, 81, },
+ { "Dinslaken 2", "DIN2", 1, 2, 82, },
+ { "Bochum 78 (Stiepel)<neu>", "BOC78", 1, 2, 84, },
+ { "Bochum 0", "BOC0", 1, 2, 88, },
+ { "Oberhausen 9 (Bake)", "OB9", 1, 2, 89, },
+ { "Coesfeld 0", "COE0", 1, 2, 92, },
+ { "Schoeppingen 1", "SPP12", 1, 2, 93, },
+ { "Stadtlohn 1", "STLN1", 1, 2, 98, },
+ { "Wuppertal 2 (Bake)", "WUP2", 1, 2, 99, },
+ { "Raegelin 1", "DKOW", 1, 3, 1, },
+ { "Fuerstenberg 1", "FTBG", 1, 3, 3, },
+ { "Maerkisch-Buchholz 3", "MAS", 1, 3, 4, },
+ { "Beeskow 0", "BEES", 1, 3, 5, },
+ { "Finowfurt 1", "EBSW", 1, 3, 6, },
+ { "Blnklz 503 Bernau 6 (B-Aue)", "BKLZ37", 1, 3, 7, },
+ { "Ziesar 0 <Ers.f.TRANS3>", "ZIES0", 1, 3, 8, },
+ { "Wittenberge 4", "WIBG", 1, 3, 9, },
+ { "Blnklz 505(Werder Havel 1)", "TRANS5", 1, 3, 10, },
+ { "Seelow 4", "SEEL", 1, 3, 11, },
+ { "Blnklz 313(Treseburger Str)", "BKLZ47", 1, 3, 12, },
+ { "Briesen 0", "BRIE", 1, 3, 13, },
+ { "Perleberg 4", "PLBG", 1, 3, 14, },
+ { "Muencheberg 4", "MUEN4", 1, 3, 15, },
+ { "Herzfelde 3", "HF3", 1, 3, 16, },
+ { "Storkow 4 <Ers.f.STOR>", "STORK", 1, 3, 17, },
+ { "Neubrandenburg 14", "NBBG", 1, 3, 18, },
+ { "Treuenbrietzen 0", "TREUB", 1, 3, 19, },
+ { "Prenzlau 3", "PZL", 1, 3, 20, },
+ { "Pasewalk 2", "PAWA2", 1, 3, 22, },
+ { "NaumbgRi ???", "???", 1, 3, 23, },
+ { "Rathenow 4", "RATH4", 1, 3, 24, },
+ { "Blnklz 414(B.-Apitz-Str7)", "BKLZ54", 1, 3, 26, },
+ { "Blnklz 406(Jaegerstieg)", "B25", 1, 3, 27, },
+ { "Templin 2", "TPL", 1, 3, 28, },
+ { "Luckenwalde 2", "LCKW", 1, 3, 29, },
+ { "Lehnin 0", "LEHN0", 1, 3, 30, },
+ { "Frankfurt/Oder 10", "FFO", 1, 3, 31, },
+ { "Blnklz 604 (Michendorf)", "MICHD", 1, 3, 32, },
+ { "Trebbin 2", "LWD", 1, 3, 33, },
+ { "Gramzow 2", "GRAM0", 1, 3, 35, },
+ { "Bad Freienwalde 0", "PLF", 1, 3, 36, },
+ { "Falkenhage 4", "PRD", 1, 3, 37, },
+ { "Fuerstenwalde 7", "RBG", 1, 3, 38, },
+ { "Angermuende 7", "TLF", 1, 3, 39, },
+ { "Wittstock 5", "WTT", 1, 3, 40, },
+ { "Dambeck 2", "WOZ", 1, 3, 41, },
+ { "Neuzelle 3", "EIHS", 1, 3, 42, },
+ { "Raben 1", "RAB", 1, 3, 43, },
+ { "Toepchin 3", "TOEP3", 1, 3, 44, },
+ { "Brandenburg 16", "BDB", 1, 3, 45, },
+ { "Jueterbog 4", "JTB", 1, 3, 46, },
+ { "Brandenburg 2<Ers.f.TRANS4>", "KRAN", 1, 3, 47, },
+ { "Lieberose 1", "LIEB99", 1, 3, 48, },
+ { "Wiesenburg Mark 0", "WIESB", 1, 3, 49, },
+ { "Mirow 1", "MIROW", 1, 3, 50, },
+ { "Rhinow 1", "RNOW", 1, 3, 51, },
+ { "Rheinsberg 3", "ZHLN", 1, 3, 52, },
+ { "Petkus 3", "PETK", 1, 3, 53, },
+ { "Blankensee 1", "KEUL", 1, 3, 54, },
+ { "Neustrelitz 6", "NEUST6", 1, 3, 55, },
+ { "Greifenberg 1", "GREI1", 1, 3, 57, },
+ { "Pritzwalk 6", "PTZW", 1, 3, 58, },
+ { "Schwedt 6", "SCHDT", 1, 3, 59, },
+ { "Schmoelln 1", "SMLL", 1, 3, 62, },
+ { "Woldegk 4", "WOCK", 1, 3, 65, },
+ { "Neuruppin 6", "NRP", 1, 3, 66, },
+ { "Belzig 2", "BELZ", 1, 3, 67, },
+ { "Gransee 1", "GRAS", 1, 3, 69, },
+ { "Kyritz 4", "KYRZ", 1, 3, 70, },
+ { "Gross Doelln 0", "GDOE", 1, 3, 71, },
+ { "Premnitz 0", "RATH", 1, 3, 72, },
+ { "Gloewen 2", "GLOE2", 1, 3, 73, },
+ { "Luebben 2", "LBN", 1, 3, 74, },
+ { "Blnklz 502(Bestensee 3)", "BKLZ38", 1, 3, 76, },
+ { "Blnklz 504(Pausin 1)", "BKLZ39", 1, 3, 77, },
+ { "Golssen 0", "GOLN0", 1, 3, 78, },
+ { "Luebbenau 2", "LUEB2", 1, 3, 79, },
+ { "Blnklz 410(Alt-Mahlsdorf)", "BKLZ51", 1, 3, 80, },
+ { "Blnklz 412(Eichhorster S.)", "BKLZ53", 1, 3, 81, },
+ { "Blnklz 416(Muehlenbeck 2)", "BKLZ55", 1, 3, 83, },
+ { "Blnklz 417(Hennigsdorf 0)", "BKLZ63", 1, 3, 84, },
+ { "Blnklz 506(Ludwigsfelde 3)", "BKLZ57", 1, 3, 86, },
+ { "Blnklz 507(Ruedersdorf 1)", "BKLZ58", 1, 3, 87, },
+ { "Blnklz 508(Strausberg 1)", "BKLZ59", 1, 3, 88, },
+ { "Blnklz 509(Zossen 5)", "BKLZ60", 1, 3, 89, },
+ { "Blnklz 510(Mahlow 4)", "BKLZ72", 1, 3, 90, },
+ { "Blnklz 511(Bernau 3)", "BKLZ64", 1, 3, 91, },
+ { "Blnklz 513(Oranienburg 3)", "BKLZ65", 1, 3, 92, },
+ { "Blnklz 514(Falkensee 1)", "BKLZ66", 1, 3, 93, },
+ { "Liebenwalde 2", "LIEBW2", 1, 3, 94, },
+ { "Eberswalde 8", "EBSW8", 1, 3, 96, },
+ { "Blnklz 512(Erkner 8)", "BKLZ81", 1, 3, 97, },
+ { "Blnklz 515(KWH 2)", "BKLZ74", 1, 3, 98, },
+ { "Blnklz 605(Fichtenwalde 1)", "BKLZ70", 1, 3, 99, },
+ { "Reinfeld 10", "REIF10", 1, 4, 3, },
+ { "Gudow 10", "GUD0", 1, 4, 9, },
+ { "Travemuende 7", "TRV7", 1, 4, 10, },
+ { "Kiel 2", "KIL2", 1, 4, 11, },
+ { "Rendsburg 2 (Preus.Elekt)", "RDB", 1, 4, 17, },
+ { "Nortorf 4", "NORTO4", 1, 4, 18, },
+ { "Freienwill 4", "FRW4", 1, 4, 19, },
+ { "Westerland 0", "WLD0", 1, 4, 20, },
+ { "Heide Holst 2", "HEI2", 1, 4, 22, },
+ { "Hennstedt b Itzehoe 1", "HNI1", 1, 4, 23, },
+ { "Bredstedt 3", "BST3", 1, 4, 24, },
+ { "Brunsbuettel 1", "BRB1", 1, 4, 30, },
+ { "Luebeck 2", "LCK2", 1, 4, 31, },
+ { "Luebeck 4", "LCK4", 1, 4, 32, },
+ { "Itzehoe 2 (Polizei)", "ITZH", 1, 4, 36, },
+ { "Glueckstadt 1", "GLS1", 1, 4, 40, },
+ { "Ploen 1", "PLN2", 1, 4, 44, },
+ { "Burg/Fehmarn 1", "FEHM1", 1, 4, 46, },
+ { "Hartenholm 0", "HHLM0", 1, 4, 50, },
+ { "Daenischenhagen 1", "DAEN1", 1, 4, 52, },
+ { "Luebeck 9", "LCK9", 1, 4, 53, },
+ { "Henstedt-Ulzburg 4", "HNU4", 1, 4, 55, },
+ { "Luebeck 23", "LCK23", 1, 4, 56, },
+ { "Schoenwalde 1", "SCE1", 1, 4, 57, },
+ { "Ratzeburg 1", "RATZ1", 1, 4, 58, },
+ { "Schwarzenbek 1", "SWB1", 1, 4, 59, },
+ { "Elmshorn 10", "EHN10", 1, 4, 61, },
+ { "Eckernfoerde 5", "ECKF5", 1, 4, 62, },
+ { "Husum 0", "HUS0", 1, 4, 66, },
+ { "Marne 0", "MARN0", 1, 4, 72, },
+ { "Neumuenster 10", "NEUM10", 1, 4, 73, },
+ { "Suederluegum 1", "SUED1", 1, 4, 76, },
+ { "Garding 1", "GARD1", 1, 4, 81, },
+ { "Hohenfelde 0", "HFLD0", 1, 4, 82, },
+ { "Ahrensboek 1", "ABK0", 1, 4, 83, },
+ { "Schleswig 4", "SLWG4", 1, 4, 86, },
+ { "Wankendorf", "WAN", 1, 4, 90, },
+ { "Wyk/Foehr 0", "WYK", 1, 4, 94, },
+ { "Bad Segeberg 0", "BSE0", 1, 4, 95, },
+ { "Kappeln 1", "KPN1", 1, 4, 96, },
+ { "Suelfeld 1", "SFD1", 1, 4, 99, },
+ { "Hamburg 22 (Lagerstr.2)", "H22", 2, 4, 1, },
+ { "Buxtehude 0", "BUX0", 2, 4, 2, },
+ { "Buchholz 0 (Nordheide)", "BUCH0", 2, 4, 3, },
+ { "Egestorf 1", "EGT1", 2, 4, 4, },
+ { "Lueneburg 3", "LUE3", 2, 4, 5, },
+ { "Marxen 2 (Ramelsloh)", "MARX2", 2, 4, 6, },
+ { "Wulfsen 10", "WULF10", 2, 4, 8, },
+ { "Pinneberg 7 (Z 31)", "HHKL31", 2, 4, 9, },
+ { "Hamburg 291 (Barsbuet. Z 43)", "HHKL43", 2, 4, 10, },
+ { "Hamburg 141 (Poppenbue.Z 41)", "PBTL", 2, 4, 11, },
+ { "Hamburg 184 (Allerm. Z 42)", "H159", 2, 4, 12, },
+ { "Hamburg 282 (PA90 Harb.Z44)", "HRBG", 2, 4, 13, },
+ { "Sauensiek 0", "SAUS0", 2, 4, 14, },
+ { "Betzendorf 1", "BETZ1", 2, 4, 15, },
+ { "Tostedt 0", "TOST0", 2, 4, 17, },
+ { "Hamburg 256 (Philips Z 38)", "HHKL38", 2, 4, 18, },
+ { "Hamburg 316 (Klockm. Z 56)", "HHKL56", 2, 4, 24, },
+ { "Hamburg 650 (Bauerbgwg Z66)", "HHKL66", 2, 4, 25, },
+ { "Trittau 10", "TTAU10", 2, 4, 26, },
+ { "Hamburg 104 (PA2 Z 0)", "HHKL0", 2, 4, 27, },
+ { "Hamburg PA701(Wandsb. Z 67)", "HHKL67", 2, 4, 28, },
+ { "Hamburg 105 (Schulgwg.Z 12)", "HHKL12", 2, 4, 30, },
+ { "Hamburg 261 (Altona Z 13)", "HHKL13", 2, 4, 31, },
+ { "Hamburg 257 (Fachhsch.Z 14)", "HHKL14", 2, 4, 32, },
+ { "Hamburg 1 (FVSt Z 15)", "HHKL15", 2, 4, 33, },
+ { "Hamburg 12 (FVSt 42 Z 16)", "HHKL16", 2, 4, 34, },
+ { "Hamburg 133 (Modezent.Z 21)", "HHKL21", 2, 4, 35, },
+ { "Hamburg 531 (Langenh. Z 69)", "LANGH", 2, 4, 36, },
+ { "Hamburg 259 (Acht.Born Z23)", "HHKL23", 2, 4, 37, },
+ { "Hamburg 77 (Finkenw. Z 24)", "HHKL24", 2, 4, 38, },
+ { "Hamburg 76 (Waltersh.Z 25)", "HHKL25", 2, 4, 39, },
+ { "Hamburg 5891B (Wilhelmsb.)", "WILHB", 2, 4, 40, },
+ { "Hamburg 60 (Rothenb. Z 27)", "HHKL27", 2, 4, 41, },
+ { "Hamburg 6 (Hamm Z 28)", "HHKL28", 2, 4, 42, },
+ { "Hamburg 46 (Steilsh. Z 29)", "HHKL29", 2, 4, 43, },
+ { "Hamburg 326 (Ammersbk.Z 70)", "OHLS", 2, 4, 44, },
+ { "Hamburg 263 (NeuWulmst.Z34)", "HHKL34", 2, 4, 47, },
+ { "Seevetal 3 (Z 35)", "HHKL35", 2, 4, 48, },
+ { "Rosengarten 1 (Z 36)", "HHKL36", 2, 4, 49, },
+ { "Hamburg 24 (R.LindeWg.Z37)", "HHKL37", 2, 4, 50, },
+ { "Hamburg 65 (Norderst.Z 39)", "HHKL39", 2, 4, 52, },
+ { "Hamburg 260 (FA 4 Z 11)", "HHKL11", 2, 4, 53, },
+ { "Hamburg 258 (Randowstr.Z22)", "HHKL22", 2, 4, 54, },
+ { "Marschacht 10", "MSCH0", 2, 4, 56, },
+ { "Winsen/Luhe 0", "WINS0", 2, 4, 58, },
+ { "Ahrensburg 11 (Z 46)", "SIK1", 2, 4, 60, },
+ { "Wedel 11", "WDL11", 2, 4, 64, },
+ { "Hamburg 306 (Marmstorf Z47)", "HHKL70", 2, 4, 68, },
+ { "Hollenstedt 10", "HSTD1", 2, 4, 69, },
+ { "Uetersen 2", "UETS2", 2, 4, 70, },
+ { "Bad Oeynhausen", "BOEY0", 1, 5, 2, },
+ { "Bad Salzuflen 5", "SUFL", 1, 5, 3, },
+ { "Bohmte 0", "BOTE0", 1, 5, 4, },
+ { "Buende 2", "BUEN2", 1, 5, 5, },
+ { "Delbrueck 1", "DELB", 1, 5, 6, },
+ { "Extertal 2", "EXT2", 1, 5, 7, },
+ { "Bad Pyrmont 1", "PYR1", 1, 5, 9, },
+ { "Luegde-Rischenau 1", "LGR1", 1, 5, 10, },
+ { "Ibbenbueren 4", "IBB", 1, 5, 11, },
+ { "Bramsche-Engter 1", "BME1", 1, 5, 12, },
+ { "Barnstorf 0", "BARN0", 1, 5, 13, },
+ { "Herford 4", "HFS", 1, 5, 14, },
+ { "Luebbecke 1", "LBBK1", 1, 5, 16, },
+ { "Lingen 0", "LIN", 1, 5, 17, },
+ { "Bielefeld 0", "BFD0", 1, 5, 18, },
+ { "Lindern 1", "LRN1", 1, 5, 19, },
+ { "Oerlinghausen 2", "OERL2", 1, 5, 20, },
+ { "Guetersloh-Friedrichsdorf 0", "GTL99", 1, 5, 22, },
+ { "Paderborn 0", "PB0", 1, 5, 23, },
+ { "Hoevelhof 0", "HOEVH", 1, 5, 24, },
+ { "Lemgo 2", "LEMG2", 1, 5, 25, },
+ { "Bad Iburg 2", "BIB2", 1, 5, 26, },
+ { "Dissen 1", "DIS1", 1, 5, 27, },
+ { "Melle-Buer 1", "MLB1", 1, 5, 28, },
+ { "Fuerstenau 0", "FUE0", 1, 5, 29, },
+ { "Bad Bentheim 2", "BBM2", 1, 5, 30, },
+ { "Uchte 0", "UCH0", 1, 5, 32, },
+ { "Bielefeld-Joellenbeck 0", "BFDJ", 1, 5, 33, },
+ { "Bad Lippspringe 0", "BLPS0", 1, 5, 34, },
+ { "Steinhagen 0", "STHG0", 1, 5, 35, },
+ { "Spenge 0", "SPENG0", 1, 5, 37, },
+ { "Berge 0", "BERGE", 1, 5, 38, },
+ { "Minden 0", "MIN0", 1, 5, 40, },
+ { "Osnabrueck 8", "OS8", 1, 5, 41, },
+ { "Osnabrueck 0", "OS0", 1, 5, 42, },
+ { "Rahden 0", "RAHD0", 1, 5, 44, },
+ { "Rheda-Wiedenbrueck 7", "RHDA4", 1, 5, 45, },
+ { "Emlichheim 0", "WILS1", 1, 5, 48, },
+ { "Tecklenburg 1", "TE1", 1, 5, 50, },
+ { "Blomberg 99 (Nassengrund)", "BGNG99", 1, 5, 52, },
+ { "Bad Driburg 99", "BDBG99", 1, 5, 54, },
+ { "Harsewinkel 97", "HARS99", 1, 5, 55, },
+ { "Horn Bad Meinberg 1", "BMBG1", 1, 5, 56, },
+ { "Nordhorn 0", "NDHN0", 1, 5, 59, },
+ { "Guetersloh 0", "GTLH0", 1, 5, 60, },
+ { "Damme 1", "DAM1", 1, 5, 61, },
+ { "Meppen 0", "MEP0", 1, 5, 62, },
+ { "Rheine 0", "RHE0", 1, 5, 63, },
+ { "Bielefeld 1", "BFD1", 1, 5, 92, },
+ { "Minden 2", "MIN2", 1, 5, 95, },
+ { "Worms 7 (Autobahn)", "FKLZ52", 1, 6, 1, },
+ { "Westhofen Rheinhess 1", "FKLZ54", 1, 6, 2, },
+ { "Bensheim 0", "FKLZ56", 1, 6, 3, },
+ { "Seeheim 2", "FKLZ57", 1, 6, 5, },
+ { "Mosbach Baden 6", "HNKL21", 1, 6, 6, },
+ { "Eberbach 1", "HNKL22", 1, 6, 7, },
+ { "Lambrecht Pfalz 1", "LAMB1", 1, 6, 8, },
+ { "Weidenthal Pfalz 3", "WDTL3", 1, 6, 9, },
+ { "Bad Kreuznach 5<wird opt>", "BKZ5", 1, 6, 10, },
+ { "Annweiler a Trifels 1", "ANNW", 1, 6, 11, },
+ { "Wilhelmsfeld 2", "WHF2", 1, 6, 12, },
+ { "Alzey 1", "FKLZ51", 1, 6, 13, },
+ { "Mudau 1", "MUD1", 1, 6, 14, },
+ { "Kaiserslautern 2", "KL2", 1, 6, 15, },
+ { "Bad Bergzabern 5", "BBZN2", 1, 6, 22, },
+ { "Wiesloch 3", "KAKL35", 1, 6, 24, },
+ { "Hockenheim 2", "HOCK2", 1, 6, 25, },
+ { "Beerfelden 1", "AISCH", 1, 6, 26, },
+ { "Hartberg 5 (HR)", "HARTB5", 1, 6, 27, },
+ { "Ahorn Baden 1", "EUB1", 1, 6, 28, },
+ { "Schefflenz 2 (Rittersb.)", "SFL2", 1, 6, 29, },
+ { "Michelstadt 7", "MICH1", 1, 6, 30, },
+ { "Mannheim 12(Friedrichsfeld)", "KAKL55", 1, 6, 31, },
+ { "Lindenfels 1", "FKLZ55", 1, 6, 32, },
+ { "Moeckmuehl 1", "HNKL01", 1, 6, 34, },
+ { "Meisenheim 6", "MEIS6", 1, 6, 35, },
+ { "Odernheim 2", "ODH2", 1, 6, 36, },
+ { "Guntersblum 3", "GUN3", 1, 6, 37, },
+ { "Flonheim 1", "FLON1", 1, 6, 38, },
+ { "Neutsch (Ruhrgas)", "NEUT", 1, 6, 40, },
+ { "Schoenau 3 (Hl.Kreuz.)", "WHF1", 1, 6, 42, },
+ { "Neckargemuend 1", "NEG", 1, 6, 43, },
+ { "Neckargemuend 2", "NEG2", 1, 6, 44, },
+ { "Meckesheim 2", "MEH2", 1, 6, 45, },
+ { "Mannheim 178 (Schoenau)", "MA178", 1, 6, 46, },
+ { "Hardheim 1", "HAD", 1, 6, 51, },
+ { "Buchen Odenw 0", "BUC", 1, 6, 52, },
+ { "Maxdorf 0", "KAKL44", 1, 6, 53, },
+ { "Guntersblum 1", "GUN1", 1, 6, 54, },
+ { "Bensheim 13", "FKLZ74", 1, 6, 55, },
+ { "Weinheim 2", "KAKL52", 1, 6, 56, },
+ { "Winnweiler 2 (Imsbach)(KL2)", "IMB1", 1, 6, 57, },
+ { "Winnweiler 8 (KL2)", "WIW8", 1, 6, 58, },
+ { "Neustadt a d Weinstrasse 0", "KAKL06", 1, 6, 60, },
+ { "Ludwigshafen a Rhein 505", "KAKL01", 1, 6, 61, },
+ { "Speyer 5", "KAKL07", 1, 6, 62, },
+ { "Landau i d Pfalz 8", "KAKL10", 1, 6, 63, },
+ { "Heidelberg 0", "KAKL26", 1, 6, 64, },
+ { "Dahn 3", "DAHN3", 1, 6, 65, },
+ { "Schwetzingen 0", "KAKL36", 1, 6, 66, },
+ { "Ladenburg 6", "KAKL37", 1, 6, 67, },
+ { "Lampertheim 0", "KAKL38", 1, 6, 68, },
+ { "Mannheim 52 (Pfeiffersw.)", "KAKL41", 1, 6, 69, },
+ { "Neuhofen Pfalz 0", "KAKL43", 1, 6, 70, },
+ { "Mannheim 149 (Ilvesheim)", "KAKL29", 1, 6, 71, },
+ { "Mannheim 198 (Diak.-Kkh.)", "KAKL32", 1, 6, 72, },
+ { "Mannheim 199 (Grosskraftw.)", "KAKL31", 1, 6, 73, },
+ { "Mannheim 201 (Maimarktg.)", "KAKL30", 1, 6, 75, },
+ { "Mannheim 202 (VDOe)", "KAKL33", 1, 6, 76, },
+ { "Mannheim 173 (Kaefertal)", "KAKL28", 1, 6, 77, },
+ { "Viernheim 2", "KAKL39", 1, 6, 78, },
+ { "Adelsheim 4 <ers. Seckach1>", "ADH1", 1, 6, 83, },
+ { "Gernsheim Rhein 4", "FKLZ75", 1, 6, 84, },
+ { "Alsenz 7", "ALE", 1, 6, 85, },
+ { "Frankenthal 0", "KAKL02", 1, 6, 86, },
+ { "Gruenstadt 0", "KAKL03", 1, 6, 87, },
+ { "Bad Duerkheim 2", "KAKL04", 1, 6, 88, },
+ { "Bad Duerkheim 0", "KAKL45", 1, 6, 89, },
+ { "Kirchheimbolanden 5", "KIB", 1, 6, 90, },
+ { "Hassmersheim 1 (Gundelsheim)", "HAH1", 1, 6, 91, },
+ { "Enkenbach-Alsenborn 4", "ENK4", 1, 6, 93, },
+ { "Miltenberg 2", "MIL2", 1, 6, 94, },
+ { "Miltenberg 4", "MIL4", 1, 6, 95, },
+ { "Rockenhausen 6 (KL2)", "ROK6", 1, 6, 96, },
+ { "Mannheim 499 (Pfingstb. No)", "BAHN01", 1, 6, 97, },
+ { "Mannheim 4", "MA4", 1, 6, 99, },
+ { "Beuron 1", "BEU1", 1, 7, 1, },
+ { "Albstadt-Laufen 1", "ALB1", 1, 7, 2, },
+ { "Oberndorf 3", "OBD1", 1, 7, 3, },
+ { "Schwenningen P01", "SWE1", 1, 7, 4, },
+ { "Rottweil 0", "RW0", 1, 7, 5, },
+ { "Albstadt-Ebingen 2", "ALB3", 1, 7, 6, },
+ { "Baiersbronn 1", "BAI1", 1, 7, 7, },
+ { "Balingen 1", "BAL1", 1, 7, 8, },
+ { "Gosheim 1", "GOSM1", 1, 7, 9, },
+ { "Tuttlingen 2", "TUT2", 1, 7, 10, },
+ { "Konstanz 0", "KON0", 1, 7, 11, },
+ { "Waldburg 2", "WAB2", 1, 7, 12, },
+ { "Deggenhausertal 3", "DHT3", 1, 7, 13, },
+ { "Sigmaringen 4", "SIGM4", 1, 7, 14, },
+ { "Donaueschingen 5", "DOE5", 1, 7, 15, },
+ { "Singen 0", "SIN0", 1, 7, 16, },
+ { "Klettgau 6", "KLG6", 1, 7, 17, },
+ { "Rickenbach 1", "RIK1", 1, 7, 18, },
+ { "Bodman-Ludwigshafen 3", "BOD3X", 1, 7, 19, },
+ { "Sauldorf 1", "SAU1", 1, 7, 20, },
+ { "Hilzingen 1", "HILZ1", 1, 7, 21, },
+ { "Stockach 6", "STO2", 1, 7, 22, },
+ { "Aichstetten 2", "AIST2", 1, 7, 23, },
+ { "Voehrenbach 4", "VOEH4", 1, 7, 24, },
+ { "Radolfzell 1", "RAD1", 1, 7, 25, },
+ { "Schoemberg-Balingen 2", "SBA2", 1, 7, 26, },
+ { "Nagold-Hochdorf 0", "NAH", 1, 7, 27, },
+ { "Rottenburg 3", "ROTT3", 1, 7, 28, },
+ { "Hechingen 6", "HECH6", 1, 7, 29, },
+ { "Ammerbuch 2", "SKLZ03", 1, 7, 30, },
+ { "Allensbach 1", "ALLB", 1, 7, 31, },
+ { "Villingen 10", "VILL10", 1, 7, 32, },
+ { "Tiengen 0", "TIEN0", 1, 7, 33, },
+ { "Mengen 1", "MENG1", 1, 7, 34, },
+ { "Bad Schussenried 1", "BSCH1", 1, 7, 35, },
+ { "Ravensburg 0", "RAV0", 1, 7, 36, },
+ { "Friedrichshafen 0", "TET2", 1, 7, 37, },
+ { "Nagold 1", "NAG1", 1, 7, 38, },
+ { "Baiersbronn 3", "BAI3", 1, 7, 39, },
+ { "Grafenhausen 1", "GRAF", 1, 7, 40, },
+ { "Bad Saeckingen 0", "BSK0", 1, 7, 41, },
+ { "Immenstaad 0", "IMM", 1, 7, 42, },
+ { "Altensteig 2", "ALTST2", 1, 7, 43, },
+ { "St. Georgen 1", "STG1", 1, 7, 44, },
+ { "Sulz 3", "SU3", 1, 7, 45, },
+ { "Murg 2", "MURG2", 1, 7, 46, },
+ { "Tengen 2", "TEN2", 1, 7, 47, },
+ { "Waldshut 4", "WAL4", 1, 7, 48, },
+ { "Leutkirch 0", "LEUT0", 1, 7, 49, },
+ { "Triberg 2", "TRI2", 1, 7, 50, },
+ { "Furtwangen 2", "FURT2", 1, 7, 51, },
+ { "Tettnang 4", "TET4", 1, 7, 52, },
+ { "Ostrach 2", "OST2", 1, 7, 53, },
+ { "Haigerloch 0", "HAIG0", 1, 7, 54, },
+ { "Alpirsbach 4", "ALPI1", 1, 7, 56, },
+ { "Pfullendorf 1 <Prov.>", "PFUL3", 1, 7, 57, },
+ { "Rottweil 7", "RW7", 1, 7, 58, },
+ { "Baiersbronn 2", "BAI2", 1, 7, 60, },
+ { "Bad Wurzach 1", "BWU1", 1, 7, 61, },
+ { "Wangen 1", "WANG1", 1, 7, 62, },
+ { "Markdorf 1", "MARK1", 1, 7, 63, },
+ { "Burladingen 1", "BURL1", 1, 7, 64, },
+ { "Gammertingen 3", "GAMT3", 1, 7, 65, },
+ { "Kisslegg 2", "KISS2", 1, 7, 66, },
+ { "Kressbronn 3", "KRES3", 1, 7, 67, },
+ { "Freudenstadt 0", "DORN4", 1, 7, 69, },
+ { "Geisingen 1", "GEIS1", 1, 7, 70, },
+ { "Isny 0", "ISNY0", 1, 7, 71, },
+ { "Schramberg 1", "SBG1", 1, 7, 79, },
+ { "Eigeltingen 2", "EIG2", 1, 7, 87, },
+ { "Talheim 4", "TAL4", 1, 7, 93, },
+ { "Heiligenberg 0", "HEILB0", 1, 7, 94, },
+ { "Spaichingen 3", "SPAI3", 1, 7, 95, },
+ { "Blumberg 5", "BLUM5", 1, 7, 96, },
+ { "Baiersbronn-Obertal 2", "VOK", 1, 7, 98, },
+ { "Engen 4", "BARG", 1, 7, 99, },
+ { "Oberammergau 1", "OAG1", 1, 8, 1, },
+ { "Schwindegg 1", "SCHW1", 1, 8, 2, },
+ { "Bad Aibling 0", "BAIB0", 1, 8, 3, },
+ { "Teisendorf 3", "TEIS3", 1, 8, 4, },
+ { "Miesbach 4 (Ers.f.Bruckmuehl)", "BRU2", 1, 8, 5, },
+ { "Oberaudorf 2", "OADO2", 1, 8, 6, },
+ { "Ramsau 1", "RAMS1", 1, 8, 7, },
+ { "Reit im Winkl 0", "RIW0", 1, 8, 8, },
+ { "Bad Reichenhall 2", "BREI2", 1, 8, 9, },
+ { "Landau/Isar 3", "EAUF1", 1, 8, 10, },
+ { "Tann 2", "TANN2", 1, 8, 11, },
+ { "Neufahrn 81", "ALHN99", 1, 8, 12, },
+ { "Attenkirchen 1", "ATK99", 1, 8, 13, },
+ { "Olching 0 (Wolfstrasse)", "MKLZ28", 1, 8, 14, },
+ { "Seeshaupt 1", "SH99", 1, 8, 15, },
+ { "Wolfratshausen 2", "MKLZ32", 1, 8, 16, },
+ { "Starnberg 5 (Wangen)", "MKLZ31", 1, 8, 17, },
+ { "Tittmoning 1 (Froschham)", "TITT1", 1, 8, 18, },
+ { "Herrsching 1 (Widdersberg)", "HSG1", 1, 8, 19, },
+ { "Wolfratshausen 1", "ICKI99", 1, 8, 20, },
+ { "Bad Reichenhall 1 <Prov.>", "BREI", 1, 8, 21, },
+ { "Passau 11 (Dommelstadl)", "DST1", 1, 8, 22, },
+ { "Pfarrkirchen Niederbay 1", "PFI1", 1, 8, 23, },
+ { "Anger 1", "AN1", 1, 8, 24, },
+ { "Obernzell", "OZEL", 1, 8, 25, },
+ { "Hohenpeissenberg 2", "HHP2", 1, 8, 26, },
+ { "Garmisch-Partenkirchen 4", "GAR4X", 1, 8, 27, },
+ { "Grainet 1", "GRN1", 1, 8, 28, },
+ { "Glonn 1", "GLN1", 1, 8, 29, },
+ { "Taufkirchen/Vils 2", "TKI99", 1, 8, 30, },
+ { "Freyung 1", "FYG1", 1, 8, 31, },
+ { "Mainburg 1", "MNBG1", 1, 8, 32, },
+ { "Diessen 2", "DSN2", 1, 8, 33, },
+ { "Berchtesgaden 15", "BGN15", 1, 8, 34, },
+ { "Fuerstenfeldbruck 2", "MKLZ30", 1, 8, 35, },
+ { "Markt Schwaben 1(Neufinsing)", "MKLZ22", 1, 8, 36, },
+ { "Murnau 70 (Ohlstadt)", "MUR70", 1, 8, 37, },
+ { "Landsberg 3 (Poessing)", "LBG99", 1, 8, 38, },
+ { "Dingolfing 2 (Brunn)", "DGF2", 1, 8, 39, },
+ { "Grafing 21 (Ebersberg)", "GRAF21", 1, 8, 40, },
+ { "Muehldorf 0", "MDF0", 1, 8, 41, },
+ { "Grassau 2", "GSU2", 1, 8, 42, },
+ { "Ergoldsbach 2", "EGB2", 1, 8, 43, },
+ { "Weyarn 3", "WYN3", 1, 8, 44, },
+ { "Hausham 99 (Schliersbergalm)", "HHM99", 1, 8, 45, },
+ { "Freising 3 (Schiesspl.)", "FRS99", 1, 8, 46, },
+ { "Kochel am See 4 (Kreutalm)", "KAS98", 1, 8, 47, },
+ { "Woerth 1 <Ers. f. Adlk. 1>", "WTH1", 1, 8, 48, },
+ { "Holzkirchen 62", "HKI62", 1, 8, 49, },
+ { "Dachau 91(Bayernw.i.Karlsf.)", "DACH99", 1, 8, 50, },
+ { "Hallbergmoos 2 (FMG)", "HBGM99", 1, 8, 51, },
+ { "Petershausen 1", "PHSN1", 1, 8, 52, },
+ { "Roehrmoos 2", "RMS2", 1, 8, 53, },
+ { "Ruhpolding 1 (Rauschberg)", "RPD1", 1, 8, 54, },
+ { "Geltendorf 1 (Wasserbeh.)", "GDF99", 1, 8, 55, },
+ { "Trostberg 3", "TBG1", 1, 8, 56, },
+ { "Dorfen 1", "DORF1", 1, 8, 57, },
+ { "Dachau 3 (Krankenhaus)", "MKLZ25", 1, 8, 59, },
+ { "Vilsbiburg 2", "VILS2", 1, 8, 60, },
+ { "Mallersdorf 2", "MALL2", 1, 8, 61, },
+ { "Mammendorf 1 (Hattenhofen)", "MAMM99", 1, 8, 62, },
+ { "Traunstein 2", "TS2", 1, 8, 63, },
+ { "Markt Schwaben 0", "MSBN0", 1, 8, 64, },
+ { "Bernbeuren 1", "BBN1", 1, 8, 65, },
+ { "Landshut 1", "LA1", 1, 8, 66, },
+ { "Holzkirchen 3", "HKI3", 1, 8, 67, },
+ { "Rosenheim Oberbay 0", "RO0", 1, 8, 68, },
+ { "Schnaitsee 1", "SNE1", 1, 8, 69, },
+ { "Waakirchen 0", "WAA", 1, 8, 70, },
+ { "Wasserburg 1", "WSBG1", 1, 8, 71, },
+ { "Prien 1", "PRI1", 1, 8, 72, },
+ { "Waldkraiburg 0", "MHLD0", 1, 8, 73, },
+ { "Burghausen 5", "BHS99", 1, 8, 74, },
+ { "Kirchseeon 0", "KISE0", 1, 8, 75, },
+ { "Fuerstenfeldbruck 0", "FFB0", 1, 8, 76, },
+ { "Moosinning 1", "MOSI1", 1, 8, 77, },
+ { "Sulzemoos 1 (BAB-P.)", "SULZ98", 1, 8, 78, },
+ { "Vilshofen 1", "VIH1", 1, 8, 79, },
+ { "Bayrischzell", "BAYZ", 1, 8, 80, },
+ { "Reischach 1", "REI", 1, 8, 81, },
+ { "Simbach/Inn 2", "SIM2", 1, 8, 84, },
+ { "Hauzenberg 2", "HAUZ2", 1, 8, 85, },
+ { "Sindelsdorf 10", "SIDO10", 1, 8, 86, },
+ { "Zolling 1 (Grossenviecht)", "ZOLL99", 1, 8, 90, },
+ { "Griesbach 1 (OBAG)", "GRIB1", 1, 8, 91, },
+ { "Kochel am See 1", "KAS1", 1, 8, 92, },
+ { "Isen 1", "IS1", 1, 8, 93, },
+ { "Tegernsee 1 (Ringberg)", "RING", 1, 8, 94, },
+ { "Gangkofen-Kollbach 1", "GKKB1", 1, 8, 95, },
+ { "Lenggries 0", "LGS0", 1, 8, 96, },
+ { "Pfeffenhausen 1", "PFE1", 1, 8, 99, },
+ { "Arnstein 2", "ARN", 1, 9, 1, },
+ { "Bad Steben 1", "SCHNB", 1, 9, 2, },
+ { "Bayerisch Eisenstein 1", "BYS1X", 1, 9, 3, },
+ { "Berg 2", "EISE", 1, 9, 4, },
+ { "Rottendorf 3", "BIEB", 1, 9, 5, },
+ { "Werneck 2", "WNECK2", 1, 9, 6, },
+ { "Bayreuth-Oschenberg 1", "BYR1", 1, 9, 7, },
+ { "Kulmbach 4", "KULM", 1, 9, 8, },
+ { "Pressig 1", "PRES", 1, 9, 10, },
+ { "Bischofsgruen 2", "BIGR2", 1, 9, 11, },
+ { "Hof-Labyrinth 2", "HOF2", 1, 9, 12, },
+ { "Kist 1", "KIST", 1, 9, 13, },
+ { "Bodenwoehr 1", "BDWR1", 1, 9, 14, },
+ { "Burglengenfeld 3", "BLF3", 1, 9, 15, },
+ { "Burgwindheim 1", "BUW1", 1, 9, 16, },
+ { "Buttenheim 1", "BUT1", 1, 9, 17, },
+ { "Iphofen 2", "IPHN2", 1, 9, 18, },
+ { "Cham 1", "CHA1", 1, 9, 19, },
+ { "Tauberbischofsheim 4", "TBIO4", 1, 9, 20, },
+ { "Unterpleichfeld 2", "UPLF2", 1, 9, 21, },
+ { "Uettingen 4", "UETT4", 1, 9, 22, },
+ { "Erbendorf 1", "ERBN1", 1, 9, 23, },
+ { "Deggendorf 1", "DGD1", 1, 9, 24, },
+ { "Oberthulba 3", "KN51", 1, 9, 25, },
+ { "Laaber 5", "LAAB5", 1, 9, 26, },
+ { "Seubersdorf 2", "SEUB2", 1, 9, 27, },
+ { "Riedenburg 2", "RIED2", 1, 9, 28, },
+ { "Oberwerrn 51", "OBW51", 1, 9, 29, },
+ { "Abensberg 1", "ABBG1", 1, 9, 31, },
+ { "Hemau 3", "HEM3", 1, 9, 32, },
+ { "Hirschau 1", "HIR1", 1, 9, 33, },
+ { "Hofheim 1", "HFH1X", 1, 9, 34, },
+ { "Karlstadt 3", "KARL", 1, 9, 35, },
+ { "Kelheim 2", "KLH2", 1, 9, 36, },
+ { "Bamberg 6", "BAMB", 1, 9, 37, },
+ { "Oberaurach 1", "ZEIL1", 1, 9, 38, },
+ { "Pfarrweisach 1", "PFWA1", 1, 9, 39, },
+ { "Kirchlauter 1", "KLTR1", 1, 9, 40, },
+ { "Schesslitz 2", "SCHZ2", 1, 9, 41, },
+ { "Zapfendorf 2", "ZAPF1", 1, 9, 42, },
+ { "Beratzhausen 1", "BZHS1", 1, 9, 43, },
+ { "Rehau 1", "REHA1", 1, 9, 44, },
+ { "Neustadt/Coburg 1", "NEUST1", 1, 9, 45, },
+ { "Kronach 1", "KRN1", 1, 9, 46, },
+ { "Langquaid 1", "LANG1", 1, 9, 47, },
+ { "Amberg 0", "AMB0", 1, 9, 48, },
+ { "Pleystein 1", "PLEY1", 1, 9, 49, },
+ { "Lauda-Koenigshofen 3", "LDK3", 1, 9, 50, },
+ { "Lichtenfels 2", "LIFS99", 1, 9, 51, },
+ { "Muennerstadt 1", "MUENR1", 1, 9, 53, },
+ { "Meeder 1", "MED1", 1, 9, 54, },
+ { "Bad Kissingen 1", "BKG1", 1, 9, 55, },
+ { "Hammelburg 8", "HMBG8", 1, 9, 56, },
+ { "Marktheidenfeld 2", "MHF2", 1, 9, 59, },
+ { "Straubing 0", "STBG0", 1, 9, 60, },
+ { "Schoefweg 1", "SCHOE1", 1, 9, 61, },
+ { "Koetzting 1", "KOETZ1", 1, 9, 62, },
+ { "Illschwang 3", "ILLS3", 1, 9, 64, },
+ { "Oberbach 1", "OBB1X", 1, 9, 66, },
+ { "Oberviechtach 2", "OVT2", 1, 9, 67, },
+ { "Ochsenfurt 3", "OCHS3", 1, 9, 68, },
+ { "Pfatter 0", "PFAT0", 1, 9, 69, },
+ { "Regensburg 1", "R1", 1, 9, 70, },
+ { "Regensburg 4", "RBG42", 1, 9, 71, },
+ { "Schweinfurt 30", "SW30", 1, 9, 72, },
+ { "Selb 1", "SELB1", 1, 9, 73, },
+ { "Stallwang 2", "STALL2", 1, 9, 74, },
+ { "Bad Koenigshofen 1", "KHF1", 1, 9, 75, },
+ { "Alladorf 1", "AL1", 1, 9, 76, },
+ { "Tirschenreuth 0", "TIR0", 1, 9, 77, },
+ { "Waldmuenchen 1", "WMCHN1", 1, 9, 78, },
+ { "Weiden 1", "WDN1", 1, 9, 79, },
+ { "Werbach-Gamburg 2 <pr GAM3>", "WERBG2", 1, 9, 80, },
+ { "Wiesentheid 1", "WSD1X", 1, 9, 81, },
+ { "Wuerzburg 2", "WUE2", 1, 9, 82, },
+ { "Wunsiedel-Koesseine 2", "WUNS2", 1, 9, 83, },
+ { "Zell-Waldstein 2", "ZLL2", 1, 9, 84, },
+ { "Trockau 1", "TROK1", 1, 9, 85, },
+ { "Mitterfels 1", "MITF1", 1, 9, 87, },
+ { "Nabburg 2", "NABB2", 1, 9, 88, },
+ { "Obernsees 1", "OBS1", 1, 9, 90, },
+ { "Roding 1", "ROD1", 1, 9, 91, },
+ { "Gerchsheim 1", "GERH1", 1, 9, 93, },
+ { "Coburg 5", "ECKBG", 1, 9, 94, },
+ { "Karlstadt-Wiesenfeld 1", "BAHN12", 1, 9, 96, },
+ { "Wuerzburg 74", "BAHN13", 1, 9, 97, },
+ { "Waldsassen 1", "WASA1", 1, 9, 98, },
+ { "Zell/Opf. 1", "ZELL1", 1, 9, 99, },
+ { "Neuss 10", "NEU10", 2, 2, 1, },
+ { "Duesseldorf 57 (Messe)", "D98", 2, 2, 2, },
+ { "Neuss 7", "NEU7", 2, 2, 4, },
+ { "Ratingen 5", "RAT5", 2, 2, 6, },
+ { "Solingen 2", "SOL2", 2, 2, 7, },
+ { "Duesseldorf 18", "D18", 2, 2, 8, },
+ { "Duesseldorf 58", "D99", 2, 2, 9, },
+ { "Neuss 14", "NEU14", 2, 2, 10, },
+ { "Neuss-Norf 1", "NEUNO1", 2, 2, 11, },
+ { "Duesseldorf 30", "D30", 2, 2, 12, },
+ { "Langenfeld 3", "LANF3", 2, 2, 13, },
+ { "Duesseldorf 75", "D75", 2, 2, 14, },
+ { "Mettmann 7", "MTM4", 2, 2, 15, },
+ { "Duesseldorf 19", "D19", 2, 2, 17, },
+ { "Grevenbroich 3", "GVB3", 2, 2, 18, },
+ { "Grevenbroich-Kapellen 2", "GVBK", 2, 2, 19, },
+ { "Ratingen 1", "RAT1", 2, 2, 20, },
+ { "Duesseldorf 40", "D97", 2, 2, 22, },
+ { "Neuss 8", "NEU8", 2, 2, 23, },
+ { "Duesseldorf 4", "D4", 2, 2, 24, },
+ { "Hilden 6", "HDN6", 2, 2, 26, },
+ { "Duesseldorf 12", "D12", 2, 2, 27, },
+ { "Ratingen 3", "RAT3", 2, 2, 29, },
+ { "Remscheid 4 <geneigt>", "REM4", 2, 2, 30, },
+ { "Krefeld 4", "KRF4", 2, 2, 31, },
+ { "Lank 0", "LANK", 2, 2, 33, },
+ { "Osterath 0", "OSTER0", 2, 2, 35, },
+ { "Krefeld 5", "KRF5", 2, 2, 36, },
+ { "Meerbusch-Buederich 1", "MEEB1", 2, 2, 37, },
+ { "Duesseldorf 27", "D27", 2, 2, 38, },
+ { "Duesseldorf 53", "D53", 2, 2, 39, },
+ { "Willich 1", "WIL1", 2, 2, 42, },
+ { "Solingen 1 <Ant.geneigt>", "SOL1", 2, 2, 43, },
+ { "Moenchengladbach 18", "MGL18", 2, 2, 44, },
+ { "Haan 0", "HAAN", 2, 2, 45, },
+ { "Krefeld 7", "FISCH", 2, 2, 46, },
+ { "Duesseldorf 9 (Rheintunnel)", "D9", 2, 2, 47, },
+ { "Duesseldorf 2.8046", "D2", 2, 2, 49, },
+ { "Langenfeld 89", "LANF", 2, 2, 52, },
+ { "Mettmann 2", "MTM2X", 2, 2, 66, },
+ { "Wuppertal 23", "WUP23", 2, 2, 78, },
+ { "Duesseldorf 10 <Bake>", "D10", 2, 2, 88, },
+ { "Aachen 9", "AA99", 3, 2, 1, },
+ { "Krefeld 19", "KRF19", 3, 2, 2, },
+ { "Moenchengladbach 60", "MGL60", 3, 2, 3, },
+ { "Moenchengladbach 3", "MGL3", 3, 2, 4, },
+ { "Viersen 4", "VIE4", 3, 2, 5, },
+ { "Bedburg 0", "BEDB", 3, 2, 8, },
+ { "Moenchengladbach-Rheydt 8", "MGL8", 3, 2, 13, },
+ { "Selfkant 0", "SELF", 3, 2, 15, },
+ { "Anrath 0", "ANR99", 3, 2, 17, },
+ { "Wuerselen 2", "WUERS2", 3, 2, 19, },
+ { "Moenchengladbach 8", "MGLB8", 3, 2, 22, },
+ { "Langerwehe 1", "LUCH", 3, 2, 26, },
+ { "Xanten 1", "XAN1", 3, 2, 27, },
+ { "Kleve 7", "KLV7", 3, 2, 29, },
+ { "Geldern 0", "GEL0", 3, 2, 31, },
+ { "Moers 0", "MOER0", 3, 2, 32, },
+ { "Viersen 0", "VIER0", 3, 2, 33, },
+ { "Juechen 1", "JUECH1", 3, 2, 36, },
+ { "Nettetal-Kaldenkirchen 1", "NETT1", 3, 2, 40, },
+ { "Viersen 1", "VIE1", 3, 2, 42, },
+ { "Schwalmtal 9", "SCHWA", 3, 2, 43, },
+ { "Juechen-Otzenrath 4", "JUECH4", 3, 2, 44, },
+ { "Moenchengladbach-Rheydt 7", "MGLR7", 3, 2, 45, },
+ { "Stolberg 4", "STOL4", 3, 2, 46, },
+ { "Eschweiler 2", "EWLR2", 3, 2, 48, },
+ { "Alsdorf 3", "ALSD3", 3, 2, 49, },
+ { "Aachen-Kornelimuenster 0", "AAK", 3, 2, 50, },
+ { "Aachen 700", "AA7", 3, 2, 51, },
+ { "Aachen 120", "AA120", 3, 2, 52, },
+ { "Aachen 500 <Ers. f. AA57>", "AA500", 3, 2, 53, },
+ { "Erkelenz 0", "ERKL0", 3, 2, 54, },
+ { "Geilenkirchen 0", "GEIL0", 3, 2, 57, },
+ { "Heinsberg 0", "HEIN0", 3, 2, 58, },
+ { "Juelich 3", "JUEL3", 3, 2, 59, },
+ { "Kevelaer 98", "KEVL98", 3, 2, 63, },
+ { "Straelen 1", "STRAE1", 3, 2, 64, },
+ { "Neukirchen-Vluyn 6", "NEUK6", 3, 2, 65, },
+ { "Kalkar 7", "KKAR99", 3, 2, 67, },
+ { "Wegberg 89 <f. MGL7>", "WEGB89", 3, 2, 77, },
+ { "Herzogenrath 2", "HERA2", 3, 2, 80, },
+ { "Kevelaer 10", "GOCH89", 3, 2, 81, },
+ { "Sonsbeck 0.47B1", "SONS0", 3, 2, 82, },
+ { "Moenchengladbach 401", "MGL40", 3, 2, 84, },
+ { "Aachen 1 <Mischbake>", "AA1", 3, 2, 86, },
+ { "Kempen 4", "KEMP", 3, 2, 87, },
+ { "Linnich 1", "LINN", 3, 2, 88, },
+ { "Goch 0", "GOCH0", 3, 2, 90, },
+ { "Rheinberg 2", "RHBG2", 3, 2, 98, },
+ { "Aldenhoven 0", "AHVN", 3, 2, 99, },
+ { "Berlin (West) 23 PGiroA", "B23", 2, 3, 1, },
+ { "Blnklz 210 GBhf Schoenholz", "BKLZ78", 2, 3, 2, },
+ { "Blnklz 101(Ruegenerstr.)", "BKLZ01", 2, 3, 3, },
+ { "Blnklz 102(Habersaathstr)", "BKLZ2", 2, 3, 4, },
+ { "Blnklz 103(Stresemannstr.)", "BKLZ03", 2, 3, 5, },
+ { "Blnklz 407(Wilkestr.15)", "BKLZ24", 2, 3, 6, },
+ { "Blnklz 105(Skalitzer Str.)", "BKLZ05", 2, 3, 7, },
+ { "Blnklz 201(Luederitzstr.)", "BKLZ06", 2, 3, 8, },
+ { "Blnklz 202(Erasmusstr20-24)", "BKLZ07", 2, 3, 9, },
+ { "Blnklz 203(Winterfeldstr.)", "BKLZ08", 2, 3, 10, },
+ { "Blnklz 307(Wernerwerkdamm)", "BKLZ25", 2, 3, 11, },
+ { "Blnklz 205(Karl-Marx-Str.)", "BKLZ10", 2, 3, 12, },
+ { "Blnklz 301(Oranienb. Str.)", "BKLZ11", 2, 3, 13, },
+ { "Blnklz 302(Auguste V.Allee)", "BKLZ12", 2, 3, 14, },
+ { "Blnklz 305(Rathausstr)", "BKLZ15", 2, 3, 15, },
+ { "Blnklz 304(Schmargend. Str)", "BKLZ14", 2, 3, 16, },
+ { "Blnklz 204(Tempelhofer D.6)", "BKLZ09", 2, 3, 17, },
+ { "Blnklz 306(Hannemannstr)", "BKLZ16", 2, 3, 18, },
+ { "Blnklz 401(Streitstr)", "BKLZ17", 2, 3, 19, },
+ { "Blnklz 405(Kettinger Str.)", "BKLZ22", 2, 3, 20, },
+ { "Blnklz 403(Forststr)", "BKLZ19", 2, 3, 21, },
+ { "Blnklz 404(Hindenb. Damm)", "BKLZ20", 2, 3, 22, },
+ { "Blnklz 104(Lobecks)<gen.Ant>", "BKLZ04", 2, 3, 23, },
+ { "Blnklz 211(Alt-Stralau)", "BKLZ40", 2, 3, 24, },
+ { "Blnklz 501(Schaeferberg)", "B3", 2, 3, 25, },
+ { "Blnklz 212(Elsastrasse 26)", "BKLZ41", 2, 3, 28, },
+ { "Blnklz 106(Franz-J)<gen.Ant>", "BKLZ31", 2, 3, 29, },
+ { "Blnklz 308(Schnellerstr.)", "BKLZ42", 2, 3, 30, },
+ { "Blnklz 309(Koepenicker A.)", "BKLZ43", 2, 3, 31, },
+ { "Blnklz 310(Amanlisweg 10)", "BKLZ44", 2, 3, 32, },
+ { "Blnklz 311(Bitterfelder Str)", "BKLZ45", 2, 3, 33, },
+ { "Blnklz 312(E.-Barlach-Str.)", "BKLZ46", 2, 3, 34, },
+ { "Blnklz 420(Flankenschanze)", "BKLZ23", 2, 3, 35, },
+ { "Blnklz 107(Lilli-Henoch-Str)", "BKLZ32", 2, 3, 36, },
+ { "Blnklz 314(Buchholzer Str)", "BKLZ48", 2, 3, 37, },
+ { "Blnklz 408(Rudower Chaus.)", "BKLZ49", 2, 3, 38, },
+ { "Blnklz 409(O.-Geschke-Str)", "BKLZ50", 2, 3, 39, },
+ { "Blnklz 001(Rochstr)<gen.Ant>", "BKLZ30", 2, 3, 40, },
+ { "Blnklz 213(E.-Reuter-Platz)", "BKLZ79", 2, 3, 41, },
+ { "Blnklz 418(Schoenefeld)", "BKLZ56", 2, 3, 48, },
+ { "Blnklz 206(Coppist)<gen.Ant>", "BKLZ33", 2, 3, 49, },
+ { "Blnklz 209(Prenzlauer Pr)", "BKLZ36", 2, 3, 57, },
+ { "Blnklz 208(Liebermann.75)", "BKLZ35", 2, 3, 58, },
+ { "Blnklz 207(Herzberg.105)", "BKLZ34", 2, 3, 59, },
+ { "Blnklz 303(Masurenallee)", "BKLZ13", 2, 3, 60, },
+ { "Blnklz 402(Scholzplatz)", "BKLZ18", 2, 3, 61, },
+ { "Blnklz 601(Flotowstr.)", "BKLZ75", 2, 3, 64, },
+ { "Blnklz 602(Breitestr.)", "BKLZ68", 2, 3, 65, },
+ { "Blnklz 002(Karl-Marx-Allee)", "BKLZ71", 2, 3, 70, },
+ { "Blnklz 516 (Avus)", "BKLZ77", 2, 3, 95, },
+ { "Hamburg 282 (PA90 Harb.Z44)", "HRBG", 2, 4, 13, },
+ { "Hannover 790", "HAN790", 2, 5, 1, },
+ { "Barsinghausen 2", "BAR2", 2, 5, 2, },
+ { "Bergen 1", "BERG1", 2, 5, 3, },
+ { "Celle 0", "CE0", 2, 5, 4, },
+ { "Salzhemmendorf 1", "SZH1", 2, 5, 5, },
+ { "Peine 1", "PEI1", 2, 5, 6, },
+ { "Sibbesse 1", "SIB1", 2, 5, 7, },
+ { "Braunschweig 3", "BS3", 2, 5, 9, },
+ { "Wietze 2", "WIET2", 2, 5, 10, },
+ { "Wolfsburg 1", "WOB1", 2, 5, 11, },
+ { "Sprakensehl 1", "SPR1", 2, 5, 12, },
+ { "Wesendorf 1", "WEDF", 2, 5, 13, },
+ { "Alfeld 40", "ALF40", 2, 5, 14, },
+ { "Semmenstedt 99", "SEM99", 2, 5, 17, },
+ { "Hildesheimer Boerde 99", "HIBO", 2, 5, 18, },
+ { "Eschede 1", "ED1", 2, 5, 19, },
+ { "Loccum 0", "LOCC0", 2, 5, 21, },
+ { "Zernien 1", "ZNN1", 2, 5, 22, },
+ { "Gartow 2", "GTO1", 2, 5, 23, },
+ { "Bispingen 41", "BISP98", 2, 5, 24, },
+ { "Hannover 4 (Hamburger Al)", "HAN4", 2, 5, 26, },
+ { "Hannover 951 (Gradestr. 22)", "HAKL10", 2, 5, 27, },
+ { "Hannover 2 (Neue Landstr)", "HAKL21", 2, 5, 28, },
+ { "Hannover 953 (Bischofshofer)", "HAKL33", 2, 5, 29, },
+ { "Hannover 954 (HildesheimerS)", "HAKL41", 2, 5, 30, },
+ { "Hannover 210 (Goettinger Str)", "HAKL52", 2, 5, 31, },
+ { "Uetze 99", "UETZ99", 2, 5, 32, },
+ { "Garbsen 10", "GRB10", 2, 5, 33, },
+ { "Wedemark 1", "WED1", 2, 5, 34, },
+ { "Burgwedel 0", "BGW1", 2, 5, 35, },
+ { "Schwarmstedt 0", "SWST0", 2, 5, 36, },
+ { "Lehrte 2", "LEH2", 2, 5, 37, },
+ { "Sarstedt 1", "SST1", 2, 5, 38, },
+ { "Ronnenberg 9", "RON9", 2, 5, 39, },
+ { "Walsrode 1", "WSR1", 2, 5, 40, },
+ { "Gifhorn 0", "GIF0", 2, 5, 41, },
+ { "Hitzacker 1", "HITZ1", 2, 5, 42, },
+ { "Hildesheim 1", "HILD1", 2, 5, 43, },
+ { "Bleckede/Barsk.1", "BBK1", 2, 5, 44, },
+ { "Einbeck 2", "EINB2", 2, 5, 46, },
+ { "Braunschweig 701", "BS4", 2, 5, 48, },
+ { "Hameln 10", "HM10", 2, 5, 49, },
+ { "Schneverdingen 0", "SVG", 2, 5, 50, },
+ { "Helmstedt 2", "HE2", 2, 5, 51, },
+ { "Hannover 610", "AWB61", 2, 5, 52, },
+ { "Braunschweig 360", "BS36", 2, 5, 54, },
+ { "Stadthagen 0", "STDH0", 2, 5, 55, },
+ { "Nienburg 0", "NIEN", 2, 5, 58, },
+ { "Linsburg 1", "LSB1", 2, 5, 60, },
+ { "Springe 3", "SPRG3", 2, 5, 61, },
+ { "Hannover 860", "HAN860", 2, 5, 62, },
+ { "Eschershausen 40", "EHSN40", 2, 5, 63, },
+ { "Holle 40", "HOLL40", 2, 5, 64, },
+ { "Munster 1", "MUN1", 2, 5, 65, },
+ { "Burgdorf-Ehlershausen 0", "BGDEH0", 2, 5, 66, },
+ { "Salzgitter 40", "SZGB", 2, 5, 67, },
+ { "Burgdorf 0", "BGD0", 2, 5, 68, },
+ { "Seesen 1", "SES1", 2, 5, 69, },
+ { "Kreiensen 1 (Orxhausen)", "BAHN05", 2, 5, 70, },
+ { "Obernkirchen 2", "OBKN2", 2, 5, 74, },
+ { "Uelzen 3", "ULZ3", 2, 5, 76, },
+ { "Jerxheim 1", "JH0", 2, 5, 78, },
+ { "Wunstorf 2", "WUNT2", 2, 5, 80, },
+ { "Brome 0", "BRO0", 2, 5, 82, },
+ { "Salzgitter 0", "SZG0", 2, 5, 84, },
+ { "Wendeburg 99", "WEN99", 2, 5, 85, },
+ { "Hannover 730 (Langenhagen)", "HAN730", 2, 5, 86, },
+ { "Soltau 2", "SOLT", 2, 5, 87, },
+ { "Clausthal-Zellerfeld 41", "CLT41", 2, 5, 90, },
+ { "Goslar 41", "GOS41", 2, 5, 91, },
+ { "Koenigslutter 54", "KLUT51", 2, 5, 92, },
+ { "Torfhaus 0", "TFH0", 2, 5, 93, },
+ { "Sibbesse 2 (Almstedt)", "BAHN04", 2, 5, 95, },
+ { "Hannover Messe", "HANMES", 2, 5, 97, },
+ { "Hoever 99", "HAN99", 2, 5, 98, },
+ { "Dieburg 2", "DBG2", 2, 6, 2, },
+ { "Gross-Umstadt 5<Ers FKLZ58>", "GRUM", 2, 6, 3, },
+ { "Brensbach 1", "FKLZ59", 2, 6, 4, },
+ { "Heusenstamm 4", "FKLZ81", 2, 6, 5, },
+ { "Floersheim 1", "FKLZ38", 2, 6, 6, },
+ { "Gross-Gerau 6", "FKLZ69", 2, 6, 7, },
+ { "Langen i Hess 0", "FKLZ24", 2, 6, 8, },
+ { "Moerfelden-Walldorf 5", "FKLZ26", 2, 6, 9, },
+ { "Rodgau 3", "FKLZ17", 2, 6, 10, },
+ { "Darmstadt 21", "FKLZ63", 2, 6, 11, },
+ { "Darmstadt 2", "DA2", 2, 6, 12, },
+ { "Ruesselsheim 3", "FKLZ70", 2, 6, 13, },
+ { "Hofheim-Wallau 1", "FKLZ37", 2, 6, 15, },
+ { "Eppstein 2", "FKLZ18", 2, 6, 16, },
+ { "Wiesbaden 1", "WI1", 2, 6, 17, },
+ { "Wiesbaden 33", "FKLZ34", 2, 6, 18, },
+ { "Wiesbaden 34", "FKLZ32", 2, 6, 19, },
+ { "Wiesbaden 35 (Igstadt)", "FKLZ35", 2, 6, 20, },
+ { "Kelsterbach 0.9U", "MDR", 2, 6, 21, },
+ { "Mainz-Kastel 2", "FKLZ33", 2, 6, 22, },
+ { "Mainz 3", "FKLZ29", 2, 6, 23, },
+ { "Mainz 4", "FKLZ27", 2, 6, 24, },
+ { "Mainz 5", "FKLZ30", 2, 6, 25, },
+ { "Mainz 26", "FKLZ28", 2, 6, 26, },
+ { "Niedernhausen 4", "FKLZ80", 2, 6, 27, },
+ { "Eppstein 1", "EPP1", 2, 6, 28, },
+ { "Roedermark 7", "ROEM7", 2, 6, 30, },
+ { "Kastellaun 2", "KAST", 2, 6, 31, },
+ { "Lorch Rheingau 3", "FKLZ45", 2, 6, 32, },
+ { "Oppenheim 1", "FKLZ53", 2, 6, 34, },
+ { "Pfungstadt 1", "FKLZ40", 2, 6, 35, },
+ { "Bad Soden 3", "FKLZ76", 2, 6, 36, },
+ { "Kronberg i Taunus 3", "FKLZ21", 2, 6, 37, },
+ { "Frankfurt 000 (Zeil)", "FKLZ01", 2, 6, 38, },
+ { "Frankfurt 085 (Rohm)", "FKLZ04", 2, 6, 39, },
+ { "Frankfurt 001 (Raim)", "FKLZ03", 2, 6, 40, },
+ { "Frankfurt 118 (Giess)", "FKLZ05", 2, 6, 41, },
+ { "Koenigstein i Taunus 3", "FKLZ20", 2, 6, 42, },
+ { "Frankfurt 111 (D.Pl)", "FKLZ06", 2, 6, 43, },
+ { "Neu-Isenburg 0.8Q", "FNI82", 2, 6, 44, },
+ { "Frankfurt 120 (St.H)", "FKLZ12", 2, 6, 45, },
+ { "Kriftel 0.8V", "HATH", 2, 6, 46, },
+ { "Kelkheim Taunus 1", "FKLZ19", 2, 6, 47, },
+ { "Oberursel Taunus 2", "FKLZ23", 2, 6, 48, },
+ { "Frankfurt 123 (Berk)", "FKLZ13", 2, 6, 49, },
+ { "Frankfurt 046 (Diest)", "FKLZ08", 2, 6, 50, },
+ { "Frankfurt 88.9L(TGrVSt7/73)", "FKLZ02", 2, 6, 51, },
+ { "Frankfurt 121 (Lyon)", "FKLZ10", 2, 6, 52, },
+ { "Frankfurt 021 (Oeser)", "FKLZ11", 2, 6, 53, },
+ { "Bad Vilbel 4 <ers. B. Vil5>", "FKLZ14", 2, 6, 54, },
+ { "Frankfurt 82.8F (Orb)", "FKLZ07", 2, 6, 55, },
+ { "Frankfurt 098 (Flugh)", "FKLZ64", 2, 6, 56, },
+ { "Lorch Rheingau 4", "FKLZ43", 2, 6, 58, },
+ { "Frankfurt 062 (O.Jah)", "FKLZ15", 2, 6, 61, },
+ { "Nastaetten 1", "NAST1", 2, 6, 62, },
+ { "Babenhausen 3", "FKLZ60", 2, 6, 63, },
+ { "Ober-Ramstadt 5", "FKLZ41", 2, 6, 65, },
+ { "Breuberg 1", "FKLZ67", 2, 6, 66, },
+ { "Oberwesel 1", "OBWS1", 2, 6, 72, },
+ { "Pfalzfeld 1", "PFLZ", 2, 6, 73, },
+ { "Rheinboellen 2", "RHBO2", 2, 6, 74, },
+ { "Ruedesheim a Rhein 2", "RUE2X", 2, 6, 75, },
+ { "Eltville 2", "ELTV2", 2, 6, 76, },
+ { "Winterbach 1", "ECK1", 2, 6, 77, },
+ { "Boppard 1", "BOP1", 2, 6, 78, },
+ { "Frankfurt 122 (O.Kr)", "FKLZ16", 2, 6, 79, },
+ { "Stromberg 2 (Eckenroder F.)", "STRB2", 2, 6, 80, },
+ { "Trebur 1 (SWF SGM)", "TRE1", 2, 6, 81, },
+ { "Frankfurt 26.817", "FRSD", 2, 6, 83, },
+ { "Main-Taunus-Zentrum", "MTZ", 2, 6, 84, },
+ { "Besigheim 71", "HNKL25", 2, 7, 1, },
+ { "Adelberg 0", "ADB0", 2, 7, 2, },
+ { "Wildberg 71", "WILD", 2, 7, 3, },
+ { "Tuebingen 7", "TBN7", 2, 7, 4, },
+ { "Backnang 0", "BA0", 2, 7, 5, },
+ { "Goeppingen 0", "GOEP41", 2, 7, 6, },
+ { "Weilheim 1", "BOLL", 2, 7, 7, },
+ { "Tuebingen 6", "TBN6X", 2, 7, 8, },
+ { "Reutlingen 0", "REU0", 2, 7, 10, },
+ { "Metzingen 4", "ULKL24", 2, 7, 12, },
+ { "Trochtelfingen 2", "TCF2", 2, 7, 13, },
+ { "Ebersbach 1", "EBRB41", 2, 7, 14, },
+ { "Marbach 41", "SKLZ35", 2, 7, 15, },
+ { "Bad Liebenzell 2", "BLIEB2", 2, 7, 16, },
+ { "Bad Urach 2", "ULKL26", 2, 7, 17, },
+ { "Lichtenstein 2", "ULKL25", 2, 7, 18, },
+ { "Muensingen 1", "ULKL05", 2, 7, 19, },
+ { "Suessen 0", "SUES0", 2, 7, 20, },
+ { "Weinsberg 0", "HNKL23", 2, 7, 21, },
+ { "Wendlingen 18", "WEND8", 2, 7, 22, },
+ { "Gomadingen 1", "GOM1", 2, 7, 23, },
+ { "Backnang 43", "BA43X", 2, 7, 24, },
+ { "Maulbronn 42", "HNKL14", 2, 7, 25, },
+ { "Ditzingen 5 (Siemens)", "DITZ99", 2, 7, 26, },
+ { "Neuenstadt 41", "HNKL04", 2, 7, 27, },
+ { "Neckarsulm 72", "HNKL07", 2, 7, 28, },
+ { "Heilbronn 41", "HNKL08", 2, 7, 29, },
+ { "Stuttgart 41 (Mitte)", "SKLZ06", 2, 7, 30, },
+ { "Schwaigern 42", "HNKL10", 2, 7, 31, },
+ { "Stuttgart 31 (Bahnpost.)", "SKLZ08", 2, 7, 32, },
+ { "Heilbronn 1 (MB)", "HNKL11", 2, 7, 33, },
+ { "Besigheim 42", "HNKL12", 2, 7, 34, },
+ { "Stuttgart 580 (Daimler)", "SKLZ14", 2, 7, 35, },
+ { "Waiblingen 3 (Wasserturm)", "SKLZ09", 2, 7, 36, },
+ { "Winnenden 0", "SKLZ10", 2, 7, 37, },
+ { "Brackenheim 1", "HNKL13", 2, 7, 38, },
+ { "Waiblingen 4 (Remsh.-G.)", "SKLZ11", 2, 7, 39, },
+ { "Leonberg 41", "LEO41", 2, 7, 40, },
+ { "Stuttgart 582 (Th.-H.-K.)", "SKLZ13", 2, 7, 41, },
+ { "Bad Wimpfen 41", "HNKL16", 2, 7, 42, },
+ { "Stuttgart 45 (Esslingen)", "SKLZ15", 2, 7, 43, },
+ { "Calw 3", "CLW3", 2, 7, 44, },
+ { "Loewenstein 41", "HNKL17", 2, 7, 45, },
+ { "Boeblingen 4 (Sindelf.)", "SKLZ20", 2, 7, 46, },
+ { "Stuttgart 26 (Moehringen)", "SKLZ21", 2, 7, 47, },
+ { "Stuttgart 62 (Vaihingen)", "SKLZ22", 2, 7, 48, },
+ { "Weil der Stadt 41", "SKLZ23", 2, 7, 49, },
+ { "Leonberg 5 (Rutesheim)", "SKLZ24", 2, 7, 50, },
+ { "Schwaebisch Gmuend 2", "SGMD2", 2, 7, 51, },
+ { "Stuttgart 10", "S10", 2, 7, 52, },
+ { "Schorndorf 0", "SKLZ12", 2, 7, 53, },
+ { "Muenchingen 51", "SKLZ27", 2, 7, 54, },
+ { "Vaihingen 1", "SKLZ28", 2, 7, 55, },
+ { "Stuttgart 589 (Flughafen)", "SKLZ18", 2, 7, 56, },
+ { "Waldenbuch 3", "WBU3", 2, 7, 57, },
+ { "Ludwigsburg 2", "SKLZ29", 2, 7, 58, },
+ { "Stuttgart 7", "S7", 2, 7, 59, },
+ { "Plochingen 1 (Krankenhaus)", "SKLZ16", 2, 7, 60, },
+ { "Stuttgart 49 (Muenster)", "SKLZ04", 2, 7, 61, },
+ { "Stuttgart 0 (FA 1)", "SKLZ07", 2, 7, 62, },
+ { "Stuttgart 344 (Denkendorf)", "SKLZ31", 2, 7, 63, },
+ { "Ludwigsburg 3", "SKLZ32", 2, 7, 64, },
+ { "Sachsenheim 42", "SKLZ26", 2, 7, 65, },
+ { "Stuttgart 361 (Schanbach)", "SKLZ30", 2, 7, 66, },
+ { "Vaihingen 45", "HNKL18", 2, 7, 67, },
+ { "Moensheim 43", "HNKL15", 2, 7, 68, },
+ { "Neckartenzlingen 6", "SKLZ33", 2, 7, 69, },
+ { "Stuttgart 179 (Echterd.)", "S179", 2, 7, 70, },
+ { "Gomaringen 0", "GORI0", 2, 7, 71, },
+ { "Beilstein 1", "BEIL1", 2, 7, 72, },
+ { "Spraitbach 0", "SPRT0", 2, 7, 74, },
+ { "Sulzbach 41", "SKLZ34", 2, 7, 75, },
+ { "Lenningen 74 (Schopfloch)", "LNNG74", 2, 7, 76, },
+ { "Bad Boll 0", "BOLL0", 2, 7, 77, },
+ { "Heilbronn 18", "HB18", 2, 7, 79, },
+ { "Weinsberg 42", "WEIN42", 2, 7, 80, },
+ { "Lorch 1", "LRCH1", 2, 7, 82, },
+ { "Nuertingen 41", "SKLZ02", 2, 7, 87, },
+ { "Marbach 71", "SKLZ05", 2, 7, 89, },
+ { "Kirchheim 0", "SKLZ17", 2, 7, 90, },
+ { "Remseck 1", "NECK", 2, 7, 91, },
+ { "Ehningen 4", "SKLZ19", 2, 7, 92, },
+ { "Kaisersbach 1", "KABA1", 2, 7, 93, },
+ { "Neuffen 0", "NFF0", 2, 7, 94, },
+ { "Oberderdingen-Flehingen 3", "BAHN02", 2, 7, 96, },
+ { "Markgroeningen 4 (Glemstal)", "BAHN03", 2, 7, 97, },
+ { "Muenchen 852 (Planegg)", "M852", 2, 8, 2, },
+ { "Muenchen 173 (Studentenstadt)", "M173", 2, 8, 3, },
+ { "Muenchen 44 (Ufg Ahornstr)", "MKLZ34", 2, 8, 4, },
+ { "Muenchen 614 (Oberhaching)", "M613", 2, 8, 5, },
+ { "Sauerlach 2", "MKLZ29", 2, 8, 6, },
+ { "Vaterstetten 1", "VATS1", 2, 8, 10, },
+ { "Muenchen 18", "M18", 2, 8, 29, },
+ { "Muenchen 108 (Blumenstrasse)", "MKLZ01", 2, 8, 30, },
+ { "Muenchen 270 (Isabellastrasse)", "MKLZ02", 2, 8, 31, },
+ { "Muenchen 103 (Arabellastrasse)", "MKLZ03", 2, 8, 32, },
+ { "Muenchen 104 (Kirchenstrasse)", "MKLZ04", 2, 8, 33, },
+ { "Muenchen 113 (Siemens Werinh)", "MKLZ05", 2, 8, 34, },
+ { "Muenchen 0 (Blutenburgstrasse)", "MKLZ08", 2, 8, 37, },
+ { "Muenchen 109 (Neuherbergstr.)", "MKLZ09", 2, 8, 38, },
+ { "Muenchen 430 (Am Luessl 15)", "MKLZ12", 2, 8, 39, },
+ { "Muenchen 106 (Rennb.Daglfing)", "MKLZ11", 2, 8, 40, },
+ { "Muenchen 670 (Heinrich-Luebke)", "MKLZ13", 2, 8, 41, },
+ { "Muenchen 107 (Harlaching KH)", "MKLZ14", 2, 8, 42, },
+ { "Muenchen 112 (Baierbr.Str.)", "MKLZ15", 2, 8, 43, },
+ { "Muenchen 110 (Winfrieds.Laim)", "MKLZ17", 2, 8, 45, },
+ { "Muenchen 105 (Grossm.Thalk.S.)", "MKLZ06", 2, 8, 48, },
+ { "Muenchen 111 (Philips Ridler)", "MKLZ07", 2, 8, 49, },
+ { "Muenchen 117 (Garching)", "MKLZ20", 2, 8, 52, },
+ { "Gilching 4 <Ers. f. M410>", "GIL98", 2, 8, 54, },
+ { "Muenchen 114 (Germering)", "MKLZ21", 2, 8, 55, },
+ { "Muenchen 22 (Unterschleissh.)", "MKLZ23", 2, 8, 57, },
+ { "Hoehenkirchen 2 <ers. MKLZ24>", "HK99", 2, 8, 58, },
+ { "Muenchen 115 (Baierbrunn)", "MKLZ27", 2, 8, 61, },
+ { "Muenchen 65 (Stiftsbogen)", "MKLZ35", 2, 8, 84, },
+ { "Muenchen 51 (Alzeyerstr.)", "MKLZ36", 2, 8, 85, },
+ { "Nuernberg 0", "N0", 2, 9, 1, },
+ { "Nuernberg 5", "N5", 2, 9, 4, },
+ { "Nennslingen 1", "NNL1", 2, 9, 5, },
+ { "Betzenstein 1", "BTZ1", 2, 9, 6, },
+ { "Schnaittach 2", "SCHNA", 2, 9, 9, },
+ { "Rothenburg 1", "RBRG1", 2, 9, 14, },
+ { "Roth 0", "ROHT0", 2, 9, 19, },
+ { "Altdorf-Autobahnkreuz 52", "ALTD51", 2, 9, 20, },
+ { "Feucht 0", "FEU0", 2, 9, 21, },
+ { "Ansbach 1", "ANSB", 2, 9, 23, },
+ { "Nuernberg-OPD 9", "N1", 2, 9, 27, },
+ { "Nuernberg-Marienberg 92", "N11", 2, 9, 28, },
+ { "Nuernberg-Bundesanstalt 89", "N13", 2, 9, 30, },
+ { "Nuernberg-Heizkraftwerk 91", "N14", 2, 9, 31, },
+ { "Eschenbach 1", "EBA1", 2, 9, 32, },
+ { "Nuernberg-Mueller Verlag 94", "N16", 2, 9, 33, },
+ { "Lauf 1", "N21", 2, 9, 34, },
+ { "Postbauer-Heng 1", "N22", 2, 9, 35, },
+ { "Schwabach 5", "N23", 2, 9, 36, },
+ { "Herzogenaurach 0", "N29", 2, 9, 37, },
+ { "Langenzenn 1", "N25", 2, 9, 38, },
+ { "Erlangen 1", "N26", 2, 9, 39, },
+ { "Fuerth-Sparkasse 902", "N37", 2, 9, 41, },
+ { "Fuerth-Stadeln 904", "N35", 2, 9, 42, },
+ { "Nuernberg-Triumph Adler 93", "N15", 2, 9, 43, },
+ { "Veitsbronn 3", "N27", 2, 9, 44, },
+ { "Rosstal 4", "N28", 2, 9, 45, },
+ { "Erlangen 98", "ERL99", 2, 9, 46, },
+ { "Sulzbach-Rosenberg 0", "SUBA0", 2, 9, 49, },
+ { "Eckental 1", "ECKT1", 2, 9, 51, },
+ { "Nuernberg-Suedpumpwerk 905", "N31", 2, 9, 53, },
+ { "Wendelstein 2", "N33", 2, 9, 54, },
+ { "Erlangen 60", "N30", 2, 9, 56, },
+ { "Nuernberg-BePo 907", "N32", 2, 9, 58, },
+ { "Hessdorf 0", "HESS0", 2, 9, 60, },
+ { "Treuchtlingen 1", "TREU1", 2, 9, 61, },
+ { "Solnhofen 3", "MOHM", 2, 9, 62, },
+ { "Pommelsbrunn 1", "PMBN1", 2, 9, 63, },
+ { "Neustadt 3", "NSDA2", 2, 9, 64, },
+ { "Langenfeld 1", "LFD1", 2, 9, 65, },
+ { "Stein 901", "N34", 2, 9, 66, },
+ { "Graefenberg 2", "GRBG2", 2, 9, 67, },
+ { "Hoechstadt 4", "HCH4", 2, 9, 68, },
+ { "Ebermannstadt 1", "EBMN1", 2, 9, 69, },
+ { "Schwabach 0", "SBA99", 2, 9, 70, },
+ { "Uffenheim 4", "UFF2", 2, 9, 71, },
+ { "Wilhermsdorf 1", "WILH1", 2, 9, 72, },
+ { "Thalmaessing 2", "THMA2", 2, 9, 73, },
+ { "Wittelshofen 1", "WITH1", 2, 9, 74, },
+ { "Windsbach 2", "WNDB2", 2, 9, 76, },
+ { "Gunzenhausen 1", "GZHS0", 2, 9, 78, },
+ { "Allersberg 1", "ALBG1", 2, 9, 79, },
+ { "Wiesenttal 1", "WTAL1", 2, 9, 80, },
+ { "Forchheim 2", "PBG99", 2, 9, 82, },
+ { "Heilsbronn 1", "HBRO1", 2, 9, 85, },
+ { "Oberasbach 690.47", "N36", 2, 9, 86, },
+ { "Muehlhausen 3", "MH2", 2, 9, 88, },
+ { "Kipfenberg 3", "KIBG3", 2, 9, 93, },
+ { "Burgbernheim 2", "BBH2", 2, 9, 94, },
+ { "Greding 3", "GDN3", 2, 9, 99, },
+ { "Moenchengladbach-Rheydt 8", "MGL8", 3, 2, 13, },
+ { "Teicha 2", "PHA", 3, 3, 1, },
+ { "Greifenhagen 1", "SSN", 3, 3, 2, },
+ { "Markransteadt 2", "MARKR2", 3, 3, 4, },
+ { "Groitsch 6", "LPZGRO", 3, 3, 6, },
+ { "Graefenhainichen 4", "OSK", 3, 3, 7, },
+ { "Liebertwolkwitz", "LIEW", 3, 3, 8, },
+ { "Torgau 4", "TORG", 3, 3, 9, },
+ { "Bitterfeld 1", "BTTF", 3, 3, 10, },
+ { "Oschatz 3", "COL", 3, 3, 11, },
+ { "Leipzig 8 (Stoetteritz)", "STTZ", 3, 3, 12, },
+ { "Halle 15", "HALL", 3, 3, 13, },
+ { "Grimma end", "GRI0", 3, 3, 14, },
+ { "Weissenfels 7", "PTT", 3, 3, 15, },
+ { "Leipzig 0 (Universitaet HH)", "LPZ", 3, 3, 16, },
+ { "Markranstaedt 3 (Doelzig)", "LPZDLZ", 3, 3, 17, },
+ { "Gaschwitz 0", "LPZGAS", 3, 3, 18, },
+ { "Leipzig 26 (Lausen)", "LPZLAU", 3, 3, 19, },
+ { "Leipzig 70 (Seehausen)", "LPZMOC", 3, 3, 20, },
+ { "Schkeuditz 2 (end)", "LPZSCH", 3, 3, 21, },
+ { "Koethen 8", "KOET", 3, 3, 22, },
+ { "Brandis 2 (Machern)", "MAC", 3, 3, 23, },
+ { "Delitzsch 1", "DELI", 3, 3, 24, },
+ { "Leipzig 3 (Holzhausen)", "LPZHOL", 3, 3, 25, },
+ { "Nebra 3", "WGN", 3, 3, 26, },
+ { "Zeitz 9", "ZEITZ", 3, 3, 27, },
+ { "Querfurt 2", "QUERF", 3, 3, 28, },
+ { "Cobbelsdorf 4", "COBB4", 3, 3, 36, },
+ { "Leipzig 49 (Stahmeln)", "LPZSTA", 3, 3, 37, },
+ { "Altenburg 2", "ALBG", 3, 3, 38, },
+ { "Leipzig 10 (Connewitz)", "LPZTV3", 3, 3, 40, },
+ { "Taucha 2", "LPZTAU", 3, 3, 41, },
+ { "Leipzig 31 (Eutritzsch)", "LPZEUT", 3, 3, 42, },
+ { "Leipzig 69 (Schoenefeld)", "LPZSFE", 3, 3, 43, },
+ { "Dommitzsch 1 (Roitzsch)", "ROI", 3, 3, 44, },
+ { "Leipzig 62 (Adler)", "LPZPLA", 3, 3, 45, },
+ { "Naumburg 0", "NAUM", 3, 3, 46, },
+ { "Leipzig 73 (Gohlis)", "LPZGOH", 3, 3, 47, },
+ { "Halle 2 (Seeben)", "HZ04", 3, 3, 48, },
+ { "Sangerhausen 2", "LENG", 3, 3, 49, },
+ { "Halle 21 (Bruckdorf)", "HZ01", 3, 3, 50, },
+ { "Colditz 1", "COLD1", 3, 3, 52, },
+ { "Hartha 1", "HTA", 3, 3, 56, },
+ { "Dessau 12.97B1 (Sued)", "DESS12", 3, 3, 58, },
+ { "Eisleben 5", "ORIDF", 3, 3, 59, },
+ { "Teutschenthal", "TEUTS", 3, 3, 60, },
+ { "Halle 33 (Silberhoehe)", "HZ05", 3, 3, 61, },
+ { "Halle 39 (Neustadt)", "HZ02", 3, 3, 62, },
+ { "Merseburg 0", "MRSB", 3, 3, 63, },
+ { "Schmoelln 1", "SMLL1", 3, 3, 70, },
+ { "Eilenburg 7", "EBG", 3, 3, 71, },
+ { "Hayn 2", "HAY", 3, 3, 72, },
+ { "Dessau 1 (Mildensee prov)", "DESS", 3, 3, 73, },
+ { "Borna 0", "BORNA", 3, 3, 74, },
+ { "Belgern 2", "BELPU", 3, 3, 75, },
+ { "Hettstedt 3", "HSDT", 3, 3, 76, },
+ { "Bad Dueben 5 (Wellaune)", "BDUEB", 3, 3, 77, },
+ { "Halle 37 (Peissen)", "HZ03", 3, 3, 78, },
+ { "Halle 14 (Heide-Nord)", "HZ06", 3, 3, 79, },
+ { "Oelzschau 1", "BGHN", 3, 3, 80, },
+ { "Doebeln 5", "DOEB", 3, 3, 81, },
+ { "Coswig-Anhalt 6 (end)", "COSA6", 3, 3, 82, },
+ { "Mockrehna 1", "MOCK", 3, 3, 83, },
+ { "Leipzig 19 (Leutzsch)", "LPZLEU", 3, 3, 84, },
+ { "Hohenmoelsen", "HOML1", 3, 3, 85, },
+ { "Wittenberg 0 (end)", "WITTB0", 3, 3, 86, },
+ { "Bad Duerrenberg 4.97B1", "BDUE", 3, 3, 87, },
+ { "Kropstaedt 1000", "KROP10", 3, 3, 88, },
+ { "Leipzig 32 (Markleeberg)", "LPZMMA", 3, 3, 89, },
+ { "Schiffdorf 2", "SCHFD2", 3, 4, 1, },
+ { "Emden 0", "EM0", 3, 4, 2, },
+ { "Bad Zwischenahn 0", "BZW0", 3, 4, 4, },
+ { "Wardenburg 0", "WARD0", 3, 4, 5, },
+ { "Bremen 38 (Utbremer Str.)", "BRM38", 3, 4, 6, },
+ { "Verden-Walle 1", "VWA1", 3, 4, 7, },
+ { "Hoya 1", "HOY1", 3, 4, 8, },
+ { "Heeslingen-Boitzen 1", "HSL1", 3, 4, 9, },
+ { "Aurich", "AURI", 3, 4, 10, },
+ { "Borkum 0", "BORK0", 3, 4, 11, },
+ { "Doerpen 0", "DOER0", 3, 4, 12, },
+ { "Vechta-Langfoerden 1", "VLF1", 3, 4, 14, },
+ { "Jever 0", "JEV", 3, 4, 15, },
+ { "Rotenburg 0", "ROTB0", 3, 4, 16, },
+ { "Wilhelmshaven 0", "WHV0", 3, 4, 18, },
+ { "Cuxhaven 10", "CUX10", 3, 4, 23, },
+ { "Harsefeld 1", "HSFD1", 3, 4, 24, },
+ { "Leer 1", "LEE1", 3, 4, 25, },
+ { "Helgoland 0", "HGL0", 3, 4, 26, },
+ { "Hemmoor 1/2", "HMO1", 3, 4, 27, },
+ { "Hambergen 1", "HMB1", 3, 4, 28, },
+ { "Bassum 3", "BAS3", 3, 4, 29, },
+ { "Stade 1", "STD1", 3, 4, 30, },
+ { "Bremen 0 (Neuenstr.76)", "BRM0", 3, 4, 31, },
+ { "Ottersberg 2", "OTT2", 3, 4, 33, },
+ { "Visselhoevede 0", "VISS0", 3, 4, 34, },
+ { "Westerstede 9", "WSST9", 3, 4, 35, },
+ { "Bremen 135 (Findorf)", "BRM135", 3, 4, 37, },
+ { "Ritterhude 0", "RTH0", 3, 4, 38, },
+ { "Delmenhorst 0", "DLH0", 3, 4, 39, },
+ { "Bremen 80 (Stuhr/Seckenh.)", "BRM80", 3, 4, 40, },
+ { "Weyhe 0", "WYH0", 3, 4, 41, },
+ { "Bremen 136 (Tenever Hochhs)", "BRM136", 3, 4, 42, },
+ { "Lilienthal 3", "LLT3", 3, 4, 43, },
+ { "Hude Oldb 0", "HUD0", 3, 4, 45, },
+ { "Oldenburg 1 (MB)", "OD1", 3, 4, 47, },
+ { "Oldenburg 0", "OD0", 3, 4, 48, },
+ { "Norden 0", "NDN0", 3, 4, 65, },
+ { "Bremen 130 (Walle Hochhaus)", "BRM130", 3, 4, 67, },
+ { "Bremen 131 (Woltmershausen)", "BRM131", 3, 4, 68, },
+ { "Bremen 51 (Grolland)", "BRM132", 3, 4, 69, },
+ { "Bremen 133 (Huckelriede)", "BRM133", 3, 4, 70, },
+ { "Bremen 134 (In der Wisch)", "BRM134", 3, 4, 71, },
+ { "Bremen 137 (Kloeckner)", "BRM137", 3, 4, 74, },
+ { "Bremen 138 (Grohner Duene)", "BRM138", 3, 4, 75, },
+ { "Gross Ippener 0", "GIP0", 3, 4, 77, },
+ { "Sulingen 0", "SLG0", 3, 4, 78, },
+ { "Hatten 10", "HAT0", 3, 4, 79, },
+ { "Zeven 2", "ZEV2", 3, 4, 80, },
+ { "Berne 0", "BERN0", 3, 4, 85, },
+ { "Bremervoerde 0", "BRV0", 3, 4, 87, },
+ { "Osterh.-Scharmb.-Garlst.0", "OHZG0", 3, 4, 88, },
+ { "Wangerland-Horumersiel 0", "HMS0", 3, 4, 89, },
+ { "Wildeshausen 11", "WHS11", 3, 4, 90, },
+ { "Langeoog 1", "LOG0", 3, 4, 91, },
+ { "Varel 1", "VRL1", 3, 4, 92, },
+ { "Friesoythe 0", "FRY0", 3, 4, 93, },
+ { "Kirchlinteln 1", "KIRL1", 3, 4, 94, },
+ { "Papenburg 0", "PAP0", 3, 4, 95, },
+ { "Cloppenburg 0", "CLP0", 3, 4, 96, },
+ { "Wittmund-Burhafe 1", "WITB1", 3, 4, 98, },
+ { "Homberg 1", "HRE1", 3, 5, 1, },
+ { "Morschen 2", "BEIS", 3, 5, 2, },
+ { "Spangenberg 1", "SPBG", 3, 5, 3, },
+ { "Kassel Baunatal", "KSBT", 3, 5, 5, },
+ { "Korbach 0", "KOR0", 3, 5, 8, },
+ { "Arolsen 0", "AROL1", 3, 5, 9, },
+ { "Zierenberg 3", "ZIE3", 3, 5, 10, },
+ { "Hofgeismar 2", "HFGM2", 3, 5, 11, },
+ { "Bad Karlshafen 1", "BKFN1", 3, 5, 12, },
+ { "Fritzlar 2", "FRITZ2", 3, 5, 13, },
+ { "Warburg 2", "WAR2", 3, 5, 14, },
+ { "Willebadessen 1", "WBE1", 3, 5, 15, },
+ { "Goettingen 2", "GOE2", 3, 5, 17, },
+ { "Moringen-Fredelsloh 1", "MOF1", 3, 5, 18, },
+ { "Zierenberg 1", "ZIE1", 3, 5, 19, },
+ { "Grossalmerode 1", "GRA1X", 3, 5, 21, },
+ { "Kassel 1", "KS1", 3, 5, 22, },
+ { "Herzberg 0", "HERZ0", 3, 5, 25, },
+ { "Holzminden-Neuhaus 2", "HZH2", 3, 5, 26, },
+ { "Rosdorf 40", "ROSD40", 3, 5, 27, },
+ { "Osterode 40", "OSRR40", 3, 5, 28, },
+ { "Eschwege 5", "ESW5", 3, 5, 30, },
+ { "Sontra 2", "SONT2", 3, 5, 31, },
+ { "Melsungen 5", "MELS5", 3, 5, 32, },
+ { "Hann Muenden 2", "HMUE2", 3, 5, 33, },
+ { "Reinhardshagen 40", "RAHG40", 3, 5, 34, },
+ { "Bad Sachsa 1", "BSA1", 3, 5, 35, },
+ { "Hann Muenden 3", "BAHN06", 3, 5, 38, },
+ { "Northeim 4", "NORT4", 3, 5, 39, },
+ { "Kassel Vellmar", "KSVM", 3, 5, 41, },
+ { "Braunlage 40", "BRL40", 3, 5, 43, },
+ { "Waldkappel 99", "WALD99", 3, 5, 44, },
+ { "Edertal 99", "EDT99", 3, 5, 45, },
+ { "Brakel 2", "BRAK2", 3, 5, 46, },
+ { "Hessisch Lichtenau 97", "HELI97", 3, 5, 47, },
+ { "Duderstadt Wasserwerk", "DUDW", 3, 5, 48, },
+ { "Bad Sooden Allendorf 1", "BSAD1", 3, 5, 49, },
+ { "Bad Wildungen 1", "BWN1", 3, 5, 51, },
+ { "Woelfterode 99", "WROD99", 3, 5, 54, },
+ { "Kalefeld 40", "KD40", 3, 5, 55, },
+ { "Kassel 4", "KS4", 3, 5, 56, },
+ { "Buchenberg 99", "BUBG99", 3, 5, 58, },
+ { "Frankfurt 016", "F16", 2, 6, 1, },
+ { "Bad Homburg 0 <FDG>", "BHBG0", 3, 6, 1, },
+ { "Friedberg 1", "FB1", 3, 6, 2, },
+ { "Schotten Hess 1", "STT1", 3, 6, 3, },
+ { "Gelnhausen 7", "GN7", 3, 6, 4, },
+ { "Bad Schwalbach 3", "FKLZ83", 3, 6, 5, },
+ { "Friedberg 0", "FB0", 3, 6, 6, },
+ { "Biedenkopf 2 <prov>", "BID2", 3, 6, 7, },
+ { "Biedenkopf 3", "BID3", 3, 6, 10, },
+ { "Birstein 3", "BIR3", 3, 6, 11, },
+ { "Weibersbrunn 2", "WBBR2", 3, 6, 12, },
+ { "Kalbach 1", "KALB1", 3, 6, 13, },
+ { "Driedorf 2", "DRIE2", 3, 6, 14, },
+ { "Lich 2 <Steinbach Bw-Mast>", "LICH0", 3, 6, 15, },
+ { "Hilders 2", "HIL2", 3, 6, 17, },
+ { "Frankenberg 0", "FRANK0", 3, 6, 18, },
+ { "Friedewald 1", "FDWD1", 3, 6, 19, },
+ { "Hanau 1", "FKLZ50", 3, 6, 21, },
+ { "Gemuenden/Felda 1", "GMF1", 3, 6, 22, },
+ { "Gruenberg 0", "GRNB0", 3, 6, 23, },
+ { "Hanau 7", "HU7", 3, 6, 24, },
+ { "Hungen 2", "HUNG2", 3, 6, 25, },
+ { "Gemuenden 1", "GMU1", 3, 6, 26, },
+ { "Biebertal 1", "BIT1", 3, 6, 27, },
+ { "Marburg 2", "MAR2", 3, 6, 28, },
+ { "Haina Kloster 1 <n. Turm>", "HKL1", 3, 6, 29, },
+ { "Weilburg 6", "WBG6", 3, 6, 30, },
+ { "Fulda 3", "FD3", 3, 6, 31, },
+ { "Bad Hersfeld 2", "BHEF2", 3, 6, 32, },
+ { "Schluechtern 3", "SLN3", 3, 6, 33, },
+ { "Neuenstein Hess 1", "NST1", 3, 6, 34, },
+ { "Ebersburg 2", "EBER2", 3, 6, 35, },
+ { "Lauterbach 1", "LAT1", 3, 6, 36, },
+ { "Gruenberg 1", "GRUEN1", 3, 6, 37, },
+ { "Ortenberg 1", "ORT1", 3, 6, 38, },
+ { "Alsfeld 1", "ALS1", 3, 6, 39, },
+ { "Katzenelnbogen 1", "KATZ1", 3, 6, 41, },
+ { "Aarbergen 1", "FKLZ47", 3, 6, 43, },
+ { "Bad Schwalbach 2", "FKLZ48", 3, 6, 45, },
+ { "Schlangenbad 1", "FKLZ49", 3, 6, 46, },
+ { "Lich Hess. Eberstadt 1", "EBST1", 3, 6, 47, },
+ { "Aschaffenburg 14", "AB14", 3, 6, 48, },
+ { "Schwalmstadt 1", "SSDT1", 3, 6, 50, },
+ { "Nentershausen", "NENT", 3, 6, 51, },
+ { "Reichelsheim 2", "FKLZ62", 3, 6, 52, },
+ { "Woelfersheim 2 <Wbh>", "FKLZ68", 3, 6, 53, },
+ { "Limburg 1", "LM1", 3, 6, 54, },
+ { "Rotenburg 1 (TVU)", "ROF3", 3, 6, 55, },
+ { "Burgsinn 8", "BAHN11", 3, 6, 56, },
+ { "Schlitz 3", "SLTZ", 3, 6, 57, },
+ { "Wildeck 1", "WECK1", 3, 6, 58, },
+ { "Friedrichsdorf 0.8I", "KPTL", 3, 6, 59, },
+ { "Taunusstein 2", "FKLZ46", 3, 6, 60, },
+ { "Giessen 0", "GI0", 3, 6, 61, },
+ { "Linden 5", "GI3", 3, 6, 62, },
+ { "Breitenbach 3", "BHERZ", 3, 6, 63, },
+ { "Bad Brueckenau 1", "BADBR1", 3, 6, 64, },
+ { "Buseck 6.8Q", "BUS6", 3, 6, 65, },
+ { "Eckartshausen 2 endg.", "FKLZ72", 3, 6, 66, },
+ { "Steinau 1 (Fa ODW)", "STEI1", 3, 6, 68, },
+ { "Nidda 3", "NID3", 3, 6, 69, },
+ { "Braunfels 5", "BRAU5", 3, 6, 70, },
+ { "Langenselbold 0", "LSBD0", 3, 6, 71, },
+ { "Usingen 2", "USI2", 3, 6, 72, },
+ { "Ehringshausen 1", "EHR1", 3, 6, 74, },
+ { "Seligenstadt 2", "FKLZ25", 3, 6, 75, },
+ { "Bad Nauheim 2", "BNAU2", 3, 6, 77, },
+ { "Aschaffenburg 11", "AB11", 3, 6, 78, },
+ { "Aschaffenburg 13", "AB13", 3, 6, 79, },
+ { "Hanau-Grossauheim 5", "HUAU", 3, 6, 80, },
+ { "Dillenburg 1", "DILB1", 3, 6, 81, },
+ { "Eschenburg 1", "ESCH1", 3, 6, 82, },
+ { "Herleshausen 1", "HERL1", 3, 6, 83, },
+ { "Idstein 2", "FKLZ36", 3, 6, 84, },
+ { "Herborn Hess. 3", "HRBN3", 3, 6, 85, },
+ { "Selters 3", "SELT3", 3, 6, 86, },
+ { "Bad Camberg 3", "BCA3", 3, 6, 87, },
+ { "Karben 1", "FKLZ65", 3, 6, 88, },
+ { "Lohr 2", "LOHR2", 3, 6, 89, },
+ { "Neuhof-Fulda 3(Landruecken)", "BAHN10", 3, 6, 90, },
+ { "Esselbach 2", "ESB2", 3, 6, 91, },
+ { "Moembris 4", "MOEM4", 3, 6, 92, },
+ { "Obernburg 1", "OBG99", 3, 6, 93, },
+ { "Wetzlar 3", "WZ3", 3, 6, 94, },
+ { "Guxhagen 1 (Koerle)", "BAHN07", 3, 6, 95, },
+ { "Niederaula 3 (Kirchheim)", "BAHN08", 3, 6, 96, },
+ { "Huenfeld 2 (Dietershan)", "BAHN09", 3, 6, 97, },
+ { "Wiesen 1", "WIES1", 3, 6, 98, },
+ { "Faulbach 2", "FAUL2", 3, 6, 99, },
+ { "Baden-Baden 5", "BAD5", 3, 7, 1, },
+ { "Pforzheim 7", "PFO7", 3, 7, 2, },
+ { "Loerrach 4", "LOR4X", 3, 7, 3, },
+ { "Badenweiler 1", "BAW1", 3, 7, 4, },
+ { "Titisee-Neustadt 4", "TITI4", 3, 7, 5, },
+ { "Vogtsburg 1", "VO1", 3, 7, 6, },
+ { "Grenzach-Whylen 1", "GRWY1", 3, 7, 7, },
+ { "Hausach 1", "HAU1", 3, 7, 8, },
+ { "Willstaett 1", "WST1", 3, 7, 9, },
+ { "Bad Herrenalb 3", "BHA3", 3, 7, 10, },
+ { "Karlsruhe 7 (Hagsfeld)", "KA7", 3, 7, 11, },
+ { "Rastatt 6", "RAST6", 3, 7, 12, },
+ { "Freiburg-Tiengen P01", "FRT3", 3, 7, 13, },
+ { "Gaggenau 0", "GAG", 3, 7, 14, },
+ { "Efringen-Kirchen 4", "EFI4", 3, 7, 15, },
+ { "Lichtenau 0", "LICHT", 3, 7, 16, },
+ { "Eppingen 2", "HNKL09", 3, 7, 17, },
+ { "Bad Rappenau 0", "HNKL03", 3, 7, 18, },
+ { "Kirchhardt 2", "HNKL05", 3, 7, 19, },
+ { "Oberkirch 3", "OBK3", 3, 7, 20, },
+ { "Oppenau 2", "OPP2", 3, 7, 21, },
+ { "Offenburg 0", "OG", 3, 7, 22, },
+ { "Lahr 0", "LAHR", 3, 7, 23, },
+ { "Ettenheim 3", "ETT3", 3, 7, 24, },
+ { "Achern 2", "ACH2", 3, 7, 25, },
+ { "Schwanau 0", "SCNA", 3, 7, 26, },
+ { "Oberderdingen-Flehingen 1", "ODF1", 3, 7, 27, },
+ { "Pforzheim 2", "PFO2", 3, 7, 28, },
+ { "Freiburg 51", "FR51", 3, 7, 29, },
+ { "Denzlingen 0", "DENZ0", 3, 7, 30, },
+ { "Schopfheim 2", "SPFH2", 3, 7, 31, },
+ { "Gengenbach 2", "GEN2", 3, 7, 32, },
+ { "Kirchzarten 4", "KIZN4", 3, 7, 33, },
+ { "Waldkirch 0", "WAK0", 3, 7, 35, },
+ { "Emmendingen 0", "EMMD0", 3, 7, 36, },
+ { "Pforzheim 71 (Sonnenhof)", "PFO71", 3, 7, 37, },
+ { "Rheinfelden 0", "RF0", 3, 7, 38, },
+ { "Bruchsal-Untergrombach 2", "BRUG2", 3, 7, 39, },
+ { "Loerrach 5", "LOR5", 3, 7, 40, },
+ { "Walzbachtal 1", "KAKL21", 3, 7, 41, },
+ { "Karlsruhe 0 (Haupt-PA)", "KAKL12", 3, 7, 42, },
+ { "Oestringen 1", "KAKL48", 3, 7, 43, },
+ { "Karlsruhe 1 (MB)", "KAKL40", 3, 7, 44, },
+ { "Karlsruhe 170 (Neureut)", "KAKL14", 3, 7, 45, },
+ { "Karlsruhe 83 (Siemens)", "KAKL15", 3, 7, 46, },
+ { "Eichstetten 1", "EICHN1", 3, 7, 47, },
+ { "Karlsruhe 88 (Th.-M.-Str.)", "KAKL16", 3, 7, 48, },
+ { "Schliengen 3", "SCHLI3", 3, 7, 49, },
+ { "Durmersheim 0", "KAKL42", 3, 7, 51, },
+ { "Malsch 2", "KAKL19", 3, 7, 52, },
+ { "Bruchsal 6", "KAKL22", 3, 7, 53, },
+ { "Soellingen P01", "SOEL", 3, 7, 54, },
+ { "Freiburg 58", "FR58", 3, 7, 55, },
+ { "Freiburg-Industr. Nord P11", "FR11", 3, 7, 56, },
+ { "Sinsheim 7", "KAKL23", 3, 7, 57, },
+ { "Schluchsee 1", "SLSE1", 3, 7, 58, },
+ { "Baden-Baden 0", "BAD0", 3, 7, 59, },
+ { "Bad Schoenborn 5", "BSCHB5", 3, 7, 60, },
+ { "Linkenheim-Hochstetten 3", "LIHO3", 3, 7, 61, },
+ { "Baden-Baden 4", "BAD4", 3, 7, 62, },
+ { "St. Blasien 1", "STB1", 3, 7, 63, },
+ { "Kehl 0", "KEHL0", 3, 7, 66, },
+ { "Marxzell 1", "MARXZ1", 3, 7, 67, },
+ { "Bretten 3", "KAKL51", 3, 7, 68, },
+ { "Muellheim 7", "MULL7", 3, 7, 70, },
+ { "Sulzburg 4", "SULBG4", 3, 7, 75, },
+ { "Neuenbuerg 1", "NEUBG1", 3, 7, 76, },
+ { "Landau 2", "LAN2", 3, 7, 77, },
+ { "Forbach 4", "FOR3", 3, 7, 79, },
+ { "Germersheim 2", "KAKL53", 3, 7, 80, },
+ { "Waghaeusel 2", "KAKL24", 3, 7, 81, },
+ { "Rheinstetten 3", "RHEI3", 3, 7, 82, },
+ { "Woerth a Rhein 0", "KAKL11", 3, 7, 83, },
+ { "Ruelzheim 3", "KAKL09", 3, 7, 84, },
+ { "Zell i.W. 1", "ZLIW1", 3, 7, 85, },
+ { "Todtnau 3", "TODT3", 3, 7, 86, },
+ { "Maulbronn 41", "MAUL", 3, 7, 87, },
+ { "Koenigsbach-Stein 2", "KLSTB", 3, 7, 88, },
+ { "Buehl 0", "BUE2", 3, 7, 90, },
+ { "Schoenau 2", "SNAU2", 3, 7, 91, },
+ { "Karlsbad 2 (Noettingen)", "NOETT", 3, 7, 92, },
+ { "Kenzingen 3", "KEN3", 3, 7, 93, },
+ { "Schoemberg-Calw 1", "SCA1", 3, 7, 95, },
+ { "Wildbad 3 <Prov.>", "WILB1", 3, 7, 96, },
+ { "Enzkloesterle 1", "ENZ1", 3, 7, 97, },
+ { "Augsburg 1", "AU1", 3, 8, 1, },
+ { "Augsburg 3 (Haunstetten)", "AU97", 3, 8, 2, },
+ { "Augsburg 10", "AU10X", 3, 8, 3, },
+ { "Pfronten 2", "PFN2", 3, 8, 4, },
+ { "Dillingen 0", "DLGN0", 3, 8, 5, },
+ { "Affing 2", "AFF2", 3, 8, 6, },
+ { "Aichach 1", "AIC1", 3, 8, 7, },
+ { "Eichstaett 1", "EICH1", 3, 8, 8, },
+ { "Dirlewang 3", "DLW92", 3, 8, 9, },
+ { "Eurasburg 1", "ERB1", 3, 8, 10, },
+ { "Buchloe 1 <Prov. Buchloe 0>", "BULO1", 3, 8, 11, },
+ { "Krumbach 2", "KRUM2", 3, 8, 12, },
+ { "Meitingen 0", "MTN0", 3, 8, 13, },
+ { "Mittelneufnach 1", "MNFN1", 3, 8, 14, },
+ { "Schrobenhausen 4", "SBH4", 3, 8, 15, },
+ { "Schwabmuenchen 0", "SWM0", 3, 8, 16, },
+ { "Thannhausen 2", "THS2", 3, 8, 17, },
+ { "Welden 3", "WE3", 3, 8, 18, },
+ { "Ziemetshausen 2", "ZMH97", 3, 8, 19, },
+ { "Guenzburg 70", "ULKL11", 3, 8, 20, },
+ { "Oberstdorf 0", "OBDO0", 3, 8, 21, },
+ { "Nesselwang 1", "NSW1", 3, 8, 22, },
+ { "Neuburg 1 (IVK)", "NEUB99", 3, 8, 23, },
+ { "Oberstaufen 4 (Stiesberg)", "OBST4", 3, 8, 24, },
+ { "Groenenbach 1", "GROE1", 3, 8, 25, },
+ { "Zusmarshausen 2", "ZUSM2", 3, 8, 26, },
+ { "Fuessen 2", "FSN2", 3, 8, 27, },
+ { "Lindau 1", "LIND1", 3, 8, 28, },
+ { "Augsburg 4 (NCR)", "AU4", 3, 8, 29, },
+ { "Augsburg 907", "AU907", 3, 8, 30, },
+ { "Stammham 2", "STHA99", 3, 8, 33, },
+ { "Ottobeuren 3", "OTTB2", 3, 8, 34, },
+ { "Pfaffenhofen a d Ilm 5", "PFA5", 3, 8, 35, },
+ { "Pfaffenhofen a d Ilm 0", "PFA0", 3, 8, 36, },
+ { "Burgau 0", "BGU0", 3, 8, 37, },
+ { "Schweitenkirchen 2", "SKI99", 3, 8, 38, },
+ { "Ingolstadt-Zuchering 0", "IGZ", 3, 8, 39, },
+ { "Vohburg 1", "VBG1", 3, 8, 40, },
+ { "Wolnzach 1", "WOZ1", 3, 8, 41, },
+ { "Tapfheim 1", "TAPF1", 3, 8, 42, },
+ { "Unterringingen 1", "URR1", 3, 8, 43, },
+ { "Kaisheim 3", "KSH98", 3, 8, 44, },
+ { "Altenstadt 0 (Iller)", "ULKL04", 3, 8, 51, },
+ { "Aitrang 2 (Bergbauer)", "AIT2", 3, 8, 52, },
+ { "Babenhausen 1", "BBHN1", 3, 8, 54, },
+ { "Gruenenbach 1", "GRB1", 3, 8, 55, },
+ { "Immenstadt 1 (Alpe Hochried)", "IMST1", 3, 8, 57, },
+ { "Kaufbeuren 7 (Mauerstetten)", "KFN7", 3, 8, 58, },
+ { "Memmingen 0", "MEMM0", 3, 8, 59, },
+ { "Oberguenzburg 1", "OGB1", 3, 8, 61, },
+ { "Sonthofen 1", "SOHO1", 3, 8, 67, },
+ { "Weiler 1", "WEIL1", 3, 8, 68, },
+ { "Wiggensbach 2", "WIG2", 3, 8, 70, },
+ { "Neuburg 2", "NEUB2", 3, 8, 78, },
+ { "Poernbach 2", "PNB99", 3, 8, 81, },
+ { "Dortmund 85 (Eving)", "DO85", 4, 2, 8, },
+ { "Dresden 7 (Gompitz)", "GPZ", 4, 3, 1, },
+ { "Crinitz 1", "BBB", 4, 3, 2, },
+ { "Dresden 12 (Dachsenberg)", "DACHS", 4, 3, 3, },
+ { "Weisswasser 0.47B1", "WSWS", 4, 3, 4, },
+ { "Drebkau 1", "KLO", 4, 3, 5, },
+ { "Senftenberg 6", "SENF6", 4, 3, 7, },
+ { "Radeburg 1", "FRTL", 4, 3, 8, },
+ { "Meissen 5 (end)", "MSSN", 4, 3, 9, },
+ { "Pirna 7", "PIRN", 4, 3, 10, },
+ { "Koenigswartha 1", "KWTA", 4, 3, 11, },
+ { "Dresden 3 (Radebeul)", "DRES3", 4, 3, 12, },
+ { "Dresden 1 (Postplatz)", "DRES1", 4, 3, 13, },
+ { "Pulsnitz 4", "KEU", 4, 3, 14, },
+ { "Loebau 5", "LBAU", 4, 3, 15, },
+ { "Neukirch 5 (Picho)", "PICHO", 4, 3, 16, },
+ { "Neustadt 1 (Unger)", "NEUDT1", 4, 3, 17, },
+ { "Goerlitz 7", "GRLZ", 4, 3, 18, },
+ { "Zittau 5", "ZTT", 4, 3, 19, },
+ { "Altenberg 1 (Lugstein)", "LUGS", 4, 3, 20, },
+ { "Riesa 4", "RIESA", 4, 3, 21, },
+ { "Burkau 2", "BURK2", 4, 3, 22, },
+ { "Dresden 79 (Goennsdorf)", "DRESBU", 4, 3, 23, },
+ { "Jessen 2", "JESS", 4, 3, 24, },
+ { "Dippoldiswalde 3", "DIPP", 4, 3, 25, },
+ { "Heidenau 1", "DRESHE", 4, 3, 26, },
+ { "Hoyerswerda 2", "HYWD", 4, 3, 27, },
+ { "Dresden 27 ()", "DRESDS", 4, 3, 28, },
+ { "Dresden 40 (Dorfhainer Str)", "DRES40", 4, 3, 29, },
+ { "Dresden 75 (Striesen)", "DRES24", 4, 3, 30, },
+ { "Elsterwerda 5", "HLP", 4, 3, 31, },
+ { "Spremberg 5", "SPRE", 4, 3, 33, },
+ { "D-Klotzs ???", "???", 4, 3, 34, },
+ { "Herzberg 1", "HERZ", 4, 3, 35, },
+ { "Dresden 77 (Prohlis)", "DRESNI", 4, 3, 36, },
+ { "Niesky 5", "NSKY", 4, 3, 37, },
+ { "Dresden 63 (Neustadt)", "DRESNS", 4, 3, 39, },
+ { "Burkhardswalde 1", "BUHW", 4, 3, 40, },
+ { "Guben 3 <Ers. f. GUBK>", "GUBEN2", 4, 3, 41, },
+ { "Bautzen 1", "BZN", 4, 3, 42, },
+ { "Bad Schandau 1", "BSD", 4, 3, 43, },
+ { "Forst 2", "FORST", 4, 3, 44, },
+ { "Bischofswerda 3", "BHW", 4, 3, 45, },
+ { "Cottbus 8", "COTT8", 4, 3, 46, },
+ { "Ortrand 0", "ORA", 4, 3, 47, },
+ { "Tharandt 2", "THAR2", 4, 3, 48, },
+ { "Drachhausen 1", "DH", 4, 3, 49, },
+ { "Kamenz 5", "KAMZ5", 4, 3, 51, },
+ { "Grossenhain 5", "GROS5", 4, 3, 52, },
+ { "Lommatzsch 3", "LOMM3", 4, 3, 54, },
+ { "Pirna 5", "PIRN5", 4, 3, 55, },
+ { "Glashuette 1", "GLAS1", 4, 3, 56, },
+ { "Coswig-Sachsen 4", "COSW4", 4, 3, 57, },
+ { "Wilsdruff 2", "WILSD2", 4, 3, 59, },
+ { "Finsterwalde 3", "FW", 4, 3, 60, },
+ { "Neugersdorf 7", "NEUG7", 4, 3, 61, },
+ { "Uhyst 1", "UHYS1", 4, 3, 64, },
+ { "Pulsnitz 6", "PULS6", 4, 3, 66, },
+ { "Doberlug-Kirchhain 2", "DOB2", 4, 3, 88, },
+ { "Bad Doberan 5", "BDBN5", 4, 4, 1, },
+ { "Crivitz 3", "CRIV", 4, 4, 2, },
+ { "Wolgast 3", "WOLG", 4, 4, 3, },
+ { "Schwaan 3", "SCHWAN", 4, 4, 4, },
+ { "Rostock 26", "LTTK", 4, 4, 5, },
+ { "Tessin 3", "TESS", 4, 4, 6, },
+ { "Broderstorf 4 <Ers.f.BDD1>", "BDD4", 4, 4, 7, },
+ { "Grimmen 2", "GRIM", 4, 4, 8, },
+ { "Sassnitz 9 <Ers.f.SASS>", "SASS9", 4, 4, 9, },
+ { "Rostock 10", "ROST10", 4, 4, 10, },
+ { "Tribsees 3", "TRIB", 4, 4, 11, },
+ { "Barth 3", "BART", 4, 4, 12, },
+ { "Stralsund 0", "STS", 4, 4, 13, },
+ { "Rostock 11", "RWEI", 4, 4, 14, },
+ { "Ribnitz-Damgarten 8<Erf.DAS>", "RIBD", 4, 4, 15, },
+ { "Kroepelin 2", "KROEP2", 4, 4, 16, },
+ { "Greifswald 4", "GRW", 4, 4, 17, },
+ { "Bergen 0", "BRN", 4, 4, 18, },
+ { "Guestrow 20 <Ers.f.GSW>", "GSW20", 4, 4, 19, },
+ { "Schwerin 20", "SRN", 4, 4, 20, },
+ { "Bennin 1", "GRAH", 4, 4, 21, },
+ { "Ludwigslust 2 <Ers.f.LUDWL>", "LUDWL2", 4, 4, 24, },
+ { "Parchim 5", "PARC", 4, 4, 25, },
+ { "Bernitt 1", "BZ4", 4, 4, 26, },
+ { "Wittenburg 2", "ZIGM", 4, 4, 27, },
+ { "Wismar 6", "WISM", 4, 4, 28, },
+ { "Gross Godems 1", "STPE", 4, 4, 29, },
+ { "Sternberg 2", "STERN", 4, 4, 30, },
+ { "Cambs 6", "RMP", 4, 4, 31, },
+ { "Schwerin 4", "SRS", 4, 4, 32, },
+ { "Rastow 2", "RASW", 4, 4, 33, },
+ { "Marnitz 1", "RUBG", 4, 4, 34, },
+ { "Goldberg 4 <Ers.f.KKW>", "GOLD4", 4, 4, 35, },
+ { "Grevesmuehlen 5", "HBGE", 4, 4, 36, },
+ { "Gammelin 1", "BAND", 4, 4, 37, },
+ { "Redefin 2", "REDEL", 4, 4, 38, },
+ { "Roggendorf 1", "RGND1", 4, 4, 39, },
+ { "Heringsdorf 4", "HID4", 4, 4, 40, },
+ { "Torgelow 3", "TOR3", 4, 4, 42, },
+ { "Zuessow 4", "ZUES4", 4, 4, 43, },
+ { "Lalendorf 4", "HOPE2", 4, 4, 44, },
+ { "Krakow 4", "KKW4", 4, 4, 45, },
+ { "Goehren 2", "GOER2", 4, 4, 46, },
+ { "Anklam 2", "ANK", 4, 4, 47, },
+ { "Burow 1", "GOL", 4, 4, 48, },
+ { "Waren 5", "WAREN", 4, 4, 49, },
+ { "Jarmen 7", "JARM", 4, 4, 52, },
+ { "Malchin 5", "RZW", 4, 4, 53, },
+ { "Friedland 3", "FRIL", 4, 4, 56, },
+ { "Stavenhagen 0", "STVH", 4, 4, 57, },
+ { "Ueckermuende 3", "UECK", 4, 4, 58, },
+ { "Schoenberg 5 <Ers.f.Repeat>", "SCHOEB", 4, 4, 65, },
+ { "Demmin 0", "DEMM", 4, 4, 66, },
+ { "Altenkirchen 7", "ALTK7", 4, 4, 99, },
+ { "Saarbruecken 2 <Winterberg>", "SBW", 4, 6, 1, },
+ { "Welschbillig 3", "WBIL3", 4, 6, 2, },
+ { "Hallschlag 3", "HASC3", 4, 6, 3, },
+ { "Marpingen 1 (Tholey)", "MAPI1", 4, 6, 4, },
+ { "Konz 5", "KONZ5", 4, 6, 5, },
+ { "Simmern 3", "SIMME3", 4, 6, 7, },
+ { "Saarlouis 0", "SLO0", 4, 6, 8, },
+ { "Saarbruecken 5 (OPD)", "SB5", 4, 6, 9, },
+ { "Perl 1", "PERL", 4, 6, 11, },
+ { "Gemuenden 3", "GMU3", 4, 6, 13, },
+ { "Pirmasens 2", "PIR2", 4, 6, 16, },
+ { "Konken 3", "KKN3", 4, 6, 17, },
+ { "Glan-Muenchweiler 3 (KL2)", "GMW4", 4, 6, 18, },
+ { "Reichenbach-Steegen 6", "RST6", 4, 6, 19, },
+ { "Landstuhl 14", "LST14", 4, 6, 20, },
+ { "Weilerbach 4 (KL2)", "WLB4", 4, 6, 21, },
+ { "Trier 1", "TR1", 4, 6, 22, },
+ { "Kell 1", "KLL1", 4, 6, 23, },
+ { "Blieskastel 2", "BLIES2", 4, 6, 24, },
+ { "Bernkastel-Kues 1", "BNK1", 4, 6, 25, },
+ { "Pruem 2", "PRM2", 4, 6, 26, },
+ { "Idar-Oberstein 1", "IDO1", 4, 6, 27, },
+ { "Bruchmuehlbach 4", "BMLB4", 4, 6, 28, },
+ { "Dellfeld 1", "DELL1", 4, 6, 30, },
+ { "Homburg 0", "HBG0", 4, 6, 31, },
+ { "Kastellaun 3", "KAST3", 4, 6, 32, },
+ { "Schoeneberg - Kuebelberg 0", "KUEB0", 4, 6, 33, },
+ { "St. Wendel 4", "STWL4", 4, 6, 34, },
+ { "Heusweiler 2", "HSW2", 4, 6, 35, },
+ { "Saarbruecken 1 (Klzsbr)", "SB1", 4, 6, 36, },
+ { "Neumagen-Dhron 7", "HETZ2", 4, 6, 37, },
+ { "Bitburg 0", "BTB0", 4, 6, 38, },
+ { "Wolfstein Pfalz 1 (KL2)", "WOS", 4, 6, 39, },
+ { "Saarburg 4", "SAA4", 4, 6, 40, },
+ { "Gerolstein 1", "GRST", 4, 6, 41, },
+ { "Kirn 7", "KIRN7", 4, 6, 44, },
+ { "Merzig 3", "MERZ3", 4, 6, 46, },
+ { "Lebach 3", "LEB3", 4, 6, 47, },
+ { "Sulzbach Saar 10", "SUL10", 4, 6, 48, },
+ { "Voelklingen 1", "VKL1", 4, 6, 49, },
+ { "Zweibruecken 2", "ZW", 4, 6, 50, },
+ { "Buedlich 2", "BUEDL2", 4, 6, 54, },
+ { "Klein-Blittersdorf 4", "BLIES", 4, 6, 56, },
+ { "Meisenheim 7", "MEIS7", 4, 6, 59, },
+ { "Hinterweidenthal 1", "HINT1", 4, 6, 60, },
+ { "Dillingen Wasserturm", "DILL", 4, 6, 61, },
+ { "Thaleischweiler 1", "THALE1", 4, 6, 62, },
+ { "Trulben 2", "TRUL2", 4, 6, 64, },
+ { "Kirchberg 1", "KIRB1", 4, 6, 78, },
+ { "Neunkirchen Saar 1", "NK", 4, 6, 79, },
+ { "Mettlach-Orscholz 1", "METTL1", 4, 6, 80, },
+ { "Abtsgmuend 41", "ABT41", 4, 7, 1, },
+ { "Bopfingen 41", "BOPF41", 4, 7, 2, },
+ { "Weikersheim 41", "WEIK41", 4, 7, 3, },
+ { "Heidenheim 2", "HDH2", 4, 7, 4, },
+ { "Lauterstein 1", "LAU1", 4, 7, 5, },
+ { "Niederstetten 41", "NDST41", 4, 7, 6, },
+ { "Schwaebisch Hall 71", "SHALL7", 4, 7, 7, },
+ { "Gaildorf 42", "GADF", 4, 7, 8, },
+ { "Mainhardt 1", "SKLZ01", 4, 7, 9, },
+ { "Schoental 41 (Widdern)", "SCHT41", 4, 7, 10, },
+ { "Schwaebisch Hall 0", "SHALL0", 4, 7, 11, },
+ { "Bad Mergentheim 2", "DZB2", 4, 7, 12, },
+ { "Forchtenberg 1", "HNKL20", 4, 7, 14, },
+ { "Oehringen-Ohrnberg 41", "HNKL02", 4, 7, 15, },
+ { "Bad Mergentheim 41", "MERG41", 4, 7, 16, },
+ { "Creglingen 41", "CREG41", 4, 7, 17, },
+ { "Braunsbach 2", "BBCH2", 4, 7, 18, },
+ { "Schopfloch 0", "SPFL0", 4, 7, 19, },
+ { "Kuenzelsau 41", "KSAU41", 4, 7, 20, },
+ { "Lonsee 41", "LONS41", 4, 7, 21, },
+ { "Laichingen 75", "LAI75", 4, 7, 22, },
+ { "Fichtenau 1", "FICH1", 4, 7, 24, },
+ { "Crailsheim 2", "KBG2", 4, 7, 25, },
+ { "Untergroeningen 1", "UGRN1", 4, 7, 26, },
+ { "Wiesensteig/Nato 1", "WIE1", 4, 7, 27, },
+ { "Geislingen 0", "GSLN41", 4, 7, 32, },
+ { "Riedlingen 2", "RIE2X", 4, 7, 33, },
+ { "Aichstetten 3", "AIST3", 4, 7, 37, },
+ { "Aalen 41", "AAL41", 4, 7, 38, },
+ { "Ellwangen 1", "ELLW", 4, 7, 40, },
+ { "Gerstetten 71", "GERS71", 4, 7, 41, },
+ { "Heubach 1", "HEU1", 4, 7, 45, },
+ { "Lonsee 1 (Scharenstetten)", "LONS1", 4, 7, 46, },
+ { "Neresheim 1", "NER1", 4, 7, 47, },
+ { "Lauchheim 1", "LCHM79", 4, 7, 48, },
+ { "Nersingen(DASA) 0.47", "NERS", 4, 7, 49, },
+ { "Schnelldorf 1", "SNDF1", 4, 7, 50, },
+ { "Aalen-Ebnat 41", "EBNT41", 4, 7, 51, },
+ { "Ulm 51 (Jungingen)", "ULKL27", 4, 7, 53, },
+ { "Laichingen 41", "ULKL03", 4, 7, 55, },
+ { "Aalen 42", "AAL42", 4, 7, 57, },
+ { "Herbrechtingen 41", "HERB41", 4, 7, 68, },
+ { "Ulm 1", "UL1", 4, 7, 70, },
+ { "Schoental 43 (Oberkessach)", "SCHT43", 4, 7, 71, },
+ { "Schelklingen 1", "ULKL06", 4, 7, 72, },
+ { "Deggingen 71", "ULKL07", 4, 7, 73, },
+ { "Ochsenhausen 1", "ULKL08", 4, 7, 74, },
+ { "Giengen 42", "GIEN42", 4, 7, 75, },
+ { "Ulm 2 (Rasth. Seligw.)", "ULKL09", 4, 7, 76, },
+ { "Ulm 126", "ULKL10", 4, 7, 77, },
+ { "Langenau 1", "ULKL01", 4, 7, 78, },
+ { "Oehringen 3", "HNKL06", 4, 7, 79, },
+ { "Blaustein 41", "ULKL12", 4, 7, 80, },
+ { "Ulm 151", "ULKL14", 4, 7, 82, },
+ { "Blaubeuren 41", "ULKL15", 4, 7, 83, },
+ { "Ulm 172 (Neu-Ulm)", "ULKL16", 4, 7, 84, },
+ { "Ulm 141", "ULKL17", 4, 7, 85, },
+ { "Erbach 41", "ULKL18", 4, 7, 86, },
+ { "Senden 0", "ULKL19", 4, 7, 87, },
+ { "Weissenhorn 0", "ULKL02", 4, 7, 88, },
+ { "Laupheim 0", "ULKL21", 4, 7, 90, },
+ { "Illertissen 0", "ULKL22", 4, 7, 91, },
+ { "Biberach 6", "ULKL23", 4, 7, 92, },
+ { "Ehingen 0", "EHI0", 4, 7, 93, },
+ { "Langenburg 1", "LGB1", 4, 7, 95, },
+ { "Dortmund 3 (Bake)", "DO3", 4, 2, 1, },
+ { "Altenberge 0", "ALTB0", 5, 2, 1, },
+ { "Lennestadt 1", "LENNE1", 5, 2, 2, },
+ { "Attendorn 7", "ATT7", 5, 2, 3, },
+ { "Arnsberg-Neheim-Huesten 7", "NHH7", 5, 2, 5, },
+ { "Muenster 42 <geneigt>", "MST42", 5, 2, 6, },
+ { "Marsberg-Westheim 1", "MARS1", 5, 2, 7, },
+ { "Lippstadt 0", "LIPP1", 5, 2, 8, },
+ { "Schalksmuehle 10 (Roelvede)", "HGND", 5, 2, 9, },
+ { "Meschede-Freienohl 7", "MEF", 5, 2, 10, },
+ { "Hallenberg 7", "HLBG7", 5, 2, 11, },
+ { "Soest 10 <Pauli Kaserne>", "SOEST", 5, 2, 12, },
+ { "Schalksmuehle 7", "SCHLK7", 5, 2, 13, },
+ { "Olsberg 7", "OLSB7", 5, 2, 14, },
+ { "Ostbevern 10", "OST", 5, 2, 15, },
+ { "Arnsberg 0", "ARNS0", 5, 2, 16, },
+ { "Beckum 3", "BECK3", 5, 2, 17, },
+ { "Sendenhorst 2", "SEN2", 5, 2, 18, },
+ { "Altena 8 <Ers.f.ALTN1>", "ALTN8", 5, 2, 19, },
+ { "Ahlen 0", "AHL0", 5, 2, 20, },
+ { "Luedinghausen 2", "LDH2", 5, 2, 21, },
+ { "Meschede 1", "ME1", 5, 2, 22, },
+ { "Werl 0", "WERL", 5, 2, 23, },
+ { "Moehnesee 5 <5:5:1>", "MOE5", 5, 2, 24, },
+ { "Schmallenberg-Boedefeld 1", "SBF1", 5, 2, 25, },
+ { "Winterberg 8", "HLB", 5, 2, 26, },
+ { "Castrop-Rauxel 3", "CRX3", 5, 2, 27, },
+ { "Muenster-Nienberge 0", "MSTN0", 5, 2, 28, },
+ { "Vreden 0", "VRDN0", 5, 2, 29, },
+ { "Luedenscheid 2", "LS2", 5, 2, 30, },
+ { "Gronau 0", "GRON0", 5, 2, 31, },
+ { "Meinerzhagen 7", "MZHG7", 5, 2, 32, },
+ { "Luenen 0", "LUEN0", 5, 2, 33, },
+ { "Plettenberg 10", "PLET10", 5, 2, 34, },
+ { "Werdohl 7", "WDHL7", 5, 2, 35, },
+ { "Nottuln 2 <20 Grad geneigt>", "NOTT2", 5, 2, 36, },
+ { "Telgte 0", "TELG0", 5, 2, 37, },
+ { "Ruethen 0", "RUET0", 5, 2, 38, },
+ { "Emsdetten 0", "EMS0", 5, 2, 39, },
+ { "Oelde 2 (Stromberg)", "OELST2", 5, 2, 40, },
+ { "Muenster-Albachten 0", "MST0", 5, 2, 41, },
+ { "Greven 0", "GRVN0", 5, 2, 43, },
+ { "Brechten 80", "BRE", 5, 2, 44, },
+ { "Schmallenberg-Dorlar 1", "DORL1", 5, 2, 45, },
+ { "Halver 6 (Rothenbruch)", "HALV", 5, 2, 46, },
+ { "Herscheid 3 (Gasmert)", "LSG", 5, 2, 47, },
+ { "Dortmund 230", "DO230", 5, 2, 49, },
+ { "Ascheberg 2", "ASCHB2", 5, 2, 50, },
+ { "Warendorf 0", "WAF0", 5, 2, 51, },
+ { "Gevelsberg 7", "GEV7", 5, 2, 52, },
+ { "Duelmen 0", "DUEL0", 5, 2, 54, },
+ { "Sundern 1", "SUND1", 5, 2, 55, },
+ { "Bueren 1", "BUER1", 5, 2, 56, },
+ { "Brilon-Messinghausen 1", "BRIM1", 5, 2, 57, },
+ { "Dortmund 10", "DO10", 5, 2, 58, },
+ { "Witten 91 (Gedern)", "WITTW", 5, 2, 59, },
+ { "Unna 3", "UN", 5, 2, 60, },
+ { "Hagen-Dahl 9 (Priorei)", "HGNDA9", 5, 2, 61, },
+ { "Haltern 7", "HAL7", 5, 2, 62, },
+ { "Herdecke 7", "HERD7", 5, 2, 63, },
+ { "Boenen 0", "BOE0", 5, 2, 64, },
+ { "Holzwickede 1", "HOLZW", 5, 2, 65, },
+ { "Hamm 1", "HAMM1", 5, 2, 66, },
+ { "Menden 11 (Lahrberg)", "MEN11", 5, 2, 67, },
+ { "Kamen 0", "KAM0", 5, 2, 68, },
+ { "Werne 0", "WERN0", 5, 2, 69, },
+ { "Waltrop 1", "WTRP", 5, 2, 70, },
+ { "Hamm 10 (Uentrop)", "HAMM", 5, 2, 71, },
+ { "Hagen 2", "HGN2", 5, 2, 72, },
+ { "Schwerte 4", "SWT4", 5, 2, 73, },
+ { "Recklinghausen 1", "RECK1", 5, 2, 74, },
+ { "Breckerfeld 6", "BRCK", 5, 2, 75, },
+ { "Balve 7", "BALV7", 5, 2, 76, },
+ { "Gevelsberg 5 (Silschede)", "GEVS", 5, 2, 77, },
+ { "Dortmund 85 (Eving)", "DO85", 5, 2, 78, },
+ { "Iserlohn 13 (Seilerberg)", "ISN13", 5, 2, 79, },
+ { "Datteln 3", "DAT3", 5, 2, 80, },
+ { "Haltern 2", "HAL2", 5, 2, 84, },
+ { "Hagen 9 (TVU Wetter)", "HGN9", 5, 2, 85, },
+ { "Witten 12", "WITT12", 5, 2, 87, },
+ { "Herscheid 1", "HED1", 5, 2, 94, },
+ { "Marl 0", "MARL0", 5, 2, 96, },
+ { "Klettbach 1", "HAYN", 5, 3, 1, },
+ { "Grossfahner 1", "BIEN", 5, 3, 2, },
+ { "Zella-Mehlis 1", "ZEME", 5, 3, 3, },
+ { "Juechsen 1", "WNBRN", 5, 3, 4, },
+ { "Grossbreitenbach 7", "GBB", 5, 3, 5, },
+ { "Eisenberg 6 (Serba)", "ESBG6", 5, 3, 6, },
+ { "Schleusingen 4", "SLSN", 5, 3, 7, },
+ { "Eisenberg 4", "ESBG", 5, 3, 8, },
+ { "Gera 11 (Roschuetz)", "GRO", 5, 3, 9, },
+ { "Muenchenbernsdorf1(H.Reuth)", "HRTH", 5, 3, 10, },
+ { "Jena 5", "LDGF", 5, 3, 11, },
+ { "Neustadt 3 (Kleina)", "KLA", 5, 3, 12, },
+ { "Saalburg 2", "KLM", 5, 3, 13, },
+ { "Jena 6", "OSSM", 5, 3, 14, },
+ { "Ruhla 4", "RUHL", 5, 3, 15, },
+ { "Creuzburg 2 (Neuenhof)", "NEUF", 5, 3, 16, },
+ { "Nordhausen 1", "NDHN", 5, 3, 17, },
+ { "Camburg 2", "CAB", 5, 3, 18, },
+ { "Bad Frankenhausen 3", "BFRH", 5, 3, 19, },
+ { "Gera 13", "GERA13", 5, 3, 20, },
+ { "Sondershausen 5", "SOND", 5, 3, 21, },
+ { "Hermsdorf 1", "HDF1", 5, 3, 22, },
+ { "Weimar 14", "WEIM", 5, 3, 23, },
+ { "Erfurt 20(Schwerborner STR.)", "EKLZ08", 5, 3, 24, },
+ { "Arnsgereuth 1", "ARRTH", 5, 3, 25, },
+ { "Arnstadt 8", "ARNA", 5, 3, 26, },
+ { "Suhl 2", "SUHL", 5, 3, 27, },
+ { "Bad Koesen 1000", "KOES", 5, 3, 29, },
+ { "Hildburghausen 11", "HILHSN", 5, 3, 30, },
+ { "Ilmenau 4", "ILME", 5, 3, 31, },
+ { "Erfurt 13 (Flughafen alt)", "EKLZ07", 5, 3, 32, },
+ { "Erfurt 7 (Fuchsgrund)", "EKLZ03", 5, 3, 33, },
+ { "Erfurt 4 (Andreasstr.)", "EKLZ02", 5, 3, 34, },
+ { "Erfurt 3 (Chamissostr.)", "EKLZ01", 5, 3, 35, },
+ { "Neuhaus 0", "NEURE", 5, 3, 36, },
+ { "Meiningen 5", "MEIN", 5, 3, 37, },
+ { "Erfurt 17 (FZA)", "EKLZ05", 5, 3, 38, },
+ { "Erfurt 8 (EVST 4)", "EKLZ04", 5, 3, 39, },
+ { "Muehlhausen 7 (Eigenrieden)", "EGRD", 5, 3, 40, },
+ { "Blankenhain 1", "BLHA1", 5, 3, 41, },
+ { "Schmalkalden 6", "SMAL", 5, 3, 42, },
+ { "Heuthen 1 (Hockelrein)", "HOCKE", 5, 3, 43, },
+ { "Kaltennordheim 2", "KLFE", 5, 3, 44, },
+ { "Berga 1", "BERG", 5, 3, 45, },
+ { "Oberhof 2", "OBHF", 5, 3, 46, },
+ { "Poessneck 5", "PSNK", 5, 3, 47, },
+ { "Apolda 2", "APOL", 5, 3, 48, },
+ { "Bad Langensalza 4", "BSALZ", 5, 3, 49, },
+ { "Soemmerda 0", "SOEM", 5, 3, 50, },
+ { "Triebes 2", "ZLRD", 5, 3, 51, },
+ { "Lobenstein 4", "LOBS", 5, 3, 52, },
+ { "Rudolstadt 4", "RDST", 5, 3, 53, },
+ { "Schleiz 2", "SLZ", 5, 3, 54, },
+ { "Stadtroda 1", "STRDA1", 5, 3, 55, },
+ { "Wernshausen 3 (Pless)", "PLS", 5, 3, 56, },
+ { "Steinbach-Hallenberg 2", "STBH", 5, 3, 58, },
+ { "Geisa 4", "GEISA", 5, 3, 59, },
+ { "Bleicherode7 (Gebraer Kopf)", "SOLL", 5, 3, 60, },
+ { "Inselsberg", "INSEL", 5, 3, 61, },
+ { "Steinach 3 (Fellberg)", "FELL", 5, 3, 62, },
+ { "Stadtilm 4", "STADTI", 5, 3, 63, },
+ { "Waltershausen 4", "WALT4", 5, 3, 65, },
+ { "Gotha 6", "GTHA6", 5, 3, 66, },
+ { "Eisenach 11", "ESNA11", 5, 3, 67, },
+ { "Kahla 1", "KAHLA2", 5, 3, 68, },
+ { "Heiligenstadt 4", "HLGS4", 5, 3, 69, },
+ { "Thimmendorf 1", "THIM1", 5, 3, 70, },
+ { "Buttelstedt 3", "BUTT3", 5, 3, 71, },
+ { "Koenigsee 2", "KNGS2", 5, 3, 72, },
+ { "Erfurt 30", "EKLZ30", 5, 3, 73, },
+ { "Schoenbrunn 7", "SHBN7", 5, 3, 74, },
+ { "Kindelbrueck (TVU)", "KIND", 5, 3, 75, },
+ { "Schlotheim 3", "SCHLT", 5, 3, 79, },
+ { "Bischofsheim 2", "BIH2", 5, 3, 91, },
+ { "Ludwigsstadt 1", "LUDW1", 5, 3, 92, },
+ { "Ostheim 1", "UNSL1", 5, 3, 93, },
+ { "Frechen 0", "FCHN0", 6, 2, 1, },
+ { "Koeln 35 (Messe)", "K35", 6, 2, 2, },
+ { "Bergisch Gladbach 4", "BGLB99", 6, 2, 3, },
+ { "Niederkassel 0", "NKS0", 6, 2, 4, },
+ { "Koeln 0", "K0", 6, 2, 5, },
+ { "Koeln 8 <Bake>", "K8", 6, 2, 6, },
+ { "Bonn 460", "BN460", 6, 2, 7, },
+ { "Koeln 27", "K27", 6, 2, 8, },
+ { "Bornheim-Merten 1", "MTN1", 6, 2, 9, },
+ { "Frechen 8 <4.3 W ERP>", "FCHN3", 6, 2, 10, },
+ { "Kerpen-Horrem 2", "KERP51", 6, 2, 11, },
+ { "Erftstadt 50", "ERF50", 6, 2, 12, },
+ { "Koeln 34", "K34", 6, 2, 13, },
+ { "Pulheim 0", "PLH0", 6, 2, 14, },
+ { "Koeln-Porz 50", "PRZ50", 6, 2, 15, },
+ { "Bergheim 2", "BGH2", 6, 2, 16, },
+ { "Koeln 860", "HMR", 6, 2, 17, },
+ { "Koenigswinter-Oberpleis 1", "KWT1", 6, 2, 18, },
+ { "Siegburg 70", "TROI70", 6, 2, 19, },
+ { "Bergisch Gladbach 2", "BGLB2", 6, 2, 21, },
+ { "Koeln 170", "K17", 6, 2, 22, },
+ { "Koeln 25", "K25", 6, 2, 23, },
+ { "Koeln 370", "K37", 6, 2, 24, },
+ { "Koeln 430", "K43", 6, 2, 25, },
+ { "Koeln 760", "K76", 6, 2, 26, },
+ { "Koeln 640", "K640", 6, 2, 27, },
+ { "Koeln 28", "K850", 6, 2, 28, },
+ { "Bruehl 99", "BRHL99", 6, 2, 29, },
+ { "Kerpen 3", "VILLE", 6, 2, 30, },
+ { "Koeln 350.8001", "K350", 6, 2, 31, },
+ { "Bonn 0", "BN0", 6, 2, 33, },
+ { "Bonn 320", "BN320", 6, 2, 34, },
+ { "Bonn 620", "BN620", 6, 2, 35, },
+ { "Bonn 670", "BN670", 6, 2, 36, },
+ { "Siegburg 41", "SIGB41", 6, 2, 37, },
+ { "Siegburg 20", "SIGB20", 6, 2, 38, },
+ { "Lohmar 2", "LOH99", 6, 2, 39, },
+ { "Siegburg 0", "SIGB0", 6, 2, 40, },
+ { "Lohmar 1 <Mischbake>", "LOH1", 6, 2, 41, },
+ { "Bonn 13 (BMPT)", "BN13", 6, 2, 42, },
+ { "Dueren 30", "DUER30", 6, 2, 43, },
+ { "Heimbach 2", "HEIM2", 6, 2, 44, },
+ { "Huertgenwald 4 <Mischbake>", "HGW4", 6, 2, 45, },
+ { "Kerpen-Buir 1", "BUIR", 6, 2, 46, },
+ { "Monschau 1", "MONS1", 6, 2, 47, },
+ { "Hennef 1", "HNNF1", 6, 2, 48, },
+ { "Nideggen 4", "NGG4", 6, 2, 49, },
+ { "Zuelpich 1", "ZUEL", 6, 2, 50, },
+ { "Rheinbach 2", "RHBH", 6, 2, 51, },
+ { "Euskirchen 4", "EUSK4", 6, 2, 52, },
+ { "Weilerswist 0", "WLW0", 6, 2, 53, },
+ { "Bad Muenstereifel 2", "BMST", 6, 2, 54, },
+ { "Mechernich 4", "MECH2", 6, 2, 55, },
+ { "Schleiden 1", "SLDN1", 6, 2, 56, },
+ { "Koenigswinter-Oberpleis 0", "KWT", 6, 2, 57, },
+ { "Noervenich 1", "NOER", 6, 2, 58, },
+ { "Dormagen 7.80B1", "DOR7", 6, 2, 60, },
+ { "Simmerath 3", "SIMM3", 6, 2, 61, },
+ { "Nettersheim 4", "NETSH4", 6, 2, 62, },
+ { "Schleiden-Gemuend 3", "RURB", 6, 2, 63, },
+ { "Wermelskirchen 0", "WEKI0", 6, 2, 64, },
+ { "Burscheid 3", "BUR3", 6, 2, 65, },
+ { "Wesseling 0", "WESS0", 6, 2, 66, },
+ { "Huerth 0", "HRT0", 6, 2, 67, },
+ { "Roesrath 2", "RRT", 6, 2, 68, },
+ { "Burscheid 10", "BUR10", 6, 2, 69, },
+ { "Koeln 23", "K23", 6, 2, 70, },
+ { "Leverkusen-Opladen 1", "LEVOP1", 6, 2, 71, },
+ { "Bonn 2", "BN2", 6, 2, 72, },
+ { "Rommerskirchen 0", "ROMM0", 6, 2, 73, },
+ { "Bonn 630", "BN630", 6, 2, 76, },
+ { "Bensberg 60", "BNBG60", 6, 2, 78, },
+ { "Leverkusen 0", "LEV0", 6, 2, 91, },
+ { "Magdeburg 25 (Sudenburg)", "MDB25", 6, 3, 1, },
+ { "Magdeburg 22 (Cracau)", "MDB22", 6, 3, 2, },
+ { "Magdeburg 24 (Neust. See)", "MDB24", 6, 3, 3, },
+ { "Biederitz 1", "BIED1", 6, 3, 4, },
+ { "Magdeburg 7 (Olvenstaedt)", "MDB7", 6, 3, 5, },
+ { "Magdeburg 23 (Buckau)", "MDB23", 6, 3, 6, },
+ { "Moeser 1", "MOESE1", 6, 3, 7, },
+ { "Magdeburg 1", "MDB0", 6, 3, 8, },
+ { "Magdeburg 10 (Schoenebeck)", "TRANS6", 6, 3, 9, },
+ { "Leitzkau 1", "LEIT1", 6, 3, 10, },
+ { "Stendal 2", "STD2", 6, 3, 11, },
+ { "Haldensleben 4 (end)", "HLDL", 6, 3, 12, },
+ { "Oschersleben 0", "OSCH0", 6, 3, 13, },
+ { "Wernigerode 0", "WIGR0", 6, 3, 14, },
+ { "Halberstadt 2", "HBST", 6, 3, 15, },
+ { "Erxleben ueb. Hldln. 1", "ERX1", 6, 3, 16, },
+ { "Altengrabow 1", "ALGR1", 6, 3, 17, },
+ { "Genthin 0", "GENT0", 6, 3, 18, },
+ { "Burg 0", "BURG0", 6, 3, 19, },
+ { "Lindau-Anhalt 1", "DEE", 6, 3, 20, },
+ { "Kamern 2", "KAME", 6, 3, 21, },
+ { "Niederndodeleben 1", "TRANS1", 6, 3, 22, },
+ { "Egeln 0", "EGELN0", 6, 3, 23, },
+ { "Burg 5", "TRANS2", 6, 3, 24, },
+ { "Fleetmark 1", "LUEG", 6, 3, 25, },
+ { "Dolle 1", "DLL", 6, 3, 26, },
+ { "Osterburg 3", "OTBG3", 6, 3, 27, },
+ { "Frose 3 (Hoym)", "HOYM", 6, 3, 28, },
+ { "Harzgerode 0", "HGR", 6, 3, 29, },
+ { "Koennern 3", "KOENE3", 6, 3, 30, },
+ { "Elbingerode 0.97B1", "ELBRD", 6, 3, 31, },
+ { "Wanzleben 2", "WANZ2", 6, 3, 32, },
+ { "Morsleben", "MORS", 6, 3, 33, },
+ { "Tangermuende 0.97B1", "JERI0", 6, 3, 34, },
+ { "Bernburg 7", "BBG", 6, 3, 35, },
+ { "Salzwedel 8", "SALZ8", 6, 3, 36, },
+ { "Zerbst 4", "ZERBST", 6, 3, 39, },
+ { "Aschersleben 5 End", "ASCHS0", 6, 3, 48, },
+ { "Tangerhuette 0", "TANGER", 6, 3, 49, },
+ { "Kloetze", "KLOETZ", 6, 3, 52, },
+ { "Mieste 0", "MIEST0", 6, 3, 55, },
+ { "Thale", "THAL", 6, 3, 88, },
+ { "Seehausen 0", "SEE0", 6, 3, 93, },
+ { "Blankenburg 0", "BLABG", 6, 3, 95, },
+ { "Gardelegen 0", "GDLG", 6, 3, 96, },
+ { "Gernrode 3 (end)", "GERN1", 6, 3, 97, },
+ { "Hasselfelde 0", "HASS", 6, 3, 98, },
+ { "Overath 5", "OVRT5", 7, 2, 1, },
+ { "Dierdorf 10", "DIER2", 7, 2, 2, },
+ { "Daun 4", "DAU4", 7, 2, 4, },
+ { "Much 1", "MUCH", 7, 2, 6, },
+ { "Saffig 10", "SAFF10", 7, 2, 7, },
+ { "Gummersbach 40", "GU40", 7, 2, 8, },
+ { "Asbach 10 <f. HNNF6>", "ASB10", 7, 2, 9, },
+ { "Eitorf 2", "EIT2", 7, 2, 10, },
+ { "Windhagen 10", "WINH10", 7, 2, 11, },
+ { "Bad Honnef 80", "BHF80", 7, 2, 12, },
+ { "Nuembrecht 10", "NUEM10", 7, 2, 13, },
+ { "Koblenz 10 <Mischbake>", "KO10", 7, 2, 14, },
+ { "Hoehr-Grenzhausen 1 <Misch>", "HGH1", 7, 2, 15, },
+ { "Montabaur 3", "MT3", 7, 2, 16, },
+ { "Weibern 2 <Mischbake>", "WBN2", 7, 2, 18, },
+ { "Bad Marienberg 1 <Mischba.>", "BMA1", 7, 2, 19, },
+ { "Bad Bertrich 1", "BER1", 7, 2, 20, },
+ { "Blankenheim-Ahr 5", "BHM5", 7, 2, 21, },
+ { "Wissen 2", "WISS2", 7, 2, 22, },
+ { "Betzdorf 4", "BZD4", 7, 2, 23, },
+ { "Wenden 186", "WEDN89", 7, 2, 26, },
+ { "Puderbach 3", "PUDB3", 7, 2, 28, },
+ { "Kuerten-Duerscheid 3", "KUERT3", 7, 2, 30, },
+ { "Bad Honnef 0", "BHF1", 7, 2, 31, },
+ { "Wipperfuerth 2", "WIPP2", 7, 2, 33, },
+ { "Kuerten 1", "KUERT1", 7, 2, 34, },
+ { "Gummersbach 0", "GU0", 7, 2, 35, },
+ { "Windeck 2", "WIND1", 7, 2, 37, },
+ { "Bad Neuenahr-Ahrweiler 4", "BNA4", 7, 2, 38, },
+ { "Linz 4 <Mischbake>", "LNZ", 7, 2, 39, },
+ { "Kreuztal 1 <Mischbake>", "KRZT1", 7, 2, 41, },
+ { "Bad Berleburg 1", "BBERL1", 7, 2, 43, },
+ { "Bad Laasphe 7", "LPHE7", 7, 2, 44, },
+ { "Netphen 7", "NETP7", 7, 2, 45, },
+ { "Olpe 0", "OE0", 7, 2, 47, },
+ { "Drolshagen-Bleche 1", "SCHK", 7, 2, 48, },
+ { "Hilchenbach 1", "LUZL", 7, 2, 49, },
+ { "Freudenberg 7", "FDB7", 7, 2, 50, },
+ { "Burbach 3", "BURB", 7, 2, 51, },
+ { "Waldbreitbach 2", "WBB2", 7, 2, 52, },
+ { "Ellenz-Poltersdorf 2", "ELLZ2", 7, 2, 53, },
+ { "Insul 2", "INSU2", 7, 2, 54, },
+ { "Linz 2", "LNZ2", 7, 2, 55, },
+ { "Wildbergerhuette 1", "SKHL", 7, 2, 56, },
+ { "Kelberg 3 (Hochkelberg)", "HKBG", 7, 2, 57, },
+ { "Kesseling 1", "KESS1", 7, 2, 58, },
+ { "Reichshof-Eckenhagen 3", "WEHN", 7, 2, 59, },
+ { "Rengsdorf 4", "WILR", 7, 2, 60, },
+ { "Mendig 3", "MEND", 7, 2, 61, },
+ { "Cochem 1", "COC1", 7, 2, 62, },
+ { "Mayen 3", "MAY3", 7, 2, 63, },
+ { "Neuwied 2", "NEUW0", 7, 2, 64, },
+ { "Hachenburg 2", "HACH2", 7, 2, 65, },
+ { "Westerburg 1", "WESB1", 7, 2, 66, },
+ { "Asbach 5", "ASB5", 7, 2, 67, },
+ { "Loef 1", "LOEF1", 7, 2, 68, },
+ { "Engelskirchen 6", "ENGK6", 7, 2, 69, },
+ { "Altenkirchen 0", "ATK0", 7, 2, 70, },
+ { "Siegen 15", "SG99", 7, 2, 71, },
+ { "Neunkirchen-Seelscheid 1", "NNK1", 7, 2, 73, },
+ { "Ochtendung 2", "OCHT99", 7, 2, 74, },
+ { "Bad Ems 1", "BEMS1", 7, 2, 79, },
+ { "Marienheide 1", "MARI1", 7, 2, 80, },
+ { "Gummersbach 16 <Mischbake>", "GU16", 7, 2, 82, },
+ { "Flammersfeld 2", "FLF2", 7, 2, 83, },
+ { "Waldbroel 1", "WDBR1", 7, 2, 84, },
+ { "Bendorf 1", "BEN1", 7, 2, 85, },
+ { "Engelskirchen 3", "ENGK", 7, 2, 86, },
+ { "Selters 2", "SELT2", 7, 2, 87, },
+ { "Adenau 7 (Nuerburgring)", "ADN7", 7, 2, 88, },
+ { "Kaisersesch 2", "KESCH2", 7, 2, 89, },
+ { "Nassau 1", "NAS1", 7, 2, 90, },
+ { "Bad Marienberg 2", "BMA2", 7, 2, 91, },
+ { "Antweiler 1", "ANT1", 7, 2, 92, },
+ { "Ruppichteroth 3", "BKRT", 7, 2, 93, },
+ { "Lindlar 1", "LINL", 7, 2, 95, },
+ { "Siegen 1 <Mischbake>", "SG1", 7, 2, 96, },
+ { "Gummersbach 13 <Mischbake>", "GU13", 7, 2, 97, },
+ { "Rheinbrohl 0", "RHBL0", 7, 2, 99, },
+ { "Baerenstein 1", "BAER2", 7, 3, 1, },
+ { "Auerbach 4 (Schnarrtanne)", "SNTN", 7, 3, 2, },
+ { "Bad Elster 1 (Reuth)", "REUTH", 7, 3, 3, },
+ { "Marienberg 0", "MBG", 7, 3, 4, },
+ { "Chemnitz 11 (Totenstein)", "TOT", 7, 3, 5, },
+ { "Reichenbach 3", "KUH", 7, 3, 6, },
+ { "Bergen 1 (Werda)", "WDA", 7, 3, 7, },
+ { "Rochlitz 5", "ROCH", 7, 3, 8, },
+ { "Chemnitz 12 (Reichenhain)", "REIHN", 7, 3, 9, },
+ { "Frankenberg 4", "FRKN", 7, 3, 10, },
+ { "Ebersbrunn 1", "ZWW", 7, 3, 11, },
+ { "Schwarzenberg 7", "BNBC", 7, 3, 12, },
+ { "Freiberg 2", "FBG", 7, 3, 13, },
+ { "Frauenstein 3", "FRAU", 7, 3, 14, },
+ { "Glauchau 2", "GLAU", 7, 3, 15, },
+ { "Plauen 10", "KEMM", 7, 3, 16, },
+ { "Werdau 4 (Niederalbertsd.)", "NDAD", 7, 3, 17, },
+ { "Mittweida 1", "MITT1", 7, 3, 18, },
+ { "Zschopau 4 (Hohndorf)", "HDRF", 7, 3, 19, },
+ { "Chemnitz 32 (BKH-Bettenh.)", "CZ01", 7, 3, 20, },
+ { "Chemnitz 29 (Heckert)", "CZ02", 7, 3, 21, },
+ { "Chemnitz 17 (Landratsamt)", "CZ08", 7, 3, 22, },
+ { "Nossen 5", "NOSS5", 7, 3, 23, },
+ { "Chemnitz 22 (Leukersdorf)", "CZ05", 7, 3, 24, },
+ { "Chemnitz 33 (Numerik)", "CZ06", 7, 3, 25, },
+ { "Hainichen 1 (end)", "HAIN1", 7, 3, 26, },
+ { "Zwoenitz 4", "ZWO3", 7, 3, 27, },
+ { "Zwickau 1", "ZWWI", 7, 3, 28, },
+ { "Chemnitz 28 (Funkfeuer)", "CZ09", 7, 3, 29, },
+ { "Floeha 4 (TVU Steinberg)", "STEIN", 7, 3, 30, },
+ { "Crimmitzschau 2", "CRIMMI", 7, 3, 31, },
+ { "Eibenstock 4", "EIBEN", 7, 3, 32, },
+ { "Chemnitz 1010 (Autobahnamt)", "CZ10", 7, 3, 33, },
+ { "Olbernhau 3", "LUGA", 7, 3, 35, },
+ { "Hartenstein 1000", "HART1", 7, 3, 36, },
+ { "Greitz 2", "GRZ2", 7, 3, 37, },
+ { "Penig 2", "PEN2", 7, 3, 38, },
+ { "Thalheim", "THALH", 7, 3, 39, },
+ { "FTZ Example", "FTZ", 1, 1, 38, }, /* use in FTZ standard as example */
+ { "", "", 0, 0, 0, },
};
void init_station(void)
{
- int i, j;
-
- for (i = 0; cnetz_stations[i].standort[0]; i++) {
- for (j = 0; cnetz_stations[i].standort[j]; j++) {
- if (cnetz_stations[i].standort[j] == ' ')
- cnetz_stations[i].standort[j] = '_';
- }
- }
}
void station_list(void)
{
int i;
- char name[17];
+ char name[33];
printf("List of all base stations:\n\n");
- printf("Name Nat FuVst Rest Year used\n");
- printf("-------------------------------------------------\n");
- for (i = 0; cnetz_stations[i].standort[0]; i++) {
+ printf("Kurz Name Nat FuVst Rest\n");
+ printf("------------------------------------------------------------\n");
+ for (i = 0; cnetz_stations[i].long_name[0]; i++) {
memset(name, ' ', sizeof(name));
+ memcpy(name, cnetz_stations[i].name, strlen(cnetz_stations[i].name));
+ name[8] = '\0';
+ printf("%s", name);
+ memset(name, ' ', sizeof(name));
+ memcpy(name, cnetz_stations[i].long_name, strlen(cnetz_stations[i].long_name));
name[sizeof(name) - 1] = '\0';
- memcpy(name, cnetz_stations[i].standort, strlen(cnetz_stations[i].standort));
- printf("%s%d\t%d\t%d\t", name, cnetz_stations[i].nat, cnetz_stations[i].fuvst, cnetz_stations[i].rest);
- if (cnetz_stations[i].in1991)
- printf("1991");
- if (cnetz_stations[i].in1991 && cnetz_stations[i].in1999)
- printf(",");
- if (cnetz_stations[i].in1999)
- printf("1999");
- printf("\n");
+ printf("%s%d\t%d\t%d\n", name, cnetz_stations[i].nat, cnetz_stations[i].fuvst, cnetz_stations[i].rest);
}
}
-const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest)
+const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest, const char **long_name)
{
int i;
- for (i = 0; cnetz_stations[i].standort[0]; i++) {
+ for (i = 0; cnetz_stations[i].long_name[0]; i++) {
if (cnetz_stations[i].nat == nat
&& cnetz_stations[i].fuvst == fuvst
- && cnetz_stations[i].rest == rest)
- return cnetz_stations[i].standort;
+ && cnetz_stations[i].rest == rest) {
+ if (long_name)
+ *long_name = cnetz_stations[i].long_name;
+ return cnetz_stations[i].name;
+ }
}
- return "unknown";
+ if (long_name)
+ *long_name = "unknown";
+ return *long_name;
}
const char *get_station_id(const char *name, uint8_t *nat, uint8_t *fuvst, uint8_t *rest)
{
int i, found = -1;
- for (i = 0; cnetz_stations[i].standort[0]; i++) {
+ for (i = 0; cnetz_stations[i].name[0]; i++) {
/* check for given prefix */
- if (!strncasecmp(cnetz_stations[i].standort, name, strlen(name))) {
+ if (!strncasecmp(cnetz_stations[i].name, name, strlen(name))
+ || !strncasecmp(cnetz_stations[i].long_name, name, strlen(name)) ) {
/* found twice */
if (found >= 0)
return "Given station name is ambiguous, use more letters! Use '-S fuz-name=list' to get a list of all stations.";
/* found the first time */
found = i;
/* check for exact match, so we are done */
- if (strlen(cnetz_stations[i].standort) == strlen(name))
+ if (strlen(cnetz_stations[i].name) == strlen(name))
break;
}
}
diff --git a/src/cnetz/stations.h b/src/cnetz/stations.h
index 415ab35..981713e 100644
--- a/src/cnetz/stations.h
+++ b/src/cnetz/stations.h
@@ -1,6 +1,6 @@
void init_station(void);
void station_list(void);
-const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest);
+const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest, const char **standort);
const char *get_station_id(const char *name, uint8_t *nat, uint8_t *fuvst, uint8_t *rest);
diff --git a/src/cnetz/sysinfo.c b/src/cnetz/sysinfo.c
index 0c0802d..43a73ef 100644
--- a/src/cnetz/sysinfo.c
+++ b/src/cnetz/sysinfo.c
@@ -4,10 +4,13 @@
cnetz_si si;
-void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen)
+void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe)
{
memset(&si, 0, sizeof(si));
+ /* timeslot to use */
+ si.timeslots = timeslots;
+
/* ID of base station */
si.fuz_nat = fuz_nat;
si.fuz_fuvst = fuz_fuvst;
@@ -34,7 +37,10 @@ void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t
/* a low value is tollerant to bad quality */
si.grenz_einbuchen = grenz_einbuchen; /* 1..7 */
+ if (bahn_bs)
+ kennung_fufst = 0;
si.kennung_fufst = kennung_fufst;
+ si.bahn_bs = bahn_bs;
si.authentifikationsbit = authentifikationsbit;
@@ -49,5 +55,8 @@ void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t
/* deny group of subscribers. (used to balance subscribers between base stations) */
si.teilnehmergruppensperre = teilnehmergruppensperre;
si.anzahl_gesperrter_teilnehmergruppen = anzahl_gesperrter_teilnehmergruppen;
+
+ si.meldeinterval = meldeinterval;
+ si.meldeaufrufe = meldeaufrufe;
}
diff --git a/src/cnetz/sysinfo.h b/src/cnetz/sysinfo.h
index 3e94042..d8c8be1 100644
--- a/src/cnetz/sysinfo.h
+++ b/src/cnetz/sysinfo.h
@@ -1,5 +1,6 @@
typedef struct system_information {
+ uint32_t timeslots; /* timeslot map to use */
uint8_t fuz_nat; /* national network ID */
uint8_t fuz_fuvst; /* id of switching center */
uint8_t fuz_rest; /* rest of base station id */
@@ -12,6 +13,7 @@ typedef struct system_information {
uint8_t entfernung;
uint8_t grenz_einbuchen;
uint8_t kennung_fufst; /* prio of base station */
+ uint8_t bahn_bs; /* special train base station */
uint8_t authentifikationsbit; /* base station suppoerts authentication */
uint8_t ws_kennung; /* queue setting sof base station */
uint8_t nachbar_prio;
@@ -19,9 +21,11 @@ typedef struct system_information {
uint8_t reduzierung;
int8_t teilnehmergruppensperre;
int8_t anzahl_gesperrter_teilnehmergruppen;
+ int meldeinterval; /* when to retry availability check */
+ int meldeaufrufe; /* 0 for infinite */
} cnetz_si;
extern cnetz_si si;
-void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen);
+void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe);
diff --git a/src/cnetz/telegramm.c b/src/cnetz/telegramm.c
index 1a21369..0525f8a 100644
--- a/src/cnetz/telegramm.c
+++ b/src/cnetz/telegramm.c
@@ -27,7 +27,7 @@
#include <errno.h>
#include <math.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "cnetz.h"
#include "dsp.h"
#include "sysinfo.h"
@@ -46,7 +46,7 @@ static const char *param_ja[] = {
static const char *param_betriebsart[] = {
"Sprache klar",
"Sprache invertiert",
- "Illegaler Parameter 2",
+ "Datenbetrieb",
"Illegaler Parameter 3",
};
@@ -260,7 +260,7 @@ static struct definition_parameter {
{ 'H',"OgK-Vorschlag", 10, param_frequenz },
{ 'I',"FuZ-Nationalitaet", 3, NULL },
{ 'J',"Sendeleistungsanpassung", 1, param_anpassen },
- { 'K',"Frequenz-Nr.", 11, param_frequenz },
+ { 'K',"Frequenz-Nr.", 0, param_frequenz }, /* length 10 or 11 */
{ 'L',"Art der Signalisierung im OgK", 1, param_signalisierung },
{ 'M',"OgK-Verkehrsanteil", 5, param_verkehrsanteil },
{ 'N',"FuTln-Nationalitaet", 3, NULL },
@@ -274,6 +274,7 @@ static struct definition_parameter {
{ 'V',"Sicherungs-Code", 16, NULL },
{ 'W',"WS-Kennung", 2, param_wskennung },
{ 'X',"Wahlziffer beliebig 16 Ziffern", 64, NULL },
+ { 'Y',"Bahn-MS", 1, param_ja },
{ 'Z',"Zeitschlitz-Nr.", 5, NULL },
{ 'a',"Grenzert fuer Ausloesen", 4, param_ausloesen },
{ 'b',"Chipkarten-FuTelG-Bit", 1, param_chipkarte },
@@ -298,6 +299,7 @@ static struct definition_parameter {
{ 'u',"Grenzwert fuer Umschalten", 4, param_ausloesen },
{ 'v',"Vermittlungtechnische Sperren", 2, param_sperren },
{ 'w',"Erweitertes Frequenzbandbit", 1, NULL },
+ { 'x',"Bahn-BS", 1, param_ja },
{ 'y',"Reduzierungsfaktor", 2, param_reduzierung },
{ '_',"Illegaler Opcode", 64, NULL },
{ 0 ,"", 0, NULL },
@@ -347,12 +349,12 @@ static struct definition_opcode {
{ "------dJ--------eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "VH(K)", BLOCK_K,"Verbindung halten" },
{ "------dJ--------eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "RTAQ(K)", BLOCK_K,"Quittung Rufton anschalten" },
{ "------dJBB------eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "AH(K)", BLOCK_K,"Abhebe-Signal" },
- { "-----wdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "VH(V)", BLOCK_V,"Verbindung halten" },
+ { "----YwdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "VH(V)", BLOCK_V,"Verbindung halten" },
{ "------dJ----------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "AT(K)", BLOCK_K,"Ausloesen durch Funktelefonteilnehmer" },
{ "------dJBBC-------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "AT(V)", BLOCK_V,"Ausloesen durch Funktelefonteilnehmer" },
{ "------dJBB------eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "DSQ(K)", BLOCK_K,"Durchschalten Quittung" },
- { "-----wdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USAI(V)", BLOCK_V,"Umschaltantrag intern" },
- { "-----wdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USAE(V)", BLOCK_V,"Umschaltantrag extern" },
+ { "----YwdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USAI(V)", BLOCK_V,"Umschaltantrag intern" },
+ { "----YwdJBBCt----eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USAE(V)", BLOCK_V,"Umschaltantrag extern" },
{ "------dJBB--------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USTLN(K)", BLOCK_K,"Umschalten Funktelefonteilnehmer" },
{ "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", NULL, "ZFZQ(K)", BLOCK_K,"Zufallszahlquittung" },
{ "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", NULL, "AP(K)", BLOCK_K,"Autorisierungsparameter" },
@@ -366,7 +368,7 @@ static struct definition_opcode {
{ "PPdZZZZZ----------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "UBQ(R)", BLOCK_R,"Umbuchquittung" },
{ "PPdZZZZZ----------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "WSK(R)", BLOCK_R,"Warteschglange kommend" },
{ "PP-MMMMMDDDDEEEE------HHHHHHHHHHFFFFFFFF------------------------", NULL, "MLR(M)", BLOCK_M,"Melde-Leer-Ruf" },
- { "PPdZZZZZffflvvWW------yyIIIAAAAAFFFFFFFFkkgprrrrmmmmnnnnuuuuaaaa", NULL, "LR(R)", BLOCK_R,"Leer-Ruf" },
+ { "PPdZZZZZffflvvWW-----xyyIIIAAAAAFFFFFFFFkkgprrrrmmmmnnnnuuuuaaaa", NULL, "LR(R)", BLOCK_R,"Leer-Ruf" },
{ "PPdZZZZZ----------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "ATQ(R)", BLOCK_R,"Quittung fuer Ausloesen des FuTelG im OgK-Betrieb" },
{ "PPdZZZZZ----------------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "SAR(R)", BLOCK_R,"Sperraufruf" },
{ "PP-MMMMMDDDDEEEE------HHHHHHHHHHFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "WAF(M)", BLOCK_M,"Wahlaufforderung" },
@@ -385,7 +387,7 @@ static struct definition_opcode {
{ "PP----dJ------cc--------IIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "AF(V)", BLOCK_V,"Ausloesen durch FuFSt in verteilter Signalisierung" },
{ "PP----dJ--------eeeeeeeeIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "DSB(K)", BLOCK_K,"Durchschaltung" },
{ "PP----dJ-----KKKKKKKKKKKIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "DSBI(V)", BLOCK_V,"Umschaltbefehl intern (neuer SpK in der gleichen FuZ)" },
- { "PP----dJ-----KKKKKKKKKKKIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USF(K)", BLOCK_K,"Umschalten FuFst" },
+ { "PPuuuudJ-xnnnnKKKKKKKKKKIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USF(K)", BLOCK_K,"Umschalten FuFst" },
{ "PP----dJ-----KKKKKKKKKKKIIIAAAAAFFFFFFFFNNNUUUUUTTTTTTTTTTTTTTTT", NULL, "USBE(V)", BLOCK_V,"Umschaltbefehl extern (neuer SpK in einer anderen Funkzelle)" },
{ "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", NULL, "ZFZ(K)", BLOCK_K,"Zufallszahl" },
{ "________________________________________________________________", NULL, "opcode 61",BLOCK_I,"Illegaler Opcode" },
@@ -422,7 +424,7 @@ int init_telegramm(void)
printf("Message #%d has invalid digit '%c'\n", i, last_bit);
return -1;
}
- if (parameter->bits != count_bits) {
+ if (parameter->bits && parameter->bits != count_bits) {
printf("Message #%d has digit '%c' with %d bits, but parameter has %d bits\n", i, last_bit, count_bits, parameter->bits);
return -1;
}
@@ -508,13 +510,13 @@ static int encode_dialstring(uint64_t *value, const char *number)
max = strlen(number);
if (max > 16) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Given number '%s' has more than 16 digits\n", number);
+ LOGP(DFRAME, LOGL_NOTICE, "Given number '%s' has more than 16 digits\n", number);
return -EINVAL;
}
if (max == 16) {
if (number[0] != '0') {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Given 16 digit number '%s' does not start with '0'\n", number);
+ LOGP(DFRAME, LOGL_NOTICE, "Given 16 digit number '%s' does not start with '0'\n", number);
return -EINVAL;
}
*value = 0;
@@ -573,7 +575,7 @@ int match_fuz(telegramm_t *telegramm)
if (telegramm->fuz_nationalitaet != si.fuz_nat
|| telegramm->fuz_fuvst_nr != si.fuz_fuvst
|| telegramm->fuz_rest_nr != si.fuz_rest) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Ignoring message from mobile phone %d,%d,%d: Cell 'Funkzelle' does not match!\n", telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
+ LOGP(DFRAME, LOGL_NOTICE, "Ignoring message from mobile phone %d,%d,%d: Cell 'Funkzelle' does not match!\n", telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
return 0;
}
@@ -585,7 +587,7 @@ int match_futln(telegramm_t *telegramm, uint8_t futln_nat, uint8_t futln_fuvst,
if (telegramm->futln_nationalitaet != futln_nat
|| telegramm->futln_heimat_fuvst_nr != futln_fuvst
|| telegramm->futln_rest_nr != futln_rest) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Ignoring message from mobile phone %d,%d,%d: Mobile station 'Funktelefongeraet' does not match!\n", telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
+ LOGP(DFRAME, LOGL_NOTICE, "Ignoring message from mobile phone %d,%d,%d: Mobile station 'Funktelefongeraet' does not match!\n", telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
return 0;
}
@@ -598,19 +600,19 @@ static void debug_parameter(char digit, uint64_t value)
parameter = get_parameter(digit);
if (!parameter) {
- PDEBUG(DFRAME, DEBUG_ERROR, "Digit '%c' not found in definition_parameter list, please fix!\n", digit);
+ LOGP(DFRAME, LOGL_ERROR, "Digit '%c' not found in definition_parameter list, please fix!\n", digit);
abort();
}
if (parameter->value_names)
- PDEBUG(DFRAME, DEBUG_DEBUG, " (%c) %s : %s\n", digit, parameter->param_name, parameter->value_names[value]);
+ LOGP(DFRAME, LOGL_DEBUG, " (%c) %s : %s\n", digit, parameter->param_name, parameter->value_names[value]);
else if (parameter->bits == 64)
- PDEBUG(DFRAME, DEBUG_DEBUG, " (%c) %s : 0x%016" PRIx64 "\n", digit, parameter->param_name, value);
+ LOGP(DFRAME, LOGL_DEBUG, " (%c) %s : 0x%016" PRIx64 "\n", digit, parameter->param_name, value);
else if (digit == 'X') {
char wahlziffern[17];
decode_dialstring(wahlziffern, value);
- PDEBUG(DFRAME, DEBUG_DEBUG, " (%c) %s : '%s'\n", digit, parameter->param_name, wahlziffern);
+ LOGP(DFRAME, LOGL_DEBUG, " (%c) %s : '%s'\n", digit, parameter->param_name, wahlziffern);
} else
- PDEBUG(DFRAME, DEBUG_DEBUG, " (%c) %s : %" PRIu64 "\n", digit, parameter->param_name, value);
+ LOGP(DFRAME, LOGL_DEBUG, " (%c) %s : %" PRIu64 "\n", digit, parameter->param_name, value);
}
/* encode telegram to 70 bits
@@ -626,11 +628,12 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
int rc;
if (telegramm->opcode >= 64) {
- PDEBUG(DFRAME, DEBUG_ERROR, "Opcode '0x%x' exceeds bit range, please fix!\n", telegramm->opcode);
+ LOGP(DFRAME, LOGL_ERROR, "Opcode '0x%x' exceeds bit range, please fix!\n", telegramm->opcode);
abort();
}
- PDEBUG(DFRAME, DEBUG_DEBUG, "Coding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
+ if (debug)
+ LOGP(DFRAME, LOGL_INFO, "Coding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
/* copy opcode */
for (i = 0; i < 6; i++)
@@ -714,10 +717,13 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
case 'X':
rc = encode_dialstring(&value, telegramm->wahlziffern);
if (rc < 0) {
- PDEBUG(DFRAME, DEBUG_ERROR, "Illegal dial string '%s', please fix!\n", telegramm->wahlziffern);
+ LOGP(DFRAME, LOGL_ERROR, "Illegal dial string '%s', please fix!\n", telegramm->wahlziffern);
abort();
}
break;
+ case 'Y':
+ value = telegramm->bahn_ms;
+ break;
case 'Z':
value = telegramm->zeitschlitz_nr;
break;
@@ -790,6 +796,9 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
case 'w':
value = telegramm->erweitertes_frequenzbandbit;
break;
+ case 'x':
+ value = telegramm->bahn_bs;
+ break;
case 'y':
value = telegramm->reduzierungsfaktor;
break;
@@ -797,10 +806,10 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
value = telegramm->illegaler_opcode;
break;
default:
- PDEBUG(DFRAME, DEBUG_ERROR, "Parameter '%c' does not exist, please fix!\n", parameter);
+ LOGP(DFRAME, LOGL_ERROR, "Parameter '%c' does not exist, please fix!\n", parameter);
abort();
}
- if (debug && debuglevel <= DEBUG_DEBUG)
+ if (debug && loglevel <= LOGL_DEBUG)
debug_parameter(parameter, value);
val = value;
for (j = 0; string[63 - i - j] == parameter; j++) {
@@ -808,14 +817,14 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
val >>= 1;
}
if (val)
- PDEBUG(DFRAME, DEBUG_ERROR, "Parameter '%c' value '0x%" PRIx64 "' exceeds bit range!\n", parameter, value);
+ LOGP(DFRAME, LOGL_ERROR, "Parameter '%c' value '0x%" PRIx64 "' exceeds bit range!\n", parameter, value);
i += j - 1;
}
bits[70] = '\0';
if (debug) {
- PDEBUG(DFRAME, DEBUG_DEBUG, "OOOOOO%s\n", string);
- PDEBUG(DFRAME, DEBUG_DEBUG, "%s\n", bits);
+ LOGP(DFRAME, LOGL_DEBUG, "OOOOOO%s\n", string);
+ LOGP(DFRAME, LOGL_DEBUG, "%s\n", bits);
}
return bits;
@@ -839,7 +848,7 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
value = (value << 1) | (bits[i] == '1');
telegramm->opcode = value;
- PDEBUG(DFRAME, DEBUG_DEBUG, "Decoding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
+ LOGP(DFRAME, LOGL_INFO, "Decoding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
/* copy parameters */
if (auth && bits[1]) /* auth flag and chip card flag */
@@ -855,7 +864,7 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
value = (value >> 1) | ((uint64_t)(bits[69 - i - j] == '1') << 63);
value >>= 64 - j;
i += j - 1;
- if (debuglevel <= DEBUG_DEBUG)
+ if (loglevel <= LOGL_DEBUG)
debug_parameter(parameter, value);
switch (parameter) {
case 'A':
@@ -927,6 +936,9 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
case 'X':
decode_dialstring(telegramm->wahlziffern, value);
break;
+ case 'Y':
+ telegramm->bahn_ms = value;
+ break;
case 'Z':
telegramm->zeitschlitz_nr = value;
break;
@@ -999,6 +1011,9 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
case 'w':
telegramm->erweitertes_frequenzbandbit = value;
break;
+ case 'x':
+ telegramm->bahn_bs = value;
+ break;
case 'y':
telegramm->reduzierungsfaktor = value;
break;
@@ -1006,18 +1021,18 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
telegramm->illegaler_opcode = value;
break;
default:
- PDEBUG(DFRAME, DEBUG_ERROR, "Parameter '%c' does not exist, please fix!\n", parameter);
+ LOGP(DFRAME, LOGL_ERROR, "Parameter '%c' does not exist, please fix!\n", parameter);
abort();
}
}
- if (debuglevel <= DEBUG_DEBUG) {
+ if (loglevel <= LOGL_DEBUG) {
char debug_bits[71];
memcpy(debug_bits, bits, 70);
debug_bits[70] = '\0';
- PDEBUG(DFRAME, DEBUG_DEBUG, "OOOOOO%s\n", string);
- PDEBUG(DFRAME, DEBUG_DEBUG, "%s\n", debug_bits);
+ LOGP(DFRAME, LOGL_DEBUG, "OOOOOO%s\n", string);
+ LOGP(DFRAME, LOGL_DEBUG, "%s\n", debug_bits);
}
}
@@ -1190,7 +1205,7 @@ int init_coding(void)
block_code[i] = word;
}
- /* check if redunancy of a single bit matches the combined redundancy */
+ /* check if redundancy of a single bit matches the combined redundancy */
for (i = 0; i < 128; i++) {
int r = 0;
for (j = 0; j < 7; j++) {
@@ -1377,11 +1392,11 @@ static const char *decode(const char *input, int *_bit_errors)
fail_str[10] = '\0';
if (failed)
- PDEBUG(DFRAME, DEBUG_DEBUG, "Received Telegram with these block errors: '%s' (X = uncorrectable)\n", fail_str);
+ LOGP(DFRAME, LOGL_DEBUG, "Received Telegram with these block errors: '%s' (X = uncorrectable)\n", fail_str);
else if (warn)
- PDEBUG(DFRAME, DEBUG_DEBUG, "Received Telegram with these block errors: '%s' (1 / 2 = correctable)\n", fail_str);
+ LOGP(DFRAME, LOGL_DEBUG, "Received Telegram with these block errors: '%s' (1 / 2 = correctable)\n", fail_str);
else
- PDEBUG(DFRAME, DEBUG_DEBUG, "Received Telegram with no block errors.\n");
+ LOGP(DFRAME, LOGL_DEBUG, "Received Telegram with no block errors.\n");
if (failed)
return NULL;
@@ -1481,33 +1496,32 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
break;
}
if (i == 70) {
- PDEBUG(DFRAME, DEBUG_INFO, "Ignoring mysterious unmodulated telegramm (noise from phone's transmitter)\n");
+ LOGP(DFRAME, LOGL_INFO, "Ignoring mysterious unmodulated telegramm (noise from phone's transmitter)\n");
return;
}
+ LOGP_CHAN(DDSP, LOGL_INFO, "RF level: %.1f dB RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) %s\n", cnetz->rf_level_db, fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
+ if (bit_errors)
+ LOGP_CHAN(DDSP, LOGL_INFO, " -> Frame has %d bit errors.\n", bit_errors);
+
disassemble_telegramm(&telegramm, bits, si.authentifikationsbit);
opcode = telegramm.opcode;
telegramm.level = level;
telegramm.sync_time = sync_time;
- if (bit_errors)
- PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
- else
- PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
-
if (cnetz->sender.loopback) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
cnetz_sync_frame(cnetz, sync_time, -1);
return;
}
if (opcode >= 32) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm that is not used by mobile station, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm that is not used by mobile station, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
return;
}
if (definition_opcode[opcode].block == BLOCK_I) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm that is an illegal opcode, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm that is an illegal opcode, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
return;
}
@@ -1530,7 +1544,7 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
if (definition_opcode[opcode].block != BLOCK_R && definition_opcode[opcode].block != BLOCK_M) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm that is not used OgK channel signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm that is not used OgK channel signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
return;
}
/* determine block by last timeslot sent and by message type
@@ -1543,14 +1557,14 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
break;
case DSP_MODE_SPK_K:
if (definition_opcode[opcode].block != BLOCK_K) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm that is not used for concentrated signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm that is not used for concentrated signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
return;
}
cnetz_receive_telegramm_spk_k(cnetz, &telegramm);
break;
case DSP_MODE_SPK_V:
if (definition_opcode[opcode].block != BLOCK_V) {
- PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm that is not used for distributed signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
+ LOGP(DFRAME, LOGL_NOTICE, "Received Telegramm that is not used for distributed signaling, ignoring! (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
return;
}
cnetz_receive_telegramm_spk_v(cnetz, &telegramm);
@@ -1565,6 +1579,7 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
const telegramm_t *telegramm = NULL;
uint8_t opcode;
char *bits;
+ int debug = 1;
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
@@ -1583,8 +1598,15 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
;
}
+ if (!telegramm)
+ return NULL;
+
opcode = telegramm->opcode;
- bits = assemble_telegramm(telegramm, (opcode != OPCODE_LR_R) && (opcode != OPCODE_MLR_M));
+ if (opcode == OPCODE_LR_R && cnetz->sched_lr_debugged)
+ debug = 0;
+ if (opcode == OPCODE_MLR_M && cnetz->sched_mlr_debugged)
+ debug = 0;
+ bits = assemble_telegramm(telegramm, debug);
bits = encode(bits);
bits = interleave(bits);
@@ -1596,6 +1618,13 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
bits[i] ^= 1;
}
+ if (opcode == OPCODE_LR_R && !cnetz->sched_lr_debugged)
+ cnetz->sched_lr_debugged = 1;
+ if (opcode == OPCODE_MLR_M && !cnetz->sched_mlr_debugged) {
+ cnetz->sched_mlr_debugged = 1;
+ LOGP(DFRAME, LOGL_INFO, "Subsequent IDLE frames are not show, to prevent flooding the output.\n");
+ }
+
return bits;
}
diff --git a/src/cnetz/telegramm.h b/src/cnetz/telegramm.h
index 06758aa..06adda8 100644
--- a/src/cnetz/telegramm.h
+++ b/src/cnetz/telegramm.h
@@ -112,6 +112,8 @@ typedef struct telegramm {
uint8_t erweitertes_frequenzbandbit;
uint8_t reduzierungsfaktor;
uint64_t illegaler_opcode;
+ uint8_t bahn_ms;
+ uint8_t bahn_bs;
} telegramm_t;
int init_telegramm(void);
diff --git a/src/cnetz/transaction.c b/src/cnetz/transaction.c
index acfe416..f89718b 100644
--- a/src/cnetz/transaction.c
+++ b/src/cnetz/transaction.c
@@ -20,14 +20,17 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#include <math.h>
#include "../libsample/sample.h"
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
#include "../libmobile/call.h"
-#include "../libmncc/cause.h"
+#include "../libmobile/cause.h"
#include "cnetz.h"
#include "telegramm.h"
#include "database.h"
+static int new_cueue_position = 0;
+
const char *transaction2rufnummer(transaction_t *trans)
{
static char rufnummer[32]; /* make GCC happy (overflow check) */
@@ -38,25 +41,35 @@ const char *transaction2rufnummer(transaction_t *trans)
}
/* create transaction */
-transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended)
+transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended, double rf_level_db)
{
- sender_t *sender;
- transaction_t *trans = NULL;
- cnetz_t *search_cnetz;
+ transaction_t *trans;
- /* search transaction for this subsriber */
- for (sender = sender_head; sender; sender = sender->next) {
- search_cnetz = (cnetz_t *) sender;
- /* search transaction for this callref */
- trans = search_transaction_number(search_cnetz, futln_nat, futln_fuvst, futln_rest);
- if (trans)
- break;
- }
+ trans = search_transaction_number_global(futln_nat, futln_fuvst, futln_rest);
if (trans) {
const char *rufnummer = transaction2rufnummer(trans);
int old_callref = trans->callref;
cnetz_t *old_cnetz = trans->cnetz;
- PDEBUG(DTRANS, DEBUG_NOTICE, "Found alredy pending transaction for subscriber '%s', deleting!\n", rufnummer);
+ /* both states must be the same and one of the give selection */
+ if ((trans->state & state & (TRANS_EM | TRANS_UM | TRANS_VWG | TRANS_ATQ_IDLE))) {
+ if (!isnan(trans->rf_level_db) && !isnan(rf_level_db) && trans->cnetz->kanal != cnetz->kanal) {
+ if (rf_level_db > trans->rf_level_db) {
+ LOGP(DTRANS, LOGL_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is stronger, so we move to that channel!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
+ trans->rf_level_db = rf_level_db;
+ unlink_transaction(trans);
+ link_transaction(trans, cnetz);
+ update_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, cnetz->kanal, NULL, NULL, 1, 0);
+ return trans;
+ }
+ if (rf_level_db < trans->rf_level_db) {
+ LOGP(DTRANS, LOGL_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is weaker, so we ignore that channel!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
+ return trans;
+ }
+ }
+ LOGP(DTRANS, LOGL_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is also received. Try to avoid multiple OgK channels!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
+ return trans;
+ }
+ LOGP(DTRANS, LOGL_NOTICE, "Found already pending transaction for subscriber '%s', deleting!\n", rufnummer);
destroy_transaction(trans);
if (old_cnetz) /* should be... */
cnetz_go_idle(old_cnetz);
@@ -66,11 +79,11 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
trans = calloc(1, sizeof(*trans));
if (!trans) {
- PDEBUG(DTRANS, DEBUG_ERROR, "No memory!\n");
+ LOGP(DTRANS, LOGL_ERROR, "No memory!\n");
return NULL;
}
- timer_init(&trans->timer, transaction_timeout, trans);
+ osmo_timer_setup(&trans->timer, transaction_timeout, trans);
trans_new_state(trans, state);
trans->futln_nat = futln_nat;
@@ -83,15 +96,17 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
trans->mt_call = 1;
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DTRANS, DEBUG_INFO, "Created transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DTRANS, LOGL_INFO, "Created transaction for subscriber '%s'\n", rufnummer);
link_transaction(trans, cnetz);
/* update database: now busy */
- update_db(cnetz, futln_nat, futln_fuvst, futln_rest, &futelg_bit, &extended, 1, 0);
+ update_db(futln_nat, futln_fuvst, futln_rest, cnetz->kanal, &futelg_bit, &extended, 1, 0);
trans->futelg_bit = futelg_bit;
trans->extended = extended;
+ trans->rf_level_db = rf_level_db;
+
return trans;
}
@@ -99,14 +114,14 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
void destroy_transaction(transaction_t *trans)
{
/* update database: now idle */
- update_db(trans->cnetz, trans->futln_nat, trans->futln_fuvst, trans->futln_rest, NULL, NULL, 0, trans->page_failed);
+ update_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, 0, NULL, NULL, 0, trans->page_failed);
unlink_transaction(trans);
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DTRANS, DEBUG_INFO, "Destroying transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DTRANS, LOGL_INFO, "Destroying transaction for subscriber '%s'\n", rufnummer);
- timer_exit(&trans->timer);
+ osmo_timer_del(&trans->timer);
trans_new_state(trans, 0);
@@ -119,7 +134,7 @@ void link_transaction(transaction_t *trans, cnetz_t *cnetz)
transaction_t **transp;
/* attach to end of list, so first transaction is served first */
- PDEBUG(DTRANS, DEBUG_DEBUG, "Linking transaction %p to cnetz %p\n", trans, cnetz);
+ LOGP(DTRANS, LOGL_DEBUG, "Linking transaction %p to cnetz %p\n", trans, cnetz);
trans->cnetz = cnetz;
trans->next = NULL;
transp = &cnetz->trans_list;
@@ -135,12 +150,12 @@ void unlink_transaction(transaction_t *trans)
transaction_t **transp;
/* unlink */
- PDEBUG(DTRANS, DEBUG_DEBUG, "Unlinking transaction %p from cnetz %p\n", trans, trans->cnetz);
+ LOGP(DTRANS, LOGL_DEBUG, "Unlinking transaction %p from cnetz %p\n", trans, trans->cnetz);
transp = &trans->cnetz->trans_list;
while (*transp && *transp != trans)
transp = &((*transp)->next);
if (!(*transp)) {
- PDEBUG(DTRANS, DEBUG_ERROR, "Transaction not in list, please fix!!\n");
+ LOGP(DTRANS, LOGL_ERROR, "Transaction not in list, please fix!!\n");
abort();
}
*transp = trans->next;
@@ -155,7 +170,7 @@ transaction_t *search_transaction(cnetz_t *cnetz, uint64_t state_mask)
while (trans) {
if ((trans->state & state_mask)) {
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DTRANS, DEBUG_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DTRANS, LOGL_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
return trans;
}
trans = trans->next;
@@ -173,7 +188,7 @@ transaction_t *search_transaction_number(cnetz_t *cnetz, uint8_t futln_nat, uint
&& trans->futln_fuvst == futln_fuvst
&& trans->futln_rest == futln_rest) {
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DTRANS, DEBUG_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DTRANS, LOGL_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
return trans;
}
trans = trans->next;
@@ -182,6 +197,23 @@ transaction_t *search_transaction_number(cnetz_t *cnetz, uint8_t futln_nat, uint
return NULL;
}
+transaction_t *search_transaction_number_global(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest)
+{
+ sender_t *sender;
+ cnetz_t *cnetz;
+ transaction_t *trans = NULL;
+
+ /* search transaction for this subscriber */
+ for (sender = sender_head; sender; sender = sender->next) {
+ cnetz = (cnetz_t *) sender;
+ /* search transaction for this callref */
+ trans = search_transaction_number(cnetz, futln_nat, futln_fuvst, futln_rest);
+ if (trans)
+ break;
+ }
+
+ return trans;
+}
transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref)
{
transaction_t *trans = cnetz->trans_list;
@@ -192,7 +224,7 @@ transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref)
while (trans) {
if (trans->callref == callref) {
const char *rufnummer = transaction2rufnummer(trans);
- PDEBUG(DTRANS, DEBUG_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
+ LOGP(DTRANS, LOGL_DEBUG, "Found transaction for subscriber '%s'\n", rufnummer);
return trans;
}
trans = trans->next;
@@ -201,6 +233,42 @@ transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref)
return NULL;
}
+/* get oldest transaction in queue:
+ *
+ * oldest means that the queue number is the smallest.
+ * all candidates (transactions) must be in queue state.
+ */
+transaction_t *search_transaction_queue(void)
+{
+ sender_t *sender;
+ transaction_t *trans, *found = NULL;
+ cnetz_t *cnetz;
+ int queue_max = 0;
+
+ for (sender = sender_head; sender; sender = sender->next) {
+ cnetz = (cnetz_t *) sender;
+ trans = cnetz->trans_list;
+ while (trans) {
+ if ((trans->state & (TRANS_MO_QUEUE | TRANS_MT_QUEUE))) {
+ /* select if first or lower number */
+ if (!found || trans->queue_position < queue_max) {
+ queue_max = trans->queue_position;
+ found = trans;
+ }
+ }
+ trans = trans->next;
+ }
+ }
+
+ if (found) {
+ const char *rufnummer = transaction2rufnummer(found);
+ LOGP(DTRANS, LOGL_DEBUG, "Found oldest transaction in queue for subscriber '%s'\n", rufnummer);
+ return found;
+ }
+
+ return NULL;
+}
+
static const char *trans_state_name(uint64_t state)
{
switch (state) {
@@ -252,6 +320,8 @@ static const char *trans_state_name(uint64_t state)
return "AT";
case TRANS_ATQ:
return "ATQ";
+ case TRANS_ATQ_IDLE:
+ return "ATQ_IDLE";
case TRANS_MO_QUEUE:
return "MO_QUEUE";
case TRANS_MT_QUEUE:
@@ -261,7 +331,7 @@ static const char *trans_state_name(uint64_t state)
case TRANS_MT_DELAY:
return "MT_DELAY";
default:
- return "<invald transaction state>";
+ return "<invalid transaction state>";
}
}
@@ -301,6 +371,7 @@ const char *trans_short_state_name(uint64_t state)
case TRANS_AF:
case TRANS_AT:
case TRANS_ATQ:
+ case TRANS_ATQ_IDLE:
return "RELEASE";
case TRANS_MO_QUEUE:
case TRANS_MO_DELAY:
@@ -309,14 +380,17 @@ const char *trans_short_state_name(uint64_t state)
case TRANS_MT_DELAY:
return "IN QUEUE";
default:
- return "<invald transaction state>";
+ return "<invalid transaction state>";
}
}
void trans_new_state(transaction_t *trans, uint64_t state)
{
- PDEBUG(DTRANS, DEBUG_INFO, "Transaction (%s) state %s -> %s\n", transaction2rufnummer(trans), trans_state_name(trans->state), trans_state_name(state));
+ LOGP(DTRANS, LOGL_INFO, "Transaction (%s) state %s -> %s\n", transaction2rufnummer(trans), trans_state_name(trans->state), trans_state_name(state));
trans->state = state;
+ /* in case of a queue, set new positon */
+ if (!trans->queue_position && (state == TRANS_MO_QUEUE || state == TRANS_MT_QUEUE))
+ trans->queue_position = ++new_cueue_position;
cnetz_display_status();
}
@@ -324,12 +398,12 @@ void cnetz_flush_other_transactions(cnetz_t *cnetz, transaction_t *trans)
{
/* flush after this very trans */
while (trans->next) {
- PDEBUG(DTRANS, DEBUG_NOTICE, "Kicking other pending transaction\n");
+ LOGP(DTRANS, LOGL_NOTICE, "Kicking other pending transaction\n");
destroy_transaction(trans->next);
}
/* flush before this very trans */
while (cnetz->trans_list != trans) {
- PDEBUG(DTRANS, DEBUG_NOTICE, "Kicking other pending transaction\n");
+ LOGP(DTRANS, LOGL_NOTICE, "Kicking other pending transaction\n");
destroy_transaction(cnetz->trans_list);
}
}
diff --git a/src/cnetz/transaction.h b/src/cnetz/transaction.h
index edb1832..4a5d70b 100644
--- a/src/cnetz/transaction.h
+++ b/src/cnetz/transaction.h
@@ -13,7 +13,7 @@
#define TRANS_WBN (1 << 7) /* dialing received, waiting for time slot to reject call */
#define TRANS_VAG (1 << 8) /* establishment of call sent, switching channel */
/* mobile terminated call */
-#define TRANS_WSK (1 << 9) /* incomming call in queue */
+#define TRANS_WSK (1 << 9) /* incoming call in queue */
#define TRANS_VAK (1 << 10) /* establishment of call sent, switching channel */
/* traffic channel */
#define TRANS_BQ (1 << 11) /* accnowledge channel */
@@ -29,11 +29,12 @@
#define TRANS_AF (1 << 20) /* release connection by base station (SpK) */
#define TRANS_AT (1 << 21) /* release connection by mobile station */
#define TRANS_ATQ (1 << 22) /* acknowledge release of MO call in queue */
+#define TRANS_ATQ_IDLE (1 << 23) /* repeat, if call has been released already (mobile sends again) */
/* queue */
-#define TRANS_MO_QUEUE (1 << 23) /* MO queue */
-#define TRANS_MT_QUEUE (1 << 24) /* MT queue */
-#define TRANS_MO_DELAY (1 << 25) /* delay to be sure the channel is free again */
-#define TRANS_MT_DELAY (1 << 26)
+#define TRANS_MO_QUEUE (1 << 24) /* MO queue */
+#define TRANS_MT_QUEUE (1 << 25) /* MT queue */
+#define TRANS_MO_DELAY (1 << 26) /* delay to be sure the channel is free again */
+#define TRANS_MT_DELAY (1 << 27)
typedef struct transaction {
struct transaction *next; /* pointer to next node in list */
@@ -49,23 +50,29 @@ typedef struct transaction {
int8_t release_cause; /* reason for release, (c-netz coding) */
int try; /* counts resending messages */
int repeat; /* counts repeating messages */
- struct timer timer; /* for varous timeouts */
+ struct osmo_timer_list timer; /* for varous timeouts */
int mo_call; /* flags a moile originating call */
int mt_call; /* flags a moile terminating call */
int page_failed; /* failed to get a response from MS */
- double call_start; /* when did the call start? (used for metering) */
+ double metering_time; /* time between units (0.0 if no metering set) */
+ double meter_start; /* when did the metering start? (0.0 if not yet started) */
+ double meter_end; /* when did the metering end? (0.0 if not yet ended) */
+ int queue_position; /* to find next transaction in queue */
+ double rf_level_db; /* level of first contact, so we can detect correct channel at multiple receptions */
} transaction_t;
const char *transaction2rufnummer(transaction_t *trans);
-transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended);
+transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended, double rf_level_db);
void destroy_transaction(transaction_t *trans);
void link_transaction(transaction_t *trans, cnetz_t *cnetz);
void unlink_transaction(transaction_t *trans);
transaction_t *search_transaction(cnetz_t *cnetz, uint64_t state_mask);
transaction_t *search_transaction_number(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
+transaction_t *search_transaction_number_global(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref);
+transaction_t *search_transaction_queue(void);
void trans_new_state(transaction_t *trans, uint64_t state);
void cnetz_flush_other_transactions(cnetz_t *cnetz, transaction_t *trans);
-void transaction_timeout(struct timer *timer);
+void transaction_timeout(void *data);
const char *trans_short_state_name(uint64_t state);