Refactoring validity check and prefix processing of dialed number

Command line help shows how many digits and what prefixes can be dialed.

Giving a station ID via command line will be checked for being valid.

The number to call the mobile statione will be checked for being valid.

Prefixes that are defined for a nework will be removed from station ID
automatically.

Multiple station ID lengths are supported:
 * C-Netz: 7 or 8 digits, depending on area code length
 * A-Netz: 5 or 7 digits; number is truncated to last 5 digits.
 * IMTS/MTS: 5 or 7 digits, depending on phone's selector switch.
pull/1/head
Andreas Eversberg 1 year ago
parent 3a73f31d7e
commit 423bc42429
  1. 24
      src/amps/amps.c
  2. 19
      src/amps/amps_tacs_main.c
  3. 7
      src/amps/main.c
  4. 2
      src/amps/main.h
  5. 59
      src/anetz/anetz.c
  6. 1
      src/anetz/anetz.h
  7. 22
      src/anetz/main.c
  8. 20
      src/bnetz/bnetz.c
  9. 24
      src/bnetz/main.c
  10. 58
      src/cnetz/cnetz.c
  11. 1
      src/cnetz/cnetz.h
  12. 30
      src/cnetz/main.c
  13. 28
      src/eurosignal/eurosignal.c
  14. 61
      src/eurosignal/main.c
  15. 57
      src/fuvst/fuvst.c
  16. 1
      src/fuvst/fuvst.h
  17. 27
      src/fuvst/main.c
  18. 5
      src/fuvst/sniffer.c
  19. 49
      src/imts/imts.c
  20. 4
      src/imts/imts.h
  21. 51
      src/imts/main.c
  22. 12
      src/jolly/jolly.c
  23. 20
      src/jolly/main.c
  24. 3
      src/jtacs/main.c
  25. 54
      src/libmobile/call.c
  26. 61
      src/libmobile/console.c
  27. 2
      src/libmobile/console.h
  28. 169
      src/libmobile/main_mobile.c
  29. 18
      src/libmobile/main_mobile.h
  30. 22
      src/mpt1327/main.c
  31. 47
      src/mpt1327/mpt1327.c
  32. 1
      src/mpt1327/mpt1327.h
  33. 20
      src/nmt/main.c
  34. 8
      src/nmt/nmt.c
  35. 17
      src/r2000/main.c
  36. 60
      src/r2000/r2000.c
  37. 1
      src/r2000/r2000.h
  38. 7
      src/tacs/main.c
  39. 4
      src/test/test_dms.c
  40. 4
      src/test/test_sms.c
  41. 11
      src/zeitansage/main.c

@ -893,30 +893,8 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
transaction_t *trans;
uint32_t min1;
uint16_t min2;
int i;
/* 1. check if number is invalid, return INVALNUMBER */
if (!tacs) {
if (strlen(dialing) == 12 && !strncmp(dialing, "+1", 2))
dialing += 2;
if (strlen(dialing) == 11 && !strncmp(dialing, "1", 1))
dialing += 1;
} else if (!jtacs) {
if (strlen(dialing) == 14 && !strncmp(dialing, "+44", 3))
dialing += 3;
if (strlen(dialing) == 11 && !strncmp(dialing, "0", 1))
dialing += 1;
}
if (strlen(dialing) != 10) {
inval:
PDEBUG(DAMPS, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
for (i = 0; i < 10; i++) {
if (dialing[i] < '0' || dialing[i] > '9')
goto inval;
}
/* 1. split number into area code and number */
amps_number2min(dialing, &min1, &min2);
/* 2. check if the subscriber is attached */

@ -99,8 +99,7 @@ void print_help(const char *arg0)
printf(" If 1, be sure to have a round-trip delay (latency) not more than 5 ms\n");
printf(" -O --tolerant\n");
printf(" Be more tolerant when hunting for sync sequence\n");
printf("\nstation-id: Give 10 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();
}
@ -227,6 +226,11 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
static const struct number_lengths number_lengths[] = {
{ 10, "AMPS number" },
{ 0, NULL }
};
int main_amps_tacs(const char *name, int argc, char *argv[])
{
int rc, argi;
@ -237,7 +241,7 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
/* override default */
dsp_samplerate = 96000;
main_mobile_init();
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
/* handle options / config file */
add_options();
@ -257,10 +261,9 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 10) {
printf("Given station ID '%s' does not have 10 digits\n", station_id);
return 0;
}
rc = main_mobile_number_ask(station_id, "station ID");
if (rc)
return rc;
}
if (!num_kanal) {
@ -392,7 +395,7 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
printf("Base station on channel %s ready (%s), please tune transmitter to %.4f MHz and receiver to %.4f MHz. (%.3f MHz offset)\n", kanal[i], chan_type_long_name(chan_type[i]), amps_channel2freq(atoi(kanal[i]), 0) / 1e6, amps_channel2freq(atoi(kanal[i]), 1) / 1e6, amps_channel2freq(atoi(kanal[i]), 2) / 1e6);
}
main_mobile(name, &quit, NULL, station_id, 10);
main_mobile_loop(name, &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -1,3 +1,4 @@
#include <stdio.h>
#include "main.h"
#include "tones.h"
#include "noanswer.h"
@ -8,6 +9,12 @@
const int tacs = 0;
const int jtacs = 0;
const char *number_prefixes[] = {
"1xxxxxxxxxx",
"+1xxxxxxxxxx",
NULL
};
int main(int argc, char *argv[])
{
/* init common tones */

@ -2,5 +2,7 @@
extern const int tacs;
extern const int jtacs;
extern const char *number_prefixes[];
int main_amps_tacs(const char *name, int argc, char *argv[]);

@ -125,29 +125,19 @@ static struct anetz_dekaden {
{ { 1, 2, 2, 2 } }, /* 9 */
};
/* Takes the last 5 digits of a number and returns 4 paging tones.
/* Takes the 5 digits of a number and returns 4 paging tones.
If number is invalid, NULL is returned. */
static char anetz_nummer2freq_error[256];
static double *anetz_nummer2freq(const char *nummer)
{
int f[4];
static double freq[4];
int *dekade;
int i, j, digit;
int i, digit;
/* get last 5 digits */
if (strlen(nummer) < 5) {
PDEBUG(DANETZ, DEBUG_ERROR, "Number must have at least 5 digits!\n");
return NULL;
}
nummer = nummer + strlen(nummer) - 5;
/* check for digits */
for (i = 0; i < 4; i++) {
if (nummer[i] < '0' || nummer[i] > '9') {
PDEBUG(DANETZ, DEBUG_ERROR, "Number must have digits 0..9!\n");
return NULL;
}
}
/* skip prefix */
if (strlen(nummer) == 7)
nummer += 2;
/* get decade */
dekade = anetz_gruppenkennziffer[*nummer - '0'].dekade;
@ -161,18 +151,35 @@ static double *anetz_nummer2freq(const char *nummer)
digit = 10;
f[i] = (dekade[i] - 1) * 10 + digit;
freq[i] = anetz_dauerruf_frq(f[i]);
for (j = 0; j < i; j++) {
if (dekade[i] == dekade[j] && nummer[i] == nummer[j]) {
PDEBUG(DANETZ, DEBUG_NOTICE, "Number invalid, digit #%d and #%d of '%s' use same frequency F%d=%.1f of same decade %d!\n", i+1, j+1, nummer, f[i], freq[i], dekade[i]);
return NULL;
}
}
/* check if any frequency is used twice */
for (i = 0; i < 3; i++) {
if (dekade[i] == dekade[i + 1] && nummer[i] == nummer[i + 1]) {
sprintf(anetz_nummer2freq_error, "Digit #%d and #%d of '%s' use same frequency F%d=%.1f of same decade %d.", i + 1, i + 2, nummer, f[i], freq[i], dekade[i]);
return NULL;
}
}
PDEBUG(DANETZ, DEBUG_DEBUG, "Frequencies: F%d=%.1f F%d=%.1f F%d=%.1f F%d=%.1f\n", f[0], freq[0], f[1], freq[1], f[2], freq[2], f[3], freq[3]);
return freq;
}
/* check if number is a valid station ID */
const char *anetz_number_valid(const char *number)
{
double *freq;
/* assume that the number has valid length(s) and digits */
freq = anetz_nummer2freq(number);
if (!freq)
return anetz_nummer2freq_error;
return NULL;
}
/* global init */
int anetz_init(void)
{
@ -381,15 +388,13 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
anetz_t *anetz;
double *freq;
/* 1. check if number is invalid, return INVALNUMBER */
if (strlen(dialing) > 7) {
inval:
/* 1. determine paging frequencies */
freq = anetz_nummer2freq(dialing);
if (!freq) {
PDEBUG(DANETZ, DEBUG_NOTICE, "Number invalid: %s\n", anetz_nummer2freq_error);
PDEBUG(DANETZ, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
freq = anetz_nummer2freq(dialing);
if (!freq)
goto inval;
/* 2. check if given number is already in a call, return BUSY */
for (sender = sender_head; sender; sender = sender->next) {

@ -53,6 +53,7 @@ typedef struct anetz {
double anetz_kanal2freq(int kanal, int unterband);
const char *anetz_number_valid(const char *number);
int anetz_init(void);
int anetz_create(const char *kanal, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, double page_gain, int page_sequence, 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, double squelch_db, const char *operator);
void anetz_destroy(sender_t *sender);

@ -65,8 +65,7 @@ void print_help(const char *arg0)
printf(" and stays below this level, the connection is released.\n");
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
printf(" Only works with SDR! (disabled by default)\n");
printf("\nstation-id: Give (last) 5 digits of station-id, you don't need to enter it\n");
printf(" for every start of this program.\n");
main_mobile_print_station_id();
main_mobile_print_hotkeys();
}
@ -121,6 +120,12 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
static const struct number_lengths number_lengths[] = {
{ 5, "number without channel prefix" },
{ 7, "number with channel prefix" },
{ 0, NULL }
};
int main(int argc, char *argv[])
{
int rc, argi;
@ -134,7 +139,7 @@ int main(int argc, char *argv[])
init_freiton();
init_besetzton();
main_mobile_init();
main_mobile_init("0123456789", number_lengths, NULL, anetz_number_valid);
/* handle options / config file */
add_options();
@ -147,12 +152,9 @@ int main(int argc, char *argv[])
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 5 && strlen(station_id) != 7) {
printf("Given station ID '%s' does not have 7 or (the last) 5 digits\n", station_id);
return 0;
}
if (strlen(station_id) > 5)
station_id += strlen(station_id) - 5;
rc = main_mobile_number_ask(station_id, "station ID");
if (rc)
return rc;
}
if (!num_kanal) {
@ -188,7 +190,7 @@ int main(int argc, char *argv[])
printf("Base station on channel %s ready, please tune transmitter to %.3f MHz and receiver to %.3f MHz. (%.3f MHz offset)\n", kanal[i], anetz_kanal2freq(atoi(kanal[i]), 0) / 1e6, anetz_kanal2freq(atoi(kanal[i]), 1) / 1e6, anetz_kanal2freq(atoi(kanal[i]), 2) / 1e6);
}
main_mobile("anetz", &quit, NULL, station_id, 5);
main_mobile_loop("anetz", &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -693,22 +693,8 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
{
sender_t *sender;
bnetz_t *bnetz;
int i;
/* 1. check if number is invalid, return INVALNUMBER */
if (strlen(dialing) == 7 && dialing[0] == '0' && dialing[1] == '5')
dialing += 2;
else if (strlen(dialing) != 5) {
inval:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
for (i = 0; i < 5; i++) {
if (dialing[i] < '0' || dialing[i] > '9')
goto inval;
}
/* 2. check if given number is already in a call, return BUSY */
/* 1. check if given number is already in a call, return BUSY */
for (sender = sender_head; sender; sender = sender->next) {
bnetz = (bnetz_t *) sender;
if (!strcmp(bnetz->station_id, dialing))
@ -719,7 +705,7 @@ inval:
return -CAUSE_BUSY;
}
/* 3. check if all senders are busy, return NOCHANNEL */
/* 2. check if all senders are busy, return NOCHANNEL */
for (sender = sender_head; sender; sender = sender->next) {
bnetz = (bnetz_t *) sender;
if (bnetz->state == BNETZ_FREI)
@ -732,7 +718,7 @@ inval:
PDEBUG_CHAN(DBNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
/* 4. trying to page mobile station */
/* 3. trying to page mobile station */
bnetz->callref = callref;
bnetz_page(bnetz, dialing, 1);

@ -74,8 +74,7 @@ void print_help(const char *arg0)
printf(" and stays below this level, the connection is released.\n");
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
printf(" Only works with SDR! (disabled by default)\n");
printf("\nstation-id: Give 5 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();
}
@ -124,6 +123,16 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
static const struct number_lengths number_lengths[] = {
{ 5, "B-Netz number" },
{ 0, NULL }
};
static const char *number_prefixes[] = {
"05xxxxx",
NULL
};
int main(int argc, char *argv[])
{
int rc, argi;
@ -135,7 +144,7 @@ int main(int argc, char *argv[])
init_besetzton();
init_ansage();
main_mobile_init();
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
/* handle options / config file */
add_options();
@ -148,10 +157,9 @@ int main(int argc, char *argv[])
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 5) {
printf("Given station ID '%s' does not have 5 digits\n", station_id);
return 0;
}
rc = main_mobile_number_ask(station_id, "station ID");
if (rc)
return rc;
}
if (!num_kanal) {
@ -202,7 +210,7 @@ int main(int argc, char *argv[])
printf("To call phone, switch transmitter (using paging signal) to %.3f MHz.\n", bnetz_kanal2freq(19, 0) / 1e6);
}
main_mobile("bnetz", &quit, NULL, station_id, 5);
main_mobile_loop("bnetz", &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -178,6 +178,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)
{
@ -571,39 +593,15 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
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;
}
/* 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 */

@ -133,6 +133,7 @@ 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);

@ -226,8 +226,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");
}
@ -458,10 +457,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;
@ -475,7 +488,7 @@ 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();
@ -488,10 +501,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 */
@ -645,7 +657,7 @@ int main(int argc, char *argv[])
}
}
main_mobile("cnetz", &quit, NULL, station_id, 7);
main_mobile_loop("cnetz", &quit, NULL, station_id);
fail:
flush_db();

@ -660,35 +660,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
sender_t *sender;
euro_t *euro;
euro_call_t *call;
int i;
/* check prefix to choose correct channel */
if (strlen(dialing) == 10) {
if (!strncmp(dialing, "0279", 4)) {
dialing += 4;
channel = 'A';
}
if (!strncmp(dialing, "0509", 4)) {
dialing += 4;
channel = 'B';
}
if (!strncmp(dialing, "0709", 4)) {
dialing += 4;
channel = 'B';
}
}
/* number invalid */
if (strlen(dialing) != 6) {
inval:
PDEBUG(DEURO, DEBUG_NOTICE, "Call to invalid ID '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
for (i = 0; i < 6; i++) {
if (!(dialing[i] >= '0' && dialing[i] <= '9')
&& !(dialing[i] >= 'a' && dialing[i] <= 'e')
&& !(dialing[i] >= 'A' && dialing[i] <= 'E'))
goto inval;
}
/* find transmitter */
for (sender = sender_head; sender; sender = sender->next) {

@ -81,8 +81,7 @@ void print_help(const char *arg0)
printf(" to page a recevier.\n");
printf(" --repeat <num>\n");
printf(" Repead paging ID <num> times when transmitting. (default = %d)\n", repeat);
printf("\nstation-id: Give 6 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();
}
@ -102,25 +101,6 @@ static void add_options(void)
option_add(OPT_REPEAT, "repeat", 1);
}
static int check_id(const char *id)
{
int i;
if (strlen(id) != 6) {
fprintf(stderr, "Given paging ID must have exactly 6 digits!\n");
return -EINVAL;
}
for (i = 0; i < 6; i++) {
if (id[i] < '0' || id[i] > '9') {
fprintf(stderr, "Given paging ID must have digits (0..9) only!\n");
return -EINVAL;
}
}
return 0;
}
static int handle_options(int short_option, int argi, char **argv)
{
switch (short_option) {
@ -134,20 +114,20 @@ static int handle_options(int short_option, int argi, char **argv)
rx = 1;
break;
case 'I':
if (check_id(argv[argi]))
if (main_mobile_number_ask(argv[argi], "ID (--id)"))
return -EINVAL;
euro_add_id(argv[argi]);
euro_add_id(mobile_number_remove_prefix(argv[argi]));
break;
case 'D':
degraded = 1;
break;
case 'S':
if (check_id(argv[argi]))
if (main_mobile_number_ask(argv[argi], "ID to scan from"))
return -EINVAL;
scan_from = atoi(argv[argi++]);
if (check_id(argv[argi]))
scan_from = atoi(mobile_number_remove_prefix((argv[argi++])));
if (main_mobile_number_ask(argv[argi], "ID to scan to"))
return -EINVAL;
scan_to = atoi(argv[argi++]) + 1;
scan_to = atoi(mobile_number_remove_prefix(argv[argi++])) + 1;
break;
case OPT_RANDOM:
random_id = 1;
@ -162,6 +142,21 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
static const struct number_lengths number_lengths[] = {
{ 6, "number" },
{ 0, NULL }
};
static const char *number_prefixes[] = {
"0279xxxxxx",
"+49279xxxxxx",
"0509xxxxxx",
"+49509xxxxxx",
"0709xxxxxx",
"+49709xxxxxx",
NULL
};
int main(int argc, char *argv[])
{
int rc, argi;
@ -178,8 +173,7 @@ int main(int argc, char *argv[])
init_es_kaudn();
/* init mobile interface */
console_digits = "0123456789ABCDE";
main_mobile_init();
main_mobile_init("0123456789ABCDEabcde", number_lengths, number_prefixes, NULL);
/* handle options / config file */
add_options();
@ -192,10 +186,9 @@ int main(int argc, char *argv[])
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 6) {
printf("Given receiver ID '%s' does not have 6 digits\n", station_id);
return 0;
}
rc = main_mobile_number_ask(station_id, "station ID");
if (rc)
return rc;
}
if (!num_kanal) {
@ -239,7 +232,7 @@ int main(int argc, char *argv[])
printf("Base station for channel %s ready, please tune transmitter and/or receiver to %.4f MHz\n", kanal[i], euro_kanal2freq(kanal[i], fm) / 1e6);
}
main_mobile("eurosignal", &quit, NULL, station_id, 6);
main_mobile_loop("eurosignal", &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -52,6 +52,28 @@ extern int alarms;
extern int authentication;
extern int warmstart;
/* 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;
}
static int send_bit(void *inst)
{
fuvst_t *fuvst = (fuvst_t *)inst;
@ -1286,41 +1308,18 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
uint8_t futln_fuvst;
int futln_rest; /* use int for checking size > 65535 */
int len;
int i;
transaction_t *trans;
uint8_t ident;
uint8_t opcode, *data;
/* 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;
}
/* 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. base station ready? */

@ -22,6 +22,7 @@ typedef struct fuvst {
struct SysMeld SM; /* collects alarm messages */
} fuvst_t;
const char *cnetz_number_valid(const char *number);
int fuvst_create(const char *kanal, enum fuvst_chan_type chan_type, const char *audiodev, int samplerate, double rx_gain, double tx_gain, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, int ignore_link_failure, uint8_t sio, uint16_t local_pc, uint16_t remove_pc);
void fuvst_destroy(sender_t *sender);
void add_emergency(const char *number);

@ -73,6 +73,7 @@ void print_help(const char *arg0)
printf(" Don't do any link error checking at MTP.\n");
printf(" -C --bs-config <filename>\n");
printf(" Give DKO config file (6 KBytes tape file) to be loaded at boot time.\n");
main_mobile_print_station_id();
main_mobile_print_hotkeys();
}
@ -154,6 +155,20 @@ static int handle_options(int short_option, int argi, char **argv)
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;
@ -166,10 +181,11 @@ int main(int argc, char *argv[])
init_besetzton();
init_ansage();
/* init mobile interface */
allow_sdr = 0;
uses_emphasis = 0;
check_channel = 0;
main_mobile_init();
main_mobile_init("0123456789", number_lengths, number_prefixes, cnetz_number_valid);
config_init();
@ -189,10 +205,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;
}
if (num_kanal == 1 && num_device == 0)
@ -270,7 +285,7 @@ int main(int argc, char *argv[])
if (config_loaded)
printf("BS-Config: %s\n", config_name);
main_mobile("fuvst", &quit, NULL, station_id, 7);
main_mobile_loop("fuvst", &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -179,10 +179,11 @@ int main(int argc, char *argv[])
func_mtp_receive_lssu = receive_lssu;
func_mtp_receive_msu = receive_msu;
/* init mobile interface */
allow_sdr = 0;
uses_emphasis = 0;
check_channel = 0;
main_mobile_init();
main_mobile_init(NULL, NULL, NULL, NULL);
/* handle options / config file */
add_options();
@ -225,7 +226,7 @@ int main(int argc, char *argv[])
goto fail;
}
main_mobile(NULL, &quit, NULL, NULL, 0);
main_mobile_loop(NULL, &quit, NULL, NULL);
fail:
/* destroy transceiver instance */

@ -262,6 +262,21 @@ double imts_is_canada_only(const char *kanal)
return 0;
}
/* check if number is a valid station ID */
const char *mts_number_valid(const char *number)
{
int i;
/* assume that the number has valid length(s) and digits */
for (i = 0; number[i]; i++) {
if (number[i] == '1')
return "Digits value '1' is not allowed within MTS number.";
}
return NULL;
}
/* global init */
int imts_init(void)
{
@ -274,7 +289,7 @@ static void imts_paging(imts_t *imts, const char *dial_string, int loopback);
static void imts_detector_test(imts_t *imts, double length_1, double length_2, double length_3);
/* Create transceiver instance and link to a list. */
int imts_create(const char *kanal, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, double squelch_db, int ptt, int station_length, double fast_seize, enum mode mode, const char *operator, double length_1, double length_2, double length_3)
int imts_create(const char *kanal, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, double squelch_db, int ptt, double fast_seize, enum mode mode, const char *operator, double length_1, double length_2, double length_3)
{
imts_t *imts;
int rc;
@ -309,7 +324,6 @@ int imts_create(const char *kanal, const char *device, int use_sdr, int samplera
PDEBUG(DIMTS, DEBUG_DEBUG, "Creating 'IMTS' instance for channel = %s (sample rate %d).\n", kanal, samplerate);
imts->station_length = station_length;
imts->fast_seize = fast_seize;
imts->mode = mode;
imts->operator = operator;
@ -809,8 +823,9 @@ static void ani_after_digit(imts_t *imts)
/* update status while receiving station ID */
imts_display_status();
/* if all digits have been received */
if (imts->rx_ani_index == imts->station_length) {
if (imts->rx_ani_index == 7) {
PDEBUG_CHAN(DIMTS, DEBUG_INFO, "ANI '%s' complete, sending dial tone.\n", imts->station_id);
dt:
imts_set_dsp_mode(imts, DSP_MODE_TONE, TONE_DIALTONE, 0.0, 0);
timer_start(&imts->timer, DIALTONE_TO);
imts->dial_number[0] = '\0';
@ -821,6 +836,11 @@ static void ani_after_digit(imts_t *imts)
}
timer_start(&imts->timer, ANI_TO);
} else {
/* if only 5 digits have been received */
if (imts->rx_ani_index == 5) {
PDEBUG_CHAN(DIMTS, DEBUG_INFO, "ANI '%s' (5 digits) complete, sending dial tone.\n", imts->station_id);
goto dt;
}
PDEBUG_CHAN(DIMTS, DEBUG_NOTICE, "Timeout receiving ANI from mobile phone, releasing!\n");
imts_release(imts);
}
@ -1144,7 +1164,6 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
char number[8];
sender_t *sender;
imts_t *imts;
int i;
/* 1. check if given number is already in a call, return BUSY */
for (sender = sender_head; sender; sender = sender->next) {
@ -1168,31 +1187,15 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
return -CAUSE_NOCHANNEL;
}
/* 3. check if number is invalid, return INVALNUMBER */
if (strlen(dialing) == 12 && !strncmp(dialing, "+1", 2))
dialing += 2;
if (strlen(dialing) == 11 && !strncmp(dialing, "1", 1))
dialing += 1;
if (strlen(dialing) == 10 && imts->station_length == 7) {
/* 3. convert 10 digit numbers to 7 digit station ID */
if (strlen(dialing) == 10) {
strncpy(number, dialing, 3);
strcpy(number + 3, dialing + 6);
dialing = number;
}
if (strlen(dialing) == 10 && imts->station_length == 5)
dialing += 5;
if ((int)strlen(dialing) != imts->station_length) {
inval:
PDEBUG(DIMTS, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
for (i = 0; i < (int)strlen(dialing); i++) {
if (dialing[i] < '0' || dialing[i] > '9')
goto inval;
}
PDEBUG_CHAN(DIMTS, DEBUG_INFO, "Call to mobile station, paging number: %s\n", dialing);
/* 4. trying to page mobile station */
PDEBUG_CHAN(DIMTS, DEBUG_INFO, "Call to mobile station, paging number: %s\n", dialing);
imts->callref = callref;
imts_paging(imts, dialing, 0);

@ -60,7 +60,6 @@ typedef struct imts {
emphasis_t estate;
int callref; /* call reference */
char station_id[11]; /* current station ID (also used for test pattern) */
int station_length; /* digit length of station ID */
char dial_number[33]; /* number dialing */
struct timer timer;
int last_tone; /* last tone received */
@ -126,10 +125,11 @@ typedef struct imts {
} imts_t;
const char *mts_number_valid(const char *number);
void imts_list_channels(void);
double imts_channel2freq(const char *kanal, int uplink);
int imts_init(void);
int imts_create(const char *channel, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, double squelch_db, int ptt, int station_length, double fast_seize, enum mode mode, const char *operator, double length_1, double length_2, double length_3);
int imts_create(const char *channel, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, double squelch_db, int ptt, double fast_seize, enum mode mode, const char *operator, double length_1, double length_2, double length_3);
void imts_destroy(sender_t *sender);
void imts_loss_indication(imts_t *imts, double loss_time);
void imts_signal_indication(imts_t *imts);

@ -40,7 +40,6 @@
/* settings */
static double squelch_db = -INFINITY;
static int ptt = 0;
static int station_length = 0; /* defined by mode */
static double fast_seize = 0.0;
static enum mode mode = MODE_IMTS;
static char operator[32] = "010";
@ -62,9 +61,6 @@ void print_help(const char *arg0)
printf(" This adds extra delay to received audio, to eliminate noise when the\n");
printf(" transmitter of the phone is turned off. Also this disables release on\n");
printf(" loss of RF signal. (Squelch is required for this to operate.)\n");
printf(" -5 --five\n");
printf(" -7 --seven\n");
printf(" Force station ID length (default is 7 for IMTS, 5 for MTS)\n");
printf(" -F --fast-seize <delay in ms>\n");
printf(" To compensate audio processing latency, give delay when to respond,\n");
printf(" after detection of Guard tone from mobile phone.\n");
@ -89,8 +85,7 @@ void print_help(const char *arg0)
printf(" Give length of 600/1500 Hz and silence in seconds. Listen to it with\n");
printf(" a radio receiver. To exclude an element, set its length to '0'.\n");
printf(" Example: '-D 0.5 0.5 0' plays alternating 600/1500 Hz tone.\n");
printf("\nstation-id: Give %d digits of station-id, you don't need to enter it after\n", station_length);
printf(" every start of this program.\n");
main_mobile_print_station_id();
main_mobile_print_hotkeys();
}
@ -99,8 +94,6 @@ static void add_options(void)
main_mobile_add_options();
option_add('S', "squelch", 1);
option_add('P', "push-to-talk", 0);
option_add('5', "five", 0);
option_add('7', "seven", 0);
option_add('F', "fast-seize", 1);
option_add('D', "decoder-test", 3);
option_add('M', "mts", 0);
@ -119,12 +112,6 @@ static int handle_options(int short_option, int argi, char **argv)
case 'P':
ptt = 1;
break;
case '5':
station_length = 5;
break;
case '7':
station_length = 7;
break;
case 'F':
fast_seize = atof(argv[argi]) / 1000.0;
if (fast_seize < 0.0)
@ -150,6 +137,19 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
static const struct number_lengths number_lengths[] = {
{ 5, "MTS number format" },
{ 7, "IMTS number format" },
{ 10, "IMTS number (digits 4..6 will br removed)" },
{ 0, NULL }
};
static const char *number_prefixes[] = {
"1xxxxxxxxxx",
"+1xxxxxxxxxx",
NULL
};
int main(int argc, char *argv[])
{
int rc, argi;
@ -163,7 +163,8 @@ int main(int argc, char *argv[])
init_invalidnumber();
init_congestion();
main_mobile_init();
/* init mobile interface */
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
/* handle options / config file */
add_options();
@ -174,19 +175,15 @@ int main(int argc, char *argv[])
if (argi <= 0)
return argi;
if (!station_length) {
if (mode == MODE_IMTS)
station_length = 7;
else
station_length = 5;
}
/* set check for MTS mode */
if (mode == MODE_MTS)
main_mobile_set_number_check_valid(mts_number_valid);
if (argi < argc) {
station_id = argv[argi];
if ((int)strlen(station_id) != station_length) {
printf("Given station ID '%s' does not have %d digits\n", station_id, station_length);
return 0;
}
rc = main_mobile_number_ask(station_id, "station ID");
if (rc)
return rc;
}
if (!num_kanal) {
@ -266,7 +263,7 @@ int main(int argc, char *argv[])
/* create transceiver instance */
for (i = 0; i < num_kanal; i++) {
rc = imts_create(kanal[i], dsp_device[i], use_sdr, dsp_samplerate, rx_gain, tx_gain, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, squelch_db, ptt, station_length, fast_seize, mode, operator, detector_test_length_1, detector_test_length_2, detector_test_length_3);
rc = imts_create(kanal[i], dsp_device[i], use_sdr, dsp_samplerate, rx_gain, tx_gain, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, squelch_db, ptt, fast_seize, mode, operator, detector_test_length_1, detector_test_length_2, detector_test_length_3);
if (rc < 0) {
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
goto fail;
@ -274,7 +271,7 @@ int main(int argc, char *argv[])
printf("Base station on channel %s ready, please tune transmitter to %.3f MHz and receiver to %.3f MHz. (%.3f MHz offset)\n", kanal[i], imts_channel2freq(kanal[i], 0) / 1e6, imts_channel2freq(kanal[i], 1) / 1e6, imts_channel2freq(kanal[i], 2) / 1e6);
}
main_mobile((mode == MODE_IMTS) ? "imts" : "mts", &quit, NULL, station_id, station_length);
main_mobile_loop((mode == MODE_IMTS) ? "imts" : "mts", &quit, NULL, station_id);
fail:
/* destroy transceiver instance */

@ -480,13 +480,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
sender_t *sender;
jolly_t *jolly;
/* 1. check if number is invalid, return INVALNUMBER */
if (strlen(dialing) == 0) {
PDEBUG(DJOLLY, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
}
/* 2. check if given number is already in a call, return BUSY */
/* 1. check if given number is already in a call, return BUSY */
for (sender = sender_head; sender; sender = sender->next) {
jolly = (jolly_t *) sender;
if (!strcmp(jolly->station_id, dialing))