C-Netz: Added list of base station names and IDs

Automatic polarity detection is now done by using the polarity of last
transmitted message. We cannot use two base station IDs anymore, to
detect the polarity. Now we deal only with the defined base station ID.
pull/1/head
Andreas Eversberg 3 years ago
parent 008bca784b
commit 360729d270
  1. 1
      src/cnetz/Makefile.am
  2. 116
      src/cnetz/cnetz.c
  3. 8
      src/cnetz/cnetz.h
  4. 23
      src/cnetz/dsp.c
  5. 57
      src/cnetz/main.c
  6. 974
      src/cnetz/stations.c
  7. 6
      src/cnetz/stations.h
  8. 51
      src/cnetz/sysinfo.c
  9. 3
      src/cnetz/sysinfo.h
  10. 51
      src/cnetz/telegramm.c
  11. 2
      src/cnetz/telegramm.h

@ -13,6 +13,7 @@ cnetz_SOURCES = \
fsk_demod.c \
image.c \
ansage.c \
stations.c \
main.c
cnetz_LDADD = \
$(COMMON_LA) \

@ -151,6 +151,7 @@
#include "sysinfo.h"
#include "telegramm.h"
#include "dsp.h"
#include "stations.h"
/* uncomment this to do echo debugging (-l) on Speech Channel */
//#define DEBUG_SPK
@ -338,26 +339,18 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
switch (polarity) {
case 1:
/* select cell 0 for positive polarity */
cnetz->cell_nr = 0;
cnetz->cell_auto = 0;
if (si[cnetz->cell_nr].flip_polarity != 0) {
fprintf(stderr, "cell %d must have positive polarity, please fix!\n", cnetz->cell_nr);
abort();
}
cnetz->negative_polarity = 0;
cnetz->auto_polarity = 0;
break;
case -1:
/* select cell 1 for negative polarity */
cnetz->cell_nr = 1;
cnetz->cell_auto = 0;
if (si[cnetz->cell_nr].flip_polarity == 0) {
fprintf(stderr, "cell %d must have negative polarity, please fix!\n", cnetz->cell_nr);
abort();
}
cnetz->negative_polarity = 1;
cnetz->auto_polarity = 0;
break;
default:
/* send two cells and select by the first message from mobile */
cnetz->cell_nr = 0; /* use cell 0 until selected */
cnetz->cell_auto = 1;
cnetz->negative_polarity = 0;
cnetz->auto_polarity = 1;
}
cnetz->pre_emphasis = pre_emphasis;
@ -402,6 +395,7 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
#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 ID %d,%d,%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));
return 0;
@ -948,24 +942,24 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.opcode = OPCODE_LR_R;
telegramm.max_sendeleistung = cnetz->ms_power;
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.zeitschlitz_nr = cnetz->sched_ts;
telegramm.grenzwert_fuer_einbuchen_und_umbuchen = si[cnetz->cell_nr].grenz_einbuchen;
telegramm.authentifikationsbit = si[cnetz->cell_nr].authentifikationsbit;
telegramm.vermittlungstechnische_sperren = si[cnetz->cell_nr].vermittlungstechnische_sperren;
telegramm.ws_kennung = si[cnetz->cell_nr].ws_kennung;
telegramm.reduzierungsfaktor = si[cnetz->cell_nr].reduzierung;
telegramm.fuz_nationalitaet = si[cnetz->cell_nr].fuz_nat;
telegramm.fuz_fuvst_nr = si[cnetz->cell_nr].fuz_fuvst;
telegramm.fuz_rest_nr = si[cnetz->cell_nr].fuz_rest;
telegramm.kennung_fufst = si[cnetz->cell_nr].kennung_fufst;
telegramm.nachbarschafts_prioritaets_bit = si[cnetz->cell_nr].nachbar_prio;
telegramm.bewertung_nach_pegel_und_entfernung = si[cnetz->cell_nr].bewertung;
telegramm.entfernungsangabe_der_fufst = si[cnetz->cell_nr].entfernung;
telegramm.mittelungsfaktor_fuer_ausloesen = si[cnetz->cell_nr].mittel_ausloesen;
telegramm.mittelungsfaktor_fuer_umschalten = si[cnetz->cell_nr].mittel_umschalten;
telegramm.grenzwert_fuer_umschalten = si[cnetz->cell_nr].grenz_umschalten;
telegramm.grenze_fuer_ausloesen = si[cnetz->cell_nr].grenz_ausloesen;
telegramm.grenzwert_fuer_einbuchen_und_umbuchen = si.grenz_einbuchen;
telegramm.authentifikationsbit = si.authentifikationsbit;
telegramm.vermittlungstechnische_sperren = si.vermittlungstechnische_sperren;
telegramm.ws_kennung = si.ws_kennung;
telegramm.reduzierungsfaktor = si.reduzierung;
telegramm.fuz_nationalitaet = si.fuz_nat;
telegramm.fuz_fuvst_nr = si.fuz_fuvst;
telegramm.fuz_rest_nr = si.fuz_rest;
telegramm.kennung_fufst = si.kennung_fufst;
telegramm.nachbarschafts_prioritaets_bit = si.nachbar_prio;
telegramm.bewertung_nach_pegel_und_entfernung = si.bewertung;
telegramm.entfernungsangabe_der_fufst = si.entfernung;
telegramm.mittelungsfaktor_fuer_ausloesen = si.mittel_ausloesen;
telegramm.mittelungsfaktor_fuer_umschalten = si.mittel_umschalten;
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);
if (trans) {
@ -1090,10 +1084,10 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
telegramm.opcode = OPCODE_MLR_M;
telegramm.max_sendeleistung = cnetz->ms_power;
telegramm.ogk_verkehrsanteil = 0; /* must be 0 or phone might not respond to messages in different slot */
telegramm.teilnehmergruppensperre = si[cnetz->cell_nr].teilnehmergruppensperre;
telegramm.anzahl_gesperrter_teilnehmergruppen = si[cnetz->cell_nr].anzahl_gesperrter_teilnehmergruppen;
telegramm.teilnehmergruppensperre = si.teilnehmergruppensperre;
telegramm.anzahl_gesperrter_teilnehmergruppen = si.anzahl_gesperrter_teilnehmergruppen;
telegramm.ogk_vorschlag = CNETZ_OGK_KANAL;
telegramm.fuz_rest_nr = si[cnetz->cell_nr].fuz_rest;
telegramm.fuz_rest_nr = si.fuz_rest;
trans = search_transaction(cnetz, TRANS_VWG | TRANS_MA);
if (trans) {
@ -1133,10 +1127,10 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
switch (opcode) {
case OPCODE_EM_R:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
if (si[cnetz->cell_nr].authentifikationsbit && telegramm->chipkarten_futelg_bit)
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);
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);
@ -1154,10 +1148,10 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
valid_frame = 1;
break;
case OPCODE_UM_R:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
if (si[cnetz->cell_nr].authentifikationsbit && telegramm->chipkarten_futelg_bit)
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);
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);
@ -1176,14 +1170,14 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
case OPCODE_UWG_R:
case OPCODE_UWK_R:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
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);
break;
case OPCODE_VWG_R:
case OPCODE_SRG_R:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
if (opcode == OPCODE_VWG_R)
@ -1217,7 +1211,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
valid_frame = 1;
break;
case OPCODE_ATO_R:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
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);
@ -1236,7 +1230,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
valid_frame = 1;
break;
case OPCODE_MFT_M:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
if (!match_fuz(telegramm))
break;
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
if (!trans) {
@ -1278,15 +1272,15 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
telegramm.max_sendeleistung = cnetz->ms_power;
telegramm.sendeleistungsanpassung = 1;
telegramm.entfernung = si[cnetz->cell_nr].entfernung;
telegramm.fuz_nationalitaet = si[cnetz->cell_nr].fuz_nat;
telegramm.fuz_fuvst_nr = si[cnetz->cell_nr].fuz_fuvst;
telegramm.fuz_rest_nr = si[cnetz->cell_nr].fuz_rest;
telegramm.entfernung = si.entfernung;
telegramm.fuz_nationalitaet = si.fuz_nat;
telegramm.fuz_fuvst_nr = si.fuz_fuvst;
telegramm.fuz_rest_nr = si.fuz_rest;
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.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.zufallszahl = cnetz->challenge;
switch (trans->state) {
@ -1295,7 +1289,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
telegramm.opcode = OPCODE_BQ_K;
if (++trans->repeat >= 8 && !timer_running(&trans->timer)) {
if (cnetz->challenge_valid) {
if (si[cnetz->cell_nr].authentifikationsbit == 0) {
if (si.authentifikationsbit == 0) {
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Cannot authenticate, because base station does not support it. (Authentication disabled in sysinfo.)\n");
goto no_auth;
}
@ -1454,7 +1448,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
switch (opcode) {
case OPCODE_BEL_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1468,7 +1462,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
trans->try = 0;
break;
case OPCODE_DSQ_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1516,7 +1510,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
break;
case OPCODE_VH_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1529,7 +1523,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
timer_stop(&trans->timer);
break;
case OPCODE_RTAQ_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1542,7 +1536,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
timer_start(&trans->timer, 0.0375 * F_RTA); /* F_RTA frames */
break;
case OPCODE_AH_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1561,7 +1555,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
call_up_answer(trans->callref, transaction2rufnummer(trans));
break;
case OPCODE_AT_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1610,15 +1604,15 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
telegramm.sendeleistungsanpassung = 1;
telegramm.ankuendigung_gespraechsende = 0;
telegramm.gebuehren_stand = meter;
telegramm.fuz_nationalitaet = si[cnetz->cell_nr].fuz_nat;
telegramm.fuz_fuvst_nr = si[cnetz->cell_nr].fuz_fuvst;
telegramm.fuz_rest_nr = si[cnetz->cell_nr].fuz_rest;
telegramm.fuz_nationalitaet = si.fuz_nat;
telegramm.fuz_fuvst_nr = si.fuz_fuvst;
telegramm.fuz_rest_nr = si.fuz_rest;
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.entfernung = si[cnetz->cell_nr].entfernung;
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
telegramm.entfernung = si.entfernung;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.gueltigkeit_des_gebuehrenstandes = 0;
telegramm.ausloesegrund = trans->release_cause;
@ -1667,7 +1661,7 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
case OPCODE_VH_V:
case OPCODE_USAI_V:
case OPCODE_USAE_V:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
@ -1699,7 +1693,7 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
cnetz->scrambler_switch = 0;
break;
case OPCODE_AT_V:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
if (!match_fuz(telegramm)) {
break;
}
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {

@ -85,13 +85,13 @@ typedef struct cnetz {
/* all cnetz states */
enum cnetz_state state; /* main state of sender */
/* cell nr selection */
int cell_auto; /* if set, cell_nr is selected automatically */
int cell_nr; /* current cell number to use (sysinfo) */
/* polarity detection */
int auto_polarity; /* if set, polarity of transmitter is selected */
int negative_polarity; /* current polarity 0: positive 1: negative */
/* scheduler */
int sched_ts; /* current time slot */
int sched_last_ts[2]; /* last timeslot we transmitted, so we can match MS timeslot */
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 */

@ -646,20 +646,21 @@ again:
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
/* if automatic cell selection is used, toggle between
* two cells until a response for one cell is received
/* 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->cell_auto)
cnetz->cell_nr = (cnetz->sched_ts & 7) >> 2;
/* send on timeslots depending on the cell_nr:
* cell 0: 0, 8, 16, 24
* cell 1: 4, 12, 20, 28
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->cell_nr == 0)
|| ((cnetz->sched_ts & 7) == 4 && cnetz->cell_nr == 1)) {
if (((cnetz->sched_ts & 7) == 0 && cnetz->negative_polarity == 0)
|| ((cnetz->sched_ts & 7) == 4 && cnetz->negative_polarity == 1)) {
if (cnetz->sched_r_m == 0) {
/* set last time slot, so we can match received message from mobile station */
cnetz->sched_last_ts[cnetz->cell_nr] = cnetz->sched_ts;
/* 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);
} else {

@ -36,6 +36,7 @@
#include "dsp.h"
#include "telegramm.h"
#include "ansage.h"
#include "stations.h"
/* settings */
int num_chan_type = 0;
@ -51,8 +52,9 @@ uint64_t challenge;
int response_valid;
uint64_t response;
uint8_t fuz_nat = 1;
uint8_t fuz_fuvst = 1;
uint8_t fuz_rest = 38;
uint8_t fuz_fuvst = 4;
uint8_t fuz_rest = 66;
const char *fuz_name = NULL;
uint8_t kennung_fufst = 1; /* normal prio */
uint8_t authentifikationsbit = 0;
uint8_t ws_kennung = 0; /* no queue */
@ -90,7 +92,7 @@ void print_help(const char *arg0)
printf(" -F --flip-polarity no | yes | auto\n");
printf(" Flip polarity of transmitted FSK signal. If yes, the sound card\n");
printf(" generates a negative signal rather than a positive one. If auto, the\n");
printf(" base station generates two virtual base stations with both polarities.\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");
@ -124,6 +126,11 @@ void print_help(const char *arg0)
printf(" Set switching center ID of base station. (default = %d)\n", fuz_fuvst);
printf(" -S --sysinfo fuz-rest=<id>\n");
printf(" Set cell ID of base station. (default = %d)\n", fuz_rest);
printf(" -S --sysinfo fuz=<nat>,<fuvst>,<rest>\n");
printf(" Set country, switching center and cell ID of base station at once.\n");
printf(" -S --sysinfo fuz-name=<name>\n");
printf(" Set country, switching center and cell ID by providing name or prefix\n");
printf(" Use 'list' to get a list of all base sstation names.\n");
printf(" -S --sysinfo kennung-fufst=<id>\n");
printf(" Set priority for selecting base station. (default = %d)\n", kennung_fufst);
printf(" 0 = Test (Only special mobile stations may register.)\n");
@ -259,7 +266,7 @@ static void add_options(void)
static int handle_options(int short_option, int argi, char **argv)
{
int rc;
const char *p;
const char *p, *q;
switch (short_option) {
case 'T':
@ -333,11 +340,30 @@ static int handle_options(int short_option, int argi, char **argv)
fuz_nat = atoi_limit(p, 0, 7);
} else
if (!strncasecmp(argv[argi], "fuz-fuvst=", p - argv[argi])) {
fuz_fuvst = atoi_limit(p, 0, 32);
fuz_fuvst = atoi_limit(p, 0, 31);
} else
if (!strncasecmp(argv[argi], "fuz-rest=", p - argv[argi])) {
fuz_rest = atoi_limit(p, 0, 255);
} else
if (!strncasecmp(argv[argi], "fuz=", p - argv[argi])) {
q = strchr(p, ',');
if (!q) {
error_fuz:
fprintf(stderr, "You must give 3 values for 'fuz'.\n");
return -EINVAL;
}
fuz_nat = atoi_limit(p, 0, 7);
p = q + 1;
q = strchr(p, ',');
if (!q)
goto error_fuz;
fuz_fuvst = atoi_limit(p, 0, 31);
p = q + 1;
fuz_rest = atoi_limit(p, 0, 255);
} else
if (!strncasecmp(argv[argi], "fuz-name=", p - argv[argi])) {
fuz_name = strdup(p);
} else
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
kennung_fufst = atoi_limit(p, 0, 3);
} else
@ -433,6 +459,8 @@ int main(int argc, char *argv[])
init_besetzton();
init_ansage();
init_station();
main_mobile_init();
/* handle options / config file */
@ -452,6 +480,25 @@ int main(int argc, char *argv[])
}
}
/* resolve name of base station */
if (fuz_name) {
const char *error;
/* get data from name */
if (!strcmp(fuz_name, "list")) {
station_list();
return 0;
}
/* resolve */
error = get_station_id(fuz_name, &fuz_nat, &fuz_fuvst, &fuz_rest);
if (error) {
fprintf(stderr, "%s\n", error);
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);
mandatory = 1;

@ -0,0 +1,974 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "stations.h"
/* The list of cell towers is ripped from BSA61 phone's firmware */
static struct cnetz_stations {
char standort[64];
uint8_t nat, fuvst, rest;
} cnetz_stations[] = {
/* Standort Nat FuVST Rest */
{ "Aachen 1", 3, 2, 86 },
{ "AachenKo", 3, 2, 50 },
{ "Aache120", 3, 2, 52 },
{ "Aachen57", 3, 2, 53 },
{ "Alsdorf3", 3, 2, 49 },
{ "AltonaWF", 5, 2, 31 },
{ "B.Berleb", 7, 2, 43 },
{ "B.Bertr.", 7, 2, 20 },
{ "B.Honn80", 7, 2, 12 },
{ "B.Honn0", 7, 2, 31 },
{ "B.Mari.", 7, 2, 19 },
{ "B.Neuena", 7, 2, 38 },
{ "Balve 7", 5, 2, 33 },
{ "Beckum 3", 5, 2, 17 },
{ "Bensb.60", 6, 2, 78 },
{ "Bergheim", 6, 2, 16 },
{ "BergiGla", 6, 2, 21 },
{ "Betzd. 4", 7, 2, 23 },
{ "Bocholt0", 3, 2, 66 },
{ "Bochum 0", 4, 2, 17 },
{ "Stiepel", 4, 2, 84 },
{ "Wattensc", 4, 2, 83 },
{ "Boenen", 4, 2, 34 },
{ "Bonn 0", 7, 2, 7 },
{ "Bonn 2 K", 7, 2, 72 },
{ "Bonn 13", 7, 2, 42 },
{ "Bonn 320", 7, 2, 11 },
{ "Bonn 620", 7, 2, 13 },
{ "Bonn 670", 7, 2, 36 },
{ "Bottrop", 1, 2, 13 },
{ "BrilonMe", 5, 2, 57 },
{ "Bruehl 0", 6, 2, 29 },
{ "Bueren 1", 5, 2, 56 },
{ "Bursche.", 2, 2, 93 },
{ "Cast.Ra.", 4, 2, 27 },
{ "Coesfeld", 5, 2, 42 },
{ "Datteln", 4, 2, 80 },
{ "Dawn 4", 7, 2, 4 },
{ "Dinsl. 2", 1, 2, 82 },
{ "Dormag.", 2, 2, 40 },
{ "Dorsten", 5, 2, 2 },
{ "Dortm.10", 4, 2, 28 },
{ "Dortm. 3", 4, 2, 1 },
{ "Dtmd-Sc.", 4, 2, 49 },
{ "Duess.10", 2, 2, 88 },
{ "Duess.12", 2, 2, 27 },
{ "Duess.27", 2, 2, 38 },
{ "Duess.30", 2, 2, 12 },
{ "Duess. 4", 2, 2, 24 },
{ "Dues.FZA", 2, 2, 39 },
{ "Duisb.0", 1, 2, 35 },
{ "Duisb.21", 1, 2, 8 },
{ "Duisb.25", 1, 2, 16 },
{ "Elten", 3, 2, 30 },
{ "Erftstd.", 6, 2, 12 },
{ "Erkelenz", 3, 2, 54 },
{ "Eschenb.", 7, 2, 24 },
{ "Eschwei2", 3, 2, 48 },
{ "Essen 13", 1, 2, 31 },
{ "Essen 15", 1, 2, 32 },
{ "Essen 28", 1, 2, 19 },
{ "Essen 35", 1, 2, 15 },
{ "Essen Ke", 1, 2, 76 },
{ "Euskir.4", 7, 2, 32 },
{ "Frechen", 6, 2, 81 },
{ "Geilenki", 3, 2, 57 },
{ "Geldern", 3, 2, 31 },
{ "Gelsenk1", 1, 2, 14 },
{ "Gelsenk7", 1, 2, 21 },
{ "Gevelsb.", 4, 2, 12 },
{ "Greven 0", 5, 2, 43 },
{ "Grev.br.", 3, 2, 79 },
{ "Grev.Ka.", 3, 2, 11 },
{ "Gumme.13", 7, 2, 97 },
{ "Hagen 2", 4, 2, 13 },
{ "Hallenb.", 5, 2, 26 },
{ "Haltern", 5, 2, 3 },
{ "Hamm", 4, 2, 40 },
{ "Hlg.haus", 1, 2, 9 },
{ "Heinsbg2", 3, 2, 58 },
{ "Herne 1", 4, 2, 18 },
{ "Hersch.1", 5, 2, 94 },
{ "Hilden 6", 2, 2, 26 },
{ "Hoehr-G.", 7, 2, 15 },
{ "Holzwi.", 4, 2, 25 },
{ "Huertgwd", 3, 2, 25 },
{ "Huerth", 6, 2, 67 },
{ "Iserlohn", 4, 2, 36 },
{ "Juechen4", 3, 2, 44 },
{ "Juelich3", 3, 2, 59 },
{ "Kamen", 4, 2, 38 },
{ "Kleve 7", 3, 2, 29 },
{ "Kobl. 10", 7, 2, 14 },
{ "Koeln 0", 6, 2, 5 },
{ "Kln. 23", 6, 2, 70 },
{ "Kln. 25", 6, 2, 23 },
{ "Kln. 170", 6, 2, 22 },
{ "Kln. 370", 6, 2, 24 },
{ "Kln. 430", 6, 2, 25 },
{ "Kln. 640", 6, 2, 27 },
{ "Kln. 760", 6, 2, 26 },
{ "Kln. 790", 6, 2, 8 },
{ "Kln. 850", 6, 2, 28 },
{ "Koeln 8", 6, 2, 6 },
{ "Koen./Ob", 7, 2, 3 },
{ "Krefe.19", 3, 2, 2 },
{ "Krefeld4", 3, 2, 69 },
{ "Kreuztal", 7, 2, 41 },
{ "Kuerten1", 7, 2, 34 },
{ "Kuerten3", 7, 2, 30 },
{ "Lennestd", 7, 2, 40 },
{ "Lethma.7", 4, 2, 29 },
{ "Leverk.0", 6, 2, 91 },
{ "Lev.Opl.", 2, 2, 41 },
{ "Lippstad", 5, 2, 8 },
{ "Lohmar 1", 7, 2, 98 },
{ "Luedens.", 5, 2, 30 },
{ "Luedhs.", 5, 2, 21 },
{ "Luenen 0", 4, 2, 33 },
{ "Marl 0", 5, 2, 4 },
{ "Meerbu.B", 2, 2, 37 },
{ "Menden11", 4, 2, 37 },
{ "Merten", 6, 2, 9 },
{ "Meschede", 5, 2, 22 },
{ "Mettm. 2", 2, 2, 66 },
{ "Moehnes.", 5, 2, 24 },
{ "Mgldb. 3", 3, 2, 4 },
{ "Mgldb. 7", 3, 2, 45 },
{ "Moers 0", 3, 2, 32 },
{ "Muens.Al", 5, 2, 41 },
{ "Muens.42", 5, 2, 6 },
{ "Nehm.Hu.", 5, 2, 5 },
{ "Meinerzh", 5, 2, 32 },
{ "Nettersh", 3, 2, 62 },
{ "Nettetal", 3, 2, 40 },
{ "Neukir.6", 3, 2, 65 },
{ "NeussNor", 2, 2, 11 },
{ "Neuss 8", 2, 2, 23 },
{ "Neuss 14", 2, 2, 10 },
{ "Nd.Kass.", 6, 2, 4 },
{ "Nordkir3", 5, 2, 44 },
{ "Nottuln2", 5, 2, 36 },
{ "Oberh. 1", 1, 2, 68 },
{ "Oberh.16", 1, 2, 12 },
{ "Oberh.21", 1, 2, 7 },
{ "Oberh.25", 1, 2, 37 },
{ "Oberh. 9", 1, 2, 89 },
{ "Oelde 2", 5, 2, 40 },
{ "Overath5", 7, 2, 1 },
{ "Plettenb", 5, 2, 34 },
{ "Porz 50", 6, 2, 15 },
{ "Pulheim", 6, 2, 14 },
{ "Ratingen", 2, 2, 20 },
{ "Recklhs.", 4, 2, 74 },
{ "Remsch.4", 2, 2, 34 },
{ "Roesr.Na", 6, 2, 68 },
{ "Rommersk", 6, 2, 20 },
{ "Schleidn", 3, 2, 56 },
{ "Schm.Bo.", 5, 2, 25 },
{ "Schoepp.", 5, 2, 93 },
{ "Schwalmt", 3, 2, 43 },
{ "Schwerte", 4, 2, 73 },
{ "Sendenh.", 5, 2, 18 },
{ "Siegen 1", 7, 2, 96 },
{ "Siegb.20", 7, 2, 2 },
{ "Simmerat", 3, 2, 61 },
{ "Soling.", 2, 2, 43 },
{ "Stolbg.2", 3, 2, 46 },
{ "Stolbg.3", 3, 2, 47 },
{ "Straelen", 3, 2, 64 },
{ "Sundern1", 5, 2, 55 },
{ "Telgte 0", 5, 2, 37 },
{ "Velbert1", 1, 2, 36 },
{ "Velb.La.", 1, 2, 11 },
{ "Velb.Ne.", 1, 2, 17 },
{ "Vettels.", 7, 2, 17 },
{ "Viersen1", 3, 2, 42 },
{ "Viersen4", 3, 2, 5 },
{ "Weibern2", 7, 2, 18 },
{ "Weilers.", 7, 2, 77 },
{ "Werdohl7", 5, 2, 35 },
{ "Werl-Rf.", 5, 2, 23 },
{ "Werne", 4, 2, 39 },
{ "Wesel", 3, 2, 28 },
{ "Wesseli.", 6, 2, 66 },
{ "Willich", 3, 2, 71 },
{ "Windeck2", 7, 2, 37 },
{ "Witten10", 4, 2, 31 },
{ "Witten12", 4, 2, 14 },
{ "Wupp. 2", 1, 2, 99 },
{ "Wupp. 23", 1, 2, 34 },
{ "Wupp. 30", 1, 2, 18 },
{ "Wupp.No.", 1, 2, 22 },
{ "Xanten 1", 3, 2, 27 },
{ "Chemn-9-", 5, 3, 5 },
{ "Zwick-9-", 5, 3, 4 },
{ "Biens-6-", 5, 3, 2 },
{ "Warth-6-", 5, 3, 3 },
{ "Leipz-5-", 2, 3, 98 },
{ "Peter-5-", 3, 3, 1 },
{ "Gompi-5-", 4, 3, 1 },
{ "Schwe-4-", 1, 3, 4 },
{ "Alt-b-4-", 1, 3, 8 },
{ "Graeb-4-", 1, 3, 9 },
{ "Phoeb-4-", 1, 3, 10 },
{ "Recka-4-", 1, 3, 11 },
{ "B.AltMoa", 2, 3, 4 },
{ "B.August", 2, 3, 14 },
{ "B.Coppis", 2, 3, 49 },
{ "B.Erasmu", 2, 3, 9 },
{ "B.FranzJ", 2, 3, 29 },
{ "B.Frohna", 2, 3, 2 },
{ "B.Forsts", 2, 3, 21 },
{ "B.Hannem", 2, 3, 18 },
{ "B.Herzbe", 2, 3, 59 },
{ "B.Hinden", 2, 3, 22 },
{ "B.Karl-M", 2, 3, 12 },
{ "B.Karlsh", 2, 3, 97 },
{ "B.Kettin", 2, 3, 20 },
{ "B.Lieber", 2, 3, 58 },
{ "B.Lobeck", 2, 3, 23 },
{ "B.Lueder", 2, 3, 8 },
{ "B.Masure", 2, 3, 60 },
{ "B.Oranie", 2, 3, 13 },
{ "B.PGiroA", 2, 3, 1 },
{ "B.Prenzl", 2, 3, 57 },
{ "B.Rathau", 2, 3, 15 },
{ "B.Rochst", 2, 3, 40 },
{ "B.Ruegen", 2, 3, 3 },
{ "B.Schaef", 2, 3, 99 },
{ "B.Schmar", 2, 3, 16 },
{ "B.Scholz", 2, 3, 61 },
{ "B.Skalit", 2, 3, 7 },
{ "B.Streit", 2, 3, 19 },
{ "B.Strese", 2, 3, 5 },
{ "B.Tempel", 2, 3, 17 },
{ "B.Werner", 2, 3, 11 },
{ "B.Wilh.-", 2, 3, 36 },
{ "B.Wilkes", 2, 3, 6 },
{ "B.Winter", 2, 3, 10 },
{ "Birkholz", 2, 3, 44 },
{ "Hamberge", 1, 3, 3 },
{ "Hayn", 5, 3, 1 },
{ "Rostock", 1, 3, 2 },
{ "Stralsun", 1, 3, 1 },
{ "B.Segebg", 1, 4, 95 },
{ "Bredst.3", 1, 4, 24 },
{ "Bremen38", 1, 4, 6 },
{ "Bremerh.", 1, 4, 21 },
{ "Brm. 0", 1, 4, 31 },
{ "Brm. 80", 1, 4, 40 },
{ "Walle", 1, 4, 67 },
{ "Woltmers", 1, 4, 68 },
{ "Huckelri", 1, 4, 70 },
{ "Hochh.Wi", 1, 4, 71 },
{ "Findorff", 1, 4, 37 },
{ "Tenever", 1, 4, 42 },
{ "Kloecknr", 1, 4, 74 },
{ "HochDuen", 1, 4, 75 },
{ "Berne 0", 1, 4, 85 },
{ "Bremervo", 1, 4, 87 },
{ "Delmenho", 1, 4, 39 },
{ "Edewecht", 1, 4, 84 },
{ "Friesoyt", 1, 4, 93 },
{ "GrKneten", 1, 4, 49 },
{ "Grolland", 1, 4, 69 },
{ "Hatten10", 1, 4, 79 },
{ "Hude 0", 1, 4, 45 },
{ "Ippener0", 1, 4, 77 },
{ "Kirchtim", 1, 4, 80 },
{ "Lilienth", 1, 4, 43 },
{ "Oldenbu0", 1, 4, 48 },
{ "Oldenbu1", 1, 4, 47 },
{ "Osterhol", 1, 4, 88 },
{ "Ritterhu", 1, 4, 38 },
{ "Varel 1", 1, 4, 92 },
{ "Weyhe 0", 1, 4, 41 },
{ "Wildesha", 1, 4, 90 },
{ "Brunsbue", 1, 4, 30 },
{ "Cuxhaven", 1, 4, 5 },
{ "Egestorf", 1, 4, 54 },
{ "Fleckeby", 1, 4, 12 },
{ "Freienw.", 1, 4, 19 },
{ "Heesl.B.", 1, 4, 9 },
{ "Heide 2", 1, 4, 22 },
{ "Helgolan", 1, 4, 97 },
{ "Hemmoor1", 1, 4, 4 },
{ "Hens.Ul.", 1, 4, 55 },
{ "Hoya 1", 1, 4, 8 },
{ "Jever 0", 1, 4, 15 },
{ "Kappeln", 1, 4, 96 },
{ "Kiel 2", 1, 4, 11 },
{ "Krum.Gr.", 1, 4, 26 },
{ "Leer 1", 1, 4, 25 },
{ "Luebeck", 1, 4, 56 },
{ "Luenebg.", 1, 4, 51 },
{ "Norden 0", 1, 4, 65 },
{ "Schoenw.", 1, 4, 57 },
{ "Schwarzb", 1, 4, 59 },
{ "Vechta L", 1, 4, 14 },
{ "Ahrens11", 2, 4, 60 },
{ "Bassum 3", 1, 4, 29 },
{ "Buxtehud", 2, 4, 2 },
{ "Elmshorn", 2, 4, 51 },
{ "FernVHmb", 2, 4, 33 },
{ "Finkenwd", 2, 4, 38 },
{ "Rosenga.", 2, 4, 49 },
{ "Seevetal", 2, 4, 48 },
{ "Garding1", 1, 4, 81 },
{ "Hamberg.", 1, 4, 28 },
{ "Hambg 22", 2, 4, 1 },
{ "HH FA 4", 2, 4, 53 },
{ "HH FHS", 2, 4, 32 },
{ "HH 105", 2, 4, 30 },
{ "HH 24", 2, 4, 50 },
{ "HH Alton", 2, 4, 31 },
{ "Barsbuet", 2, 4, 17 },
{ "Harburg", 2, 4, 13 },
{ "HH Modez", 2, 4, 35 },
{ "HH Hohel", 2, 4, 34 },
{ "HH Phi.M", 2, 4, 65 },
{ "NeuWulms", 2, 4, 47 },
{ "Poppenbu", 2, 4, 16 },
{ "HH PostA", 2, 4, 27 },
{ "HH Radow", 2, 4, 66 },
{ "SAGA A.B", 2, 4, 37 },
{ "Stade", 1, 4, 60 },
{ "Suederlu", 1, 4, 76 },
{ "Wedel 9", 1, 4, 64 },
{ "Hamm 25", 2, 4, 42 },
{ "Harsefld", 2, 4, 57 },
{ "Henstedt", 1, 4, 23 },
{ "Husum 0", 1, 4, 66 },
{ "Marne 0", 1, 4, 72 },
{ "Norderst", 2, 4, 52 },
{ "Osterjor", 1, 4, 63 },
{ "Pinnebg", 1, 4, 61 },
{ "Ratzebur", 1, 4, 58 },
{ "Rotenbu.", 2, 4, 41 },
{ "Reinfeld", 1, 4, 3 },
{ "Rendsbur", 1, 4, 17 },
{ "Steilho.", 2, 4, 43 },
{ "Travemue", 1, 4, 10 },
{ "VerdenWa", 1, 4, 7 },
{ "Waltersh", 2, 4, 39 },
{ "Wangerla", 1, 4, 89 },
{ "Westerl.", 1, 4, 20 },
{ "Wilhelms", 2, 4, 40 },
{ "Winsen 0", 2, 4, 58 },
{ "Wittsmoo", 2, 4, 62 },
{ "Bars.hs.", 2, 5, 2 },
{ "B.Pyrmon", 1, 5, 9 },
{ "B.Iburg", 1, 5, 26 },
{ "B.Benth2", 1, 5, 30 },
{ "Bergen 1", 2, 5, 3 },
{ "Bielef.1", 1, 5, 92 },
{ "Bram.En.", 1, 5, 12 },
{ "Brauns.3", 2, 5, 9 },
{ "Burgdorf", 2, 5, 68 },
{ "Burgwed.", 2, 5, 35 },
{ "Celle", 2, 5, 4 },
{ "Damme", 1, 5, 61 },
{ "DissenTW", 1, 5, 27 },
{ "Einbeck2", 2, 5, 94 },
{ "Eschwege", 2, 5, 73 },
{ "Fuersten", 1, 5, 29 },
{ "Garbsen", 2, 5, 33 },
{ "Gartow", 2, 5, 23 },
{ "Goett. 2", 2, 5, 14 },
{ "Goslar41", 2, 5, 41 },
{ "Grabow", 2, 5, 19 },
{ "Grossal.", 2, 5, 18 },
{ "Guetersl", 1, 5, 21 },
{ "Hameln10", 2, 5, 49 },
{ "Harsewin", 1, 5, 22 },
{ "Hann-Mu.", 2, 5, 54 },
{ "H. 2", 2, 5, 28 },
{ "H. 4 Mba", 2, 5, 26 },
{ "H. Messe", 2, 5, 62 },
{ "H. OPD", 2, 5, 27 },
{ "H.Studen", 2, 5, 29 },
{ "H.UniApp", 2, 5, 32 },
{ "H.Linden", 2, 5, 30 },
{ "H.UniHan", 2, 5, 31 },
{ "Helmst.", 2, 5, 51 },
{ "Herzberg", 2, 5, 53 },
{ "Hoevelhf", 1, 5, 24 },
{ "Ibbenb.", 1, 5, 11 },
{ "Irxleben", 2, 5, 88 },
{ "Kassel", 2, 5, 72 },
{ "Korbach", 2, 5, 78 },
{ "Langenhn", 2, 5, 86 },
{ "Lehrte", 2, 5, 37 },
{ "Lemgo", 1, 5, 25 },
{ "Lindern", 1, 5, 19 },
{ "Lindsbg.", 2, 5, 60 },
{ "Lingen", 1, 5, 17 },
{ "Luebbe.", 1, 5, 16 },
{ "Luedge-R", 1, 5, 10 },
{ "MelleBue", 1, 5, 28 },
{ "Melsung5", 2, 5, 75 },
{ "Meppen", 1, 5, 62 },
{ "Minden", 1, 5, 95 },
{ "Mori.Fr.", 2, 5, 15 },
{ "Munster1", 2, 5, 65 },
{ "Oerlingh", 1, 5, 20 },
{ "Paderbor", 1, 5, 23 },
{ "Peine", 2, 5, 6 },
{ "Rheine", 1, 5, 63 },
{ "Ronnebg.", 2, 5, 39 },
{ "Salzgitt", 2, 5, 67 },
{ "Salzh.df", 2, 5, 5 },
{ "Sarstedt", 2, 5, 38 },
{ "Schnever", 2, 5, 10 },
{ "Schoeneb", 2, 5, 58 },
{ "Seesen 1", 2, 5, 69 },
{ "Sibbesse", 2, 5, 7 },
{ "Sontra", 2, 5, 74 },
{ "Spraken.", 2, 5, 12 },
{ "Uelzen 3", 2, 5, 76 },
{ "Walsrode", 2, 5, 40 },
{ "Wedemark", 2, 5, 34 },
{ "Willeb.", 2, 5, 17 },
{ "Wolfsb.", 2, 5, 11 },
{ "Zernien", 2, 5, 22 },
{ "Zierenb.", 2, 5, 16 },
{ "Aarberg1", 3, 6, 43 },
{ "Aarberg3", 3, 6, 44 },
{ "Alsfeld1", 3, 6, 39 },
{ "Altenstd", 3, 6, 40 },
{ "Alzey", 3, 6, 12 },
{ "Annweile", 1, 6, 11 },
{ "Aschaf11", 3, 6, 90 },
{ "Babenhs3", 3, 6, 42 },
{ "B.Cambg3", 3, 6, 87 },
{ "B.Duerkh", 1, 6, 88 },
{ "B.Hersf2", 3, 6, 32 },
{ "B.Kreuz.", 1, 6, 30 },
{ "B.Schwa2", 3, 6, 45 },
{ "B.Soden", 2, 6, 36 },
{ "B.Vilbel", 2, 6, 54 },
{ "Benshm 0", 1, 6, 3 },
{ "Benshm13", 1, 6, 55 },
{ "Bernkas.", 1, 6, 25 },
{ "Biebert.", 3, 6, 27 },
{ "Bitburg", 1, 6, 38 },
{ "Boppard", 1, 6, 32 },
{ "Brensbac", 3, 6, 51 },
{ "Darmst.2", 3, 6, 23 },
{ "Dieburg0", 3, 6, 41 },
{ "Dieburg2", 3, 6, 6 },
{ "Eberbach", 1, 6, 7 },
{ "Ebersbg2", 3, 6, 35 },
{ "Eppstein", 3, 6, 26 },
{ "FFM Ber.", 2, 6, 49 },
{ "FFM Dan.", 2, 6, 43 },
{ "FFM Dis.", 2, 6, 50 },
{ "FFM Flug", 2, 6, 56 },
{ "FFM Gie.", 2, 6, 41 },
{ "FFM Kle.", 2, 6, 51 },
{ "FFM Lyo.", 2, 6, 52 },
{ "FFM Oes.", 2, 6, 53 },
{ "FFM Orb.", 2, 6, 55 },
{ "FFM Rai.", 2, 6, 40 },
{ "FFM Roe.", 2, 6, 39 },
{ "FFM Ste.", 2, 6, 45 },
{ "FFM Zeil", 2, 6, 38 },
{ "Floersh.", 3, 6, 22 },
{ "Frankent", 1, 6, 86 },
{ "Frankf16", 2, 6, 1 },
{ "Friedbg.", 3, 6, 2 },
{ "Fulda 3", 3, 6, 31 },
{ "Gelnhs.", 3, 6, 4 },
{ "Gerolste", 1, 6, 41 },
{ "Giessen0", 3, 6, 61 },
{ "Giessen3", 3, 6, 62 },
{ "Gruenstd", 1, 6, 87 },
{ "Gunt.bl.", 1, 6, 13 },
{ "Haina,K.", 3, 6, 29 },
{ "Hanau 1", 3, 6, 21 },
{ "Hanau 7", 3, 6, 24 },
{ "Hatters.", 2, 6, 46 },
{ "Heusw.", 1, 6, 35 },
{ "Idar-Ob.", 1, 6, 34 },
{ "Idstein", 3, 6, 84 },
{ "Igstadt", 3, 6, 7 },
{ "Kaisersl", 1, 6, 15 },
{ "Kelkh.", 2, 6, 47 },
{ "Kell", 1, 6, 23 },
{ "K.Heidel", 1, 6, 64 },
{ "K.Ladenb", 1, 6, 67 },
{ "K.Lampre", 1, 6, 68 },
{ "K.Landau", 1, 6, 63 },
{ "K.Ludwig", 1, 6, 61 },
{ "K.M.Diak", 1, 6, 72 },
{ "K.M.Gros", 1, 6, 73 },
{ "K.M.Kaef", 1, 6, 77 },
{ "K.M.Lade", 1, 6, 71 },
{ "K.M.Maim", 1, 6, 75 },
{ "K.M.Oelf", 1, 6, 76 },
{ "K.M.Wein", 1, 6, 74 },
{ "K.Neuhof", 1, 6, 70 },
{ "K.NeustW", 1, 6, 60 },
{ "K.Pfeiff", 1, 6, 69 },
{ "K.Schwet", 1, 6, 66 },
{ "K.Speyer", 1, 6, 62 },
{ "K.Viernh", 1, 6, 78 },
{ "Koenigs.", 2, 6, 42 },
{ "Konken 3", 1, 6, 17 },
{ "Kronberg", 2, 6, 37 },
{ "Lambrech", 1, 6, 8 },
{ "Langen", 2, 6, 8 },
{ "Lauterb1", 3, 6, 36 },
{ "Lebach 3", 1, 6, 47 },
{ "Limburg", 3, 6, 54 },
{ "Lindenfs", 1, 6, 4 },
{ "Lorch 3", 3, 6, 68 },
{ "Lorch 4", 3, 6, 71 },
{ "Mannh. 4", 1, 6, 99 },
{ "Mannh205", 1, 6, 97 },
{ "Marburg", 3, 6, 28 },
{ "Mz 4 Uni", 3, 6, 17 },
{ "Mz 26Lau", 3, 6, 18 },
{ "Mz 3", 3, 6, 16 },
{ "Mz 5 Fin", 3, 6, 19 },
{ "Mz Kaste", 3, 6, 20 },
{ "Merzig 3", 1, 6, 46 },
{ "Mettl.M.", 1, 6, 80 },
{ "Michelst", 3, 6, 59 },
{ "Moerfld6", 2, 6, 9 },
{ "MosbachB", 1, 6, 6 },
{ "Mudau 1", 1, 6, 14 },
{ "Neu Ise.", 2, 6, 44 },
{ "Neuenst.", 3, 6, 34 },
{ "Neunki.", 1, 6, 79 },
{ "Oberurs.", 2, 6, 48 },
{ "Off.Jah.", 2, 6, 61 },
{ "Off.Kra.", 2, 6, 79 },
{ "Oppenhei", 3, 6, 47 },
{ "Pirmas.", 1, 6, 16 },
{ "Pruem", 1, 6, 26 },
{ "Pfungsta", 3, 6, 50 },
{ "Rodgau", 2, 6, 10 },
{ "Ruedesh.", 1, 6, 31 },
{ "Ruessel.", 3, 6, 85 },
{ "Ruessel3", 3, 6, 15 },
{ "Saarbr.1", 1, 6, 36 },
{ "SaarbrWi", 1, 6, 37 },
{ "Saarburg", 1, 6, 40 },
{ "Schlange", 3, 6, 46 },
{ "Schluec.", 3, 6, 33 },
{ "Schotten", 3, 6, 3 },
{ "Seeheim2", 1, 6, 5 },
{ "Seligen.", 3, 6, 25 },
{ "Selters3", 3, 6, 86 },
{ "Sob.Eck.", 1, 6, 33 },
{ "Sulzbh10", 1, 6, 48 },
{ "Taunusst", 3, 6, 60 },
{ "Trier", 1, 6, 22 },
{ "Voelklin", 1, 6, 49 },
{ "Wallau", 3, 6, 81 },
{ "Weidenth", 1, 6, 9 },
{ "Weilburg", 3, 6, 30 },
{ "Westhofn", 1, 6, 2 },
{ "WI S.d.R", 3, 6, 83 },
{ "Wi K.A.R", 3, 6, 82 },
{ "Wi 1", 3, 6, 11 },
{ "Wilh.fel", 1, 6, 12 },
{ "Worms 4", 1, 6, 10 },
{ "Worms 7", 1, 6, 1 },
{ "Zweibrue", 1, 6, 82 },
{ "Bad-Bad5", 3, 7, 1 },
{ "Albst.L1", 1, 7, 2 },
{ "Albst.E2", 1, 7, 6 },
{ "Allensb1", 1, 7, 31 },
{ "Altenst2", 1, 7, 43 },
{ "Backna43", 1, 7, 38 },
{ "Badenwei", 3, 7, 4 },
{ "Balingen", 1, 7, 8 },
{ "Balingn2", 1, 7, 26 },
{ "B.Mergen", 1, 7, 24 },
{ "B.Rappen", 3, 7, 18 },
{ "B.Schuss", 1, 7, 35 },
{ "B.Urach2", 2, 7, 17 },
{ "B.Wimpfe", 1, 7, 57 },
{ "B.Wurzac", 1, 7, 61 },
{ "Besighei", 1, 7, 52 },
{ "Beuron 1", 1, 7, 1 },
{ "Biberbac", 1, 7, 92 },
{ "Blaube41", 1, 7, 83 },
{ "Blaustei", 1, 7, 80 },
{ "Bodmann3", 1, 7, 19 },
{ "Brackenh", 1, 7, 53 },
{ "Bretten3", 3, 7, 68 },
{ "Buehl Ba", 3, 7, 90 },
{ "Calw 3", 2, 7, 44 },
{ "Crailsh.", 1, 7, 25 },
{ "Deggenh.", 1, 7, 13 },
{ "Deggin71", 1, 7, 73 },
{ "Denkend.", 2, 7, 63 },
{ "Denzling", 3, 7, 30 },
{ "Donauesc", 1, 7, 15 },
{ "Ehingen1", 1, 7, 89 },
{ "Eigeltin", 3, 7, 75 },
{ "Ehningen", 2, 7, 92 },
{ "Emmendin", 3, 7, 36 },
{ "Eppingen", 3, 7, 17 },
{ "Erbach41", 1, 7, 86 },
{ "Ettenhei", 3, 7, 24 },
{ "Forchten", 1, 7, 56 },
{ "FreibuBr", 3, 7, 29 },
{ "Freudens", 3, 7, 97 },
{ "Friedric", 1, 7, 37 },
{ "Ammerbuc", 1, 7, 30 },
{ "Gomading", 2, 7, 23 },
{ "Gaggenau", 3, 7, 14 },
{ "Guenzb70", 1, 7, 59 },
{ "Baiersb.", 1, 7, 7 },
{ "Haigerlo", 1, 7, 54 },
{ "Hausach", 3, 7, 8 },
{ "Heching6", 1, 7, 29 },
{ "Heidenh2", 1, 7, 4 },
{ "HeilbrN1", 1, 7, 51 },
{ "Heilbr41", 1, 7, 48 },
{ "Heiligen", 1, 7, 94 },
{ "Heubach", 1, 7, 96 },
{ "Illertis", 1, 7, 91 },
{ "Isny 0", 1, 7, 71 },
{ "Karlsbad", 3, 7, 92 },
{ "Kirchhar", 3, 7, 19 },
{ "Kirchhei", 2, 7, 90 },