From 423bc4242908a4b2082a23bf817e62db2e28c58e Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Thu, 7 Oct 2021 19:35:56 +0200 Subject: 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. --- src/amps/amps.c | 24 +------ src/amps/amps_tacs_main.c | 19 ++--- src/amps/main.c | 7 ++ src/amps/main.h | 2 + src/anetz/anetz.c | 59 +++++++++------- src/anetz/anetz.h | 1 + src/anetz/main.c | 22 +++--- src/bnetz/bnetz.c | 20 +----- src/bnetz/main.c | 24 ++++--- src/cnetz/cnetz.c | 58 ++++++++------- src/cnetz/cnetz.h | 1 + src/cnetz/main.c | 30 +++++--- src/eurosignal/eurosignal.c | 28 -------- src/eurosignal/main.c | 61 +++++++--------- src/fuvst/fuvst.c | 57 ++++++++------- src/fuvst/fuvst.h | 1 + src/fuvst/main.c | 27 +++++-- src/fuvst/sniffer.c | 5 +- src/imts/imts.c | 49 +++++++------ src/imts/imts.h | 4 +- src/imts/main.c | 51 +++++++------ src/jolly/jolly.c | 12 +--- src/jolly/main.c | 20 +++--- src/jtacs/main.c | 3 + src/libmobile/call.c | 54 +++++++++++++- src/libmobile/console.c | 61 +++++++++++----- src/libmobile/console.h | 2 +- src/libmobile/main_mobile.c | 169 ++++++++++++++++++++++++++++++++++++++++++-- src/libmobile/main_mobile.h | 18 ++++- src/mpt1327/main.c | 22 +++--- src/mpt1327/mpt1327.c | 47 ++++++------ src/mpt1327/mpt1327.h | 1 + src/nmt/main.c | 20 +++--- src/nmt/nmt.c | 8 +-- src/r2000/main.c | 17 +++-- src/r2000/r2000.c | 60 +++++----------- src/r2000/r2000.h | 1 + src/tacs/main.c | 7 ++ src/test/test_dms.c | 4 +- src/test/test_sms.c | 4 +- src/zeitansage/main.c | 11 ++- 41 files changed, 662 insertions(+), 429 deletions(-) diff --git a/src/amps/amps.c b/src/amps/amps.c index c4f61cd..870da27 100644 --- a/src/amps/amps.c +++ b/src/amps/amps.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 */ diff --git a/src/amps/amps_tacs_main.c b/src/amps/amps_tacs_main.c index bf71dd1..fe9cc02 100644 --- a/src/amps/amps_tacs_main.c +++ b/src/amps/amps_tacs_main.c @@ -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 */ diff --git a/src/amps/main.c b/src/amps/main.c index 163626e..3b5d964 100644 --- a/src/amps/main.c +++ b/src/amps/main.c @@ -1,3 +1,4 @@ +#include #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 */ diff --git a/src/amps/main.h b/src/amps/main.h index 116b612..23bca88 100644 --- a/src/amps/main.h +++ b/src/amps/main.h @@ -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[]); diff --git a/src/anetz/anetz.c b/src/anetz/anetz.c index f9b0c56..d5e1a76 100644 --- a/src/anetz/anetz.c +++ b/src/anetz/anetz.c @@ -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) { diff --git a/src/anetz/anetz.h b/src/anetz/anetz.h index 57ab270..fc04d95 100644 --- a/src/anetz/anetz.h +++ b/src/anetz/anetz.h @@ -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); diff --git a/src/anetz/main.c b/src/anetz/main.c index edcf71a..cd6f015 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -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 */ diff --git a/src/bnetz/bnetz.c b/src/bnetz/bnetz.c index fa75303..6788ded 100644 --- a/src/bnetz/bnetz.c +++ b/src/bnetz/bnetz.c @@ -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); diff --git a/src/bnetz/main.c b/src/bnetz/main.c index d9ff4d5..a82e412 100644 --- a/src/bnetz/main.c +++ b/src/bnetz/main.c @@ -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 */ diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c index 44e84b7..e276d62 100644 --- a/src/cnetz/cnetz.c +++ b/src/cnetz/cnetz.c @@ -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 */ diff --git a/src/cnetz/cnetz.h b/src/cnetz/cnetz.h index 84ba965..3d074b8 100644 --- a/src/cnetz/cnetz.h +++ b/src/cnetz/cnetz.h @@ -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); diff --git a/src/cnetz/main.c b/src/cnetz/main.c index 1575ac9..1c4dbba 100644 --- a/src/cnetz/main.c +++ b/src/cnetz/main.c @@ -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(); diff --git a/src/eurosignal/eurosignal.c b/src/eurosignal/eurosignal.c index 1aa5815..62f6049 100644 --- a/src/eurosignal/eurosignal.c +++ b/src/eurosignal/eurosignal.c @@ -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) { diff --git a/src/eurosignal/main.c b/src/eurosignal/main.c index fde8011..2aaedb4 100644 --- a/src/eurosignal/main.c +++ b/src/eurosignal/main.c @@ -81,8 +81,7 @@ void print_help(const char *arg0) printf(" to page a recevier.\n"); printf(" --repeat \n"); printf(" Repead paging ID 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 */ diff --git a/src/fuvst/fuvst.c b/src/fuvst/fuvst.c index f284a34..dc5da16 100755 --- a/src/fuvst/fuvst.c +++ b/src/fuvst/fuvst.c @@ -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? */ diff --git a/src/fuvst/fuvst.h b/src/fuvst/fuvst.h index 33ef3ae..1177606 100755 --- a/src/fuvst/fuvst.h +++ b/src/fuvst/fuvst.h @@ -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); diff --git a/src/fuvst/main.c b/src/fuvst/main.c index c7b89db..7a18da0 100755 --- a/src/fuvst/main.c +++ b/src/fuvst/main.c @@ -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 \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 */ diff --git a/src/fuvst/sniffer.c b/src/fuvst/sniffer.c index 5e44f88..570919d 100644 --- a/src/fuvst/sniffer.c +++ b/src/fuvst/sniffer.c @@ -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 */ diff --git a/src/imts/imts.c b/src/imts/imts.c index 2f6d9cd..8a33123 100644 --- a/src/imts/imts.c +++ b/src/imts/imts.c @@ -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); diff --git a/src/imts/imts.h b/src/imts/imts.h index efd33f6..d754c90 100644 --- a/src/imts/imts.h +++ b/src/imts/imts.h @@ -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); diff --git a/src/imts/main.c b/src/imts/main.c index 1b4ebb3..dace347 100644 --- a/src/imts/main.c +++ b/src/imts/main.c @@ -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 \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 */ diff --git a/src/jolly/jolly.c b/src/jolly/jolly.c index d5cf323..a979806 100644 --- a/src/jolly/jolly.c +++ b/src/jolly/jolly.c @@ -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)) @@ -497,7 +491,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, 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) { jolly = (jolly_t *) sender; if (jolly->state == STATE_IDLE) @@ -510,7 +504,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, PDEBUG_CHAN(DJOLLY, DEBUG_INFO, "Call to mobile station.\n"); - /* 4. trying to page mobile station */ + /* 3. trying to page mobile station */ jolly->callref = callref; jolly_page(jolly, dialing); diff --git a/src/jolly/main.c b/src/jolly/main.c index 0b1b7d8..254337b 100644 --- a/src/jolly/main.c +++ b/src/jolly/main.c @@ -67,8 +67,7 @@ void print_help(const char *arg0) printf(" Use transceiver as repeater, so multiple radios can communicate with\n"); printf(" each other. It is still possible to make and receive calls. Multiple\n"); printf(" radios can talk then to the calling/called party.\n"); - printf("\nstation-id: Give 4 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(); } @@ -118,6 +117,11 @@ static int handle_options(int short_option, int argi, char **argv) return 1; } +static const struct number_lengths number_lengths[] = { + { 4, "number" }, + { 0, NULL } +}; + int main(int argc, char *argv[]) { int rc, argi; @@ -130,7 +134,8 @@ int main(int argc, char *argv[]) init_besetzton(); // init_ansage(); - main_mobile_init(); + /* init mobile interface */ + main_mobile_init("0123456789", number_lengths, NULL, NULL); /* handle options / config file */ add_options(); @@ -143,10 +148,9 @@ int main(int argc, char *argv[]) if (argi < argc) { station_id = argv[argi]; - if (strlen(station_id) != 4) { - printf("Given station ID '%s' does not have 4 digits\n", station_id); - return 0; - } + rc = main_mobile_number_ask(station_id, "station ID"); + if (rc) + return rc; } if (!num_kanal) { @@ -198,7 +202,7 @@ int main(int argc, char *argv[]) printf("base station on channel %s ready, please tune transmitter to %.4f MHz and receiver to %.4f MHz. (%.4f MHz offset)\n", kanal[i], dl_freq + step / 1e3 * (double)atoi(kanal[i]), ul_freq + step / 1e3 * (double)atoi(kanal[i]), ul_freq - dl_freq); } - main_mobile("jollycom", &quit, NULL, station_id, 4); + main_mobile_loop("jollycom", &quit, NULL, station_id); fail: /* destroy transceiver instance */ diff --git a/src/jtacs/main.c b/src/jtacs/main.c index e0551a3..f19e160 100644 --- a/src/jtacs/main.c +++ b/src/jtacs/main.c @@ -1,3 +1,4 @@ +#include #include "../amps/main.h" #include "../amps/tones.h" #include "../amps/outoforder.h" @@ -5,6 +6,8 @@ const int tacs = 1; const int jtacs = 1; +const char *number_prefixes[] = { NULL }; + int main(int argc, char *argv[]) { /* init common tones */ diff --git a/src/libmobile/call.c b/src/libmobile/call.c index 5aefa7b..4f9049b 100644 --- a/src/libmobile/call.c +++ b/src/libmobile/call.c @@ -34,6 +34,7 @@ #include "cause.h" #include "sender.h" #include "call.h" +#include "main_mobile.h" #include "console.h" #define DISC_TIMEOUT 30 @@ -659,6 +660,7 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref, uint16_t sip_cause; uint8_t type, plan, present, screen, caller_type; char caller_id[33], number[33]; + const char *suffix, *invalid; int rc; process = get_process(callref); @@ -708,6 +710,7 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref, sdp = osmo_cc_helper_audio_accept(&ep->session_config, process, codecs, down_audio, msg, &process->session, &process->codec, 0); if (!sdp) { disconnect_process(callref, 47); + indicate_disconnect_release(callref, 47, OSMO_CC_MSG_REJ_IND); break; } @@ -733,6 +736,7 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref, if (present == OSMO_CC_PRESENT_RESTRICTED) caller_type = TYPE_ANONYMOUS; } + /* dialing */ rc = osmo_cc_get_ie_called(msg, 0, &type, &plan, number, sizeof(number)); if (rc < 0) @@ -746,7 +750,55 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref, } PDEBUG(DCALL, DEBUG_INFO, "Outgoing call from '%s' to '%s'\n", caller_id, number); - rc = call_down_setup(callref, caller_id, caller_type, number); + /* insert '+' for international dialing */ + if (type == OSMO_CC_TYPE_INTERNATIONAL && number[0] != '+') { + memmove(number + 1, number, sizeof(number) - 2); + number[0] = '+'; + } + + /* remove prefix, if any */ + suffix = mobile_number_remove_prefix(number); + + /* check suffix length */ + invalid = mobile_number_check_length(suffix); + if (invalid) { + PDEBUG(DCALL, DEBUG_NOTICE, "Mobile number '%s' has invalid length: %s\n", suffix, invalid); + disconnect_process(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + if (!connect_on_setup) { + PDEBUG(DCALL, DEBUG_INFO, "Disconnecting OSMO-CC call towards fixed network (cause=%d)\n", OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + indicate_disconnect_release(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT, OSMO_CC_MSG_DISC_IND); + } + break; + } + + /* check suffix digits */ + invalid = mobile_number_check_digits(suffix); + if (invalid) { + PDEBUG(DCALL, DEBUG_NOTICE, "Mobile number '%s' has invalid digit: %s.\n", suffix, invalid); + disconnect_process(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + if (!connect_on_setup) { + PDEBUG(DCALL, DEBUG_INFO, "Disconnecting OSMO-CC call towards fixed network (cause=%d)\n", OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + indicate_disconnect_release(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT, OSMO_CC_MSG_DISC_IND); + } + break; + } + + /* check if suffix is valid */ + if (mobile_number_check_valid) { + invalid = mobile_number_check_valid(suffix); + if (invalid) { + PDEBUG(DCALL, DEBUG_NOTICE, "Mobile number '%s' is invalid for this network: %s\n", suffix, invalid); + disconnect_process(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + if (!connect_on_setup) { + PDEBUG(DCALL, DEBUG_INFO, "Disconnecting OSMO-CC call towards fixed network (cause=%d)\n", OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT); + indicate_disconnect_release(callref, OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT, OSMO_CC_MSG_DISC_IND); + } + break; + } + } + + /* setup call */ + rc = call_down_setup(callref, caller_id, caller_type, suffix); if (rc < 0) { PDEBUG(DCALL, DEBUG_NOTICE, "Call rejected, cause %d\n", -rc); if (!connect_on_setup) { diff --git a/src/libmobile/console.c b/src/libmobile/console.c index f42fe3a..ee533b0 100644 --- a/src/libmobile/console.c +++ b/src/libmobile/console.c @@ -32,6 +32,7 @@ #include "../libosmocc/endpoint.h" #include "../libosmocc/helper.h" #include "testton.h" +#include "../libmobile/main_mobile.h" #include "console.h" #include "cause.h" #include "../libmobile/call.h" @@ -77,7 +78,8 @@ typedef struct console { int test_audio_pos; /* position for test tone toward mobile */ sample_t tx_buffer[160];/* transmit audio buffer */ int tx_buffer_pos; /* current position in transmit audio buffer */ - int num_digits; /* number of digits to be dialed */ + const struct number_lengths *number_lengths;/* number of digits to be dialed */ + int number_max_length; /* number of digits of the longest number to be dialed */ int loopback; /* loopback test for echo */ int echo_test; /* send echo back to mobile phone */ const char *digits; /* list of dialable digits */ @@ -268,10 +270,8 @@ void console_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg) osmo_cc_free_msg(msg); return; } - if (caller_id[0]) { - strncpy(console.station_id, caller_id, console.num_digits); - console.station_id[console.num_digits] = '\0'; - } + if (caller_id[0]) + strncpy(console.station_id, caller_id, sizeof(console.station_id) - 1); strncpy(console.dialing, number, sizeof(console.dialing) - 1); console.dialing[sizeof(console.dialing) - 1] = '\0'; console_new_state(CONSOLE_CONNECT); @@ -297,8 +297,8 @@ void console_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg) PDEBUG(DCC, DEBUG_INFO, "Call connected to '%s'\n", caller_id); osmo_cc_helper_audio_negotiate(msg, &console.session, &console.codec); console_new_state(CONSOLE_CONNECT); - strncpy(console.station_id, caller_id, console.num_digits); - console.station_id[console.num_digits] = '\0'; + if (caller_id[0]) + strncpy(console.station_id, caller_id, sizeof(console.station_id) - 1); request_answer_ack(console.callref); break; } @@ -358,9 +358,10 @@ static void _print_console_text(void) printf("\033[0;39m"); } -int console_init(const char *station_id, const char *audiodev, int samplerate, int buffer, int num_digits, int loopback, int echo_test, const char *digits) +int console_init(const char *audiodev, int samplerate, int buffer, int loopback, int echo_test, const char *digits, const struct number_lengths *lengths, const char *station_id) { int rc = 0; + int i; init_testton(); @@ -368,15 +369,21 @@ int console_init(const char *station_id, const char *audiodev, int samplerate, i print_console_text = _print_console_text; memset(&console, 0, sizeof(console)); - if (station_id) - strncpy(console.station_id, station_id, sizeof(console.station_id) - 1); strncpy(console.audiodev, audiodev, sizeof(console.audiodev) - 1); console.samplerate = samplerate; console.buffer_size = buffer * samplerate / 1000; - console.num_digits = num_digits; console.loopback = loopback; console.echo_test = echo_test; console.digits = digits; + console.number_lengths = lengths; + if (lengths) { + for (i = 0; lengths[i].usage; i++) { + if (lengths[i].digits > console.number_max_length) + console.number_max_length = lengths[i].digits; + } + } + if (station_id) + strncpy(console.station_id, station_id, sizeof(console.station_id) - 1); if (!audiodev[0]) return 0; @@ -451,6 +458,10 @@ void console_cleanup(void) } } +/* process input from console + * it is not called at loopback mode + * calling this implies that the console.number_lengths is set + */ static void process_ui(int c) { char text[256] = ""; @@ -460,7 +471,7 @@ static void process_ui(int c) switch (console.state) { case CONSOLE_IDLE: if (c > 0) { - if ((int)strlen(console.station_id) < console.num_digits) { + if ((int)strlen(console.station_id) < console.number_max_length) { for (i = 0; i < (int)strlen(console.digits); i++) { if (c == console.digits[i]) { console.station_id[strlen(console.station_id) + 1] = '\0'; @@ -471,7 +482,12 @@ static void process_ui(int c) if ((c == 8 || c == 127) && strlen(console.station_id)) console.station_id[strlen(console.station_id) - 1] = '\0'; dial_after_hangup: - if (c == 'd' && (int)strlen(console.station_id) == console.num_digits) { + len = strlen(console.station_id); + for (i = 0; console.number_lengths[i].usage; i++) { + if (len == console.number_lengths[i].digits) + break; + } + if (c == 'd' && console.number_lengths[i].usage) { PDEBUG(DCC, DEBUG_INFO, "Outgoing call to '%s'\n", console.station_id); console.dialing[0] = '\0'; console_new_state(CONSOLE_SETUP_RT); @@ -479,10 +495,19 @@ dial_after_hangup: request_setup(console.callref, console.station_id); } } - if (console.num_digits != (int)strlen(console.station_id)) - sprintf(text, "on-hook: %s%s (enter digits 0..9)\r", console.station_id, "..............." + 15 - console.num_digits + strlen(console.station_id)); - else - sprintf(text, "on-hook: %s (press d=dial)\r", console.station_id); + sprintf(text, "on-hook: %s%s ", console.station_id, "................................" + 32 - console.number_max_length + strlen(console.station_id)); + len = strlen(console.station_id); + for (i = 0; console.number_lengths[i].usage; i++) { + if (len == console.number_lengths[i].digits) + break; + } + if (console.number_lengths[i].usage) { + if (console.number_lengths[i + 1].usage) + sprintf(strchr(text, '\0'), "(enter digits %s or press d=dial)\r", console.digits); + else + sprintf(strchr(text, '\0'), "(press d=dial)\r"); + } else + sprintf(strchr(text, '\0'), "(enter digits %s)\r", console.digits); break; case CONSOLE_SETUP_RO: case CONSOLE_SETUP_RT: @@ -538,7 +563,7 @@ dial_after_hangup: * returns 1 on exit (ctrl+c) */ void process_console(int c) { - if (!console.loopback && console.num_digits) + if (!console.loopback && console.number_max_length) process_ui(c); if (console.session) diff --git a/src/libmobile/console.h b/src/libmobile/console.h index a54edc0..20b5a44 100644 --- a/src/libmobile/console.h +++ b/src/libmobile/console.h @@ -1,6 +1,6 @@ void console_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg); -int console_init(const char *station_id, const char *audiodev, int samplerate, int buffer, int dial_digits, int loopback, int echo_test, const char *digits); +int console_init(const char *audiodev, int samplerate, int buffer, int loopback, int echo_test, const char *digits, const struct number_lengths *lengths, const char *station_id); void console_cleanup(void); int console_open_audio(int buffer_size, double interval); int console_start_audio(void); diff --git a/src/libmobile/main_mobile.c b/src/libmobile/main_mobile.c index c0221e8..a6e7702 100644 --- a/src/libmobile/main_mobile.c +++ b/src/libmobile/main_mobile.c @@ -80,21 +80,147 @@ const char *write_tx_wave = NULL; const char *write_rx_wave = NULL; const char *read_tx_wave = NULL; const char *read_rx_wave = NULL; -const char *console_digits = "0123456789"; -void main_mobile_init(void) +static const char *number_digits; +static const struct number_lengths *number_lengths; +static const char **number_prefixes; + +const char *mobile_number_remove_prefix(const char *number) +{ + size_t len; + int i, j; + + if (!number_prefixes) + return number; + + len = strlen(number); + for (i = 0; number_prefixes[i]; i++) { + /* skip different lengths */ + if (len != strlen(number_prefixes[i])) + continue; + /* match prefix, stop at 'x' */ + for (j = 0; number_prefixes[i][j]; j++) { + if (number_prefixes[i][j] == 'x') + break; + if (number_prefixes[i][j] != number[j]) + break; + } + /* if prefix matches, return suffix */ + if (number_prefixes[i][j] == 'x') + return number + j; + } + + /* return number, if there is no prefix matching */ + return number; +} + +const char *mobile_number_check_length(const char *number) +{ + size_t len; + int i; + static char invalid[256]; + + if (!number_lengths) + return NULL; + + len = strlen(number); + for (i = 0; number_lengths[i].usage; i++) { + if ((int)len == number_lengths[i].digits) + break; + } + if (!number_lengths[i].usage) { + sprintf(invalid, "Number does not have"); + for (i = 0; number_lengths[i].usage; i++) { + sprintf(strchr(invalid, '\0'), " %d", number_lengths[i].digits); + if (number_lengths[i + 1].usage) { + if (number_lengths[i + 2].usage) + strcat(invalid, ","); + else + strcat(invalid, " or"); + } + } + sprintf(strchr(invalid, '\0'), " digits."); + return invalid; + } + + return NULL; +} + +const char *mobile_number_check_digits(const char *number) +{ + int i; + static char invalid[256]; + + for (i = 0; number[i]; i++) { + if (!strchr(number_digits, number[i])) { + sprintf(invalid, "Digit #%d of number has digit '%c' which is not in the set of allowed digits. ('%s')\n", i + 1, number[i], number_digits); + return invalid; + } + } + + return NULL; +} + +const char *(*mobile_number_check_valid)(const char *); + +void main_mobile_init(const char *digits, const struct number_lengths lengths[], const char *prefixes[], const char *(*check_valid)(const char *)) { cc_argv[cc_argc++] = options_strdup("remote auto"); - + + number_digits = digits; + number_lengths = lengths; + number_prefixes = prefixes; + mobile_number_check_valid = check_valid; + got_init = 1; #ifdef HAVE_SDR sdr_config_init(DEFAULT_LO_OFFSET); #endif } +void main_mobile_set_number_check_valid(const char *(*check_valid)(const char *)) +{ + mobile_number_check_valid = check_valid; +} + +/* ask if number is connect */ +int main_mobile_number_ask(const char *number, const char *what) +{ + const char *invalid; + + if (!got_init) { + fprintf(stderr, "main_mobile_init was not called, please fix!\n"); + abort(); + } + + number = mobile_number_remove_prefix(number); + + invalid = mobile_number_check_length(number); + if (invalid) { + printf("Given %s '%s' has invalid length: %s\n", what, number, invalid); + return -EINVAL; + } + + invalid = mobile_number_check_digits(number); + if (invalid) { + printf("Given %s '%s' has invalid digit: %s\n", what, number, invalid); + return -EINVAL; + } + + if (mobile_number_check_valid) { + invalid = mobile_number_check_valid(number); + if (invalid) { + printf("Given %s '%s' is invalid for this network: %s\n", what, number, invalid); + return -EINVAL; + } + } + + return 0; +} + void main_mobile_print_help(const char *arg0, const char *ext_usage) { - printf("Usage: %s -k %s[options] [station-id]\n", arg0, ext_usage); + printf("Usage: %s -k %s[options] [station_id]\n", arg0, ext_usage); printf("\nGlobal options:\n"); /* - - */ printf(" -h --help\n"); @@ -178,6 +304,33 @@ void main_mobile_print_help(const char *arg0, const char *ext_usage) printf("\nNetwork specific options:\n"); } +void main_mobile_print_station_id(void) +{ + int i; + + if (!number_lengths) + return; + + printf("\nstation_id: Give"); + for (i = 0; number_lengths[i].usage; i++) { + printf(" %d", number_lengths[i].digits); + if (number_lengths[i + 1].usage) { + if (number_lengths[i + 2].usage) + printf(","); + else + printf(" or"); + } + } + printf(" digits of station ID,\n"); + printf(" so you don't need to enter it for every start of this application.\n"); + for (i = 0; number_lengths[i].usage; i++) + printf(" Give %d digits for %s.\n", number_lengths[i].digits, number_lengths[i].usage); + if (number_prefixes) { + for (i = 0; number_prefixes[i]; i++) + printf(" You may use '%s' as prefix.\n", number_prefixes[i]); + } +} + void main_mobile_print_hotkeys(void) { printf("\n"); @@ -440,7 +593,7 @@ static int get_char() } /* Loop through all transceiver instances of one network. */ -void main_mobile(const char *name, int *quit, void (*myhandler)(void), const char *station_id, int station_id_digits) +void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), const char *station_id) { int buffer_size; sender_t *sender; @@ -454,6 +607,10 @@ void main_mobile(const char *name, int *quit, void (*myhandler)(void), const cha abort(); } + /* station id preset */ + if (station_id) + station_id = mobile_number_remove_prefix(station_id); + /* size of dsp buffer in samples */ buffer_size = dsp_samplerate * dsp_buffer / 1000; @@ -497,7 +654,7 @@ void main_mobile(const char *name, int *quit, void (*myhandler)(void), const cha /* init OSMO-CC */ if (!use_osmocc_sock) - console_init(station_id, call_device, call_samplerate, call_buffer, station_id_digits, loopback, echo_test, console_digits); + console_init(call_device, call_samplerate, call_buffer, loopback, echo_test, number_digits, number_lengths, station_id); /* init call control instance */ rc = call_init(name, (use_osmocc_sock) ? send_patterns : 0, release_on_disconnect, use_osmocc_sock, cc_argc, cc_argv); diff --git a/src/libmobile/main_mobile.h b/src/libmobile/main_mobile.h index f5df3a8..c0fe797 100644 --- a/src/libmobile/main_mobile.h +++ b/src/libmobile/main_mobile.h @@ -22,11 +22,23 @@ extern const char *write_rx_wave; extern const char *write_tx_wave; extern const char *read_rx_wave; extern const char *read_tx_wave; -extern const char *console_digits; -void main_mobile_init(void); +struct number_lengths { + int digits; + const char *usage; +}; + +const char *mobile_number_remove_prefix(const char *number); +const char *mobile_number_check_length(const char *number); +const char *mobile_number_check_digits(const char *number); +extern const char *(*mobile_number_check_valid)(const char *); +int main_mobile_number_ask(const char *number, const char *what); + +void main_mobile_init(const char *digits, const struct number_lengths lengths[], const char *prefixes[], const char *(*check_valid)(const char *)); +void main_mobile_set_number_check_valid(const char *(*check_valid)(const char *)); void main_mobile_print_help(const char *arg0, const char *ext_usage); void main_mobile_print_hotkeys(void); +void main_mobile_print_station_id(void); void main_mobile_add_options(void); int main_mobile_handle_options(int short_option, int argi, char **argv); @@ -42,7 +54,7 @@ int main_mobile_handle_options(int short_option, int argi, char **argv); extern int quit; void sighandler(int sigset); -void main_mobile(const char *name, int *quit, void (*myhandler)(void), const char *station_id, int station_id_digits); +void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), const char *station_id); void dump_info(void); diff --git a/src/mpt1327/main.c b/src/mpt1327/main.c index 70559d8..13393c1 100644 --- a/src/mpt1327/main.c +++ b/src/mpt1327/main.c @@ -98,9 +98,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 7 digits of Radio Unit's prefix/ident, you don't need to\n"); - printf(" enter it for every start of this program.\n"); + main_mobile_print_station_id(); main_mobile_print_hotkeys(); printf("Press 'i' key to dump list of seen Radio Units.\n"); } @@ -252,6 +250,11 @@ sysdef_oor: return 1; } +static const struct number_lengths number_lengths[] = { + { 7, "number 'pppiiii' (prefix, ident)" }, + { 0, NULL }, +}; + int main(int argc, char *argv[]) { int rc, argi; @@ -264,8 +267,8 @@ int main(int argc, char *argv[]) init_besetzton(); // init_ansage(); - console_digits = "0123456789*#"; - main_mobile_init(); + /* init mobile interface */ + main_mobile_init("0123456789", number_lengths, NULL, mpt1327_number_valid); /* handle options / config file */ add_options(); @@ -278,10 +281,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 4 digits\n", station_id); - return 0; - } + rc = main_mobile_number_ask(station_id, "station ID"); + if (rc) + return rc; } if (!num_kanal) { @@ -380,7 +382,7 @@ int main(int argc, char *argv[]) mpt1327_check_channels(); - main_mobile("mpt1327", &quit, NULL, station_id, 7); + main_mobile_loop("mpt1327", &quit, NULL, station_id); fail: /* destroy transceiver instance */ diff --git a/src/mpt1327/mpt1327.c b/src/mpt1327/mpt1327.c index 24c9103..d87d476 100755 --- a/src/mpt1327/mpt1327.c +++ b/src/mpt1327/mpt1327.c @@ -80,6 +80,7 @@ #include "dsp.h" #include "message.h" + /* Timers and counters */ #define RESPONSE_TIMEOUT 1.0 #define REPEAT_GTC 1 @@ -88,8 +89,30 @@ #define REPEAT_AHYX 3 #define REPEAT_CLEAR 3 -/* Sysdef - * +/* check if number is a valid station ID */ +const char *mpt1327_number_valid(const char *number) +{ + int value; + static char error[256]; + + /* assume that the number has valid length(s) and digits */ + + value = (number[0] - '0') * 100 + (number[1] - '0') * 10 + (number[2] - '0'); + if (value > 127) { + sprintf(error, "Prefix '%03d' is not in range 000..127.", value); + return error; + } + value = atoi(number + 3); + if (value > 8100 || value < 1) { + sprintf(error, "Ident '%04d' is not in range 0001..8100.", value); + return error; + } + + return NULL; +} + +/* + * Sysdef */ static mpt1327_sysdef_t sysdef; @@ -1536,28 +1559,10 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, mpt1327_t *tc; uint8_t prefix; uint16_t ident; - int i; - /* 1. check if number is invalid, return INVALNUMBER */ - if (strlen(dialing) != 7) { -inval: - PDEBUG(DMPT1327, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing); - return -CAUSE_INVALNUMBER; - } - for (i = 0; i < 7; i++) { - if (dialing[i] < '0' || dialing[i] > '9') - goto inval; - } + /* 1. split number into prefix and ident */ prefix = (dialing[0] - '0') * 100 + (dialing[1] - '0') * 10 + (dialing[2] - '0'); - if (prefix > 127) { - PDEBUG(DMPT1327, DEBUG_NOTICE, "Outgoing call to invalid Prefix '%03d' in number '%s', rejecting! (Prefix must be 000..127)\n", prefix, dialing); - return -CAUSE_INVALNUMBER; - } ident = atoi(dialing + 3); - if (ident > 8100 || ident < 1) { - PDEBUG(DMPT1327, DEBUG_NOTICE, "Outgoing call to invalid Ident '%04d' in number '%s', rejecting! (Ident must be 0001..8100)\n", ident, dialing); - return -CAUSE_INVALNUMBER; - } /* 2. check if given number is already in a call, return BUSY */ unit = get_unit(prefix, ident); diff --git a/src/mpt1327/mpt1327.h b/src/mpt1327/mpt1327.h index ab71970..18af5e1 100755 --- a/src/mpt1327/mpt1327.h +++ b/src/mpt1327/mpt1327.h @@ -139,6 +139,7 @@ typedef struct mpt1327 { void init_sysdef (uint16_t sys, int wt, int per, int pon, int timeout); void flush_units(void); double mpt1327_channel2freq(enum mpt1327_band band, int channel, int uplink); +const char *mpt1327_number_valid(const char *number); const char *mpt1327_band_name(enum mpt1327_band band); void mpt1327_band_list(void); int mpt1327_band_by_short_name(const char *short_name); diff --git a/src/nmt/main.c b/src/nmt/main.c index 8f4a04a..ea03c51 100644 --- a/src/nmt/main.c +++ b/src/nmt/main.c @@ -93,8 +93,7 @@ void print_help(const char *arg0) printf(" Message Service Center). (default = '%s')\n", smsc_number); printf(" -I --caller-id 1 | 0\n"); printf(" If set, the caller ID is sent while ringing the phone. (default = '%d')\n", send_callerid); - printf("\nstation-id: Give 7 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(); } @@ -258,6 +257,11 @@ int submit_sms(const char *sms) return 0; } +static const struct number_lengths number_lengths[] = { + { 7, "NMT number (1st digit country code)" }, + { 0, NULL } +}; + int main(int argc, char *argv[]) { int rc, argi; @@ -269,7 +273,8 @@ int main(int argc, char *argv[]) init_nmt_tones(); init_announcement(); - main_mobile_init(); + /* init mobile interface */ + main_mobile_init("0123456789", number_lengths, NULL, NULL); /* handle options / config file */ add_options(); @@ -282,10 +287,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) { @@ -407,7 +411,7 @@ int main(int argc, char *argv[]) nmt_check_channels(nmt_system); - main_mobile("nmt", &quit, myhandler, station_id, 7); + main_mobile_loop("nmt", &quit, myhandler, station_id); fail: /* fifo */ diff --git a/src/nmt/nmt.c b/src/nmt/nmt.c index 6b89590..5385593 100644 --- a/src/nmt/nmt.c +++ b/src/nmt/nmt.c @@ -1712,22 +1712,16 @@ int _out_setup(int callref, const char *caller_id, enum number_type caller_type, { sender_t *sender; nmt_t *nmt; - int i; nmt_subscriber_t subscr; transaction_t *trans; memset(&subscr, 0, sizeof(subscr)); - /* 1. check if number is invalid, return INVALNUMBER */ + /* 1. split number into country and subscriber parts */ if (dialstring2number(dialing, &subscr.country, subscr.number)) { -inval: PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing); return -CAUSE_INVALNUMBER; } - for (i = 0; i < 6; i++) { - if (subscr.number[i] < '0' || subscr.number[i] > '9') - goto inval; - } /* 2. check if given number is already in a call, return BUSY */ trans = get_transaction_by_number(&subscr); diff --git a/src/r2000/main.c b/src/r2000/main.c index c895217..5aed476 100644 --- a/src/r2000/main.c +++ b/src/r2000/main.c @@ -247,6 +247,11 @@ static int handle_options(int short_option, int argi, char **argv) return 1; } +static const struct number_lengths number_lengths[] = { + { 9, "number 'trrrnnnnn' (type, relais, number)" }, + { 0, NULL } +}; + int main(int argc, char *argv[]) { int rc, argi; @@ -257,7 +262,8 @@ int main(int argc, char *argv[]) /* init tones */ init_radiocom_tones(); - main_mobile_init(); + /* init mobile interface */ + main_mobile_init("0123456789", number_lengths, NULL, r2000_number_valid); /* handle options / config file */ add_options(); @@ -270,10 +276,9 @@ int main(int argc, char *argv[]) if (argi < argc) { station_id = argv[argi]; - if (strlen(station_id) != 9) { - printf("Given station ID '%s' does not have 9 digits\n", station_id); - return 0; - } + rc = main_mobile_number_ask(station_id, "station ID"); + if (rc) + return rc; } if (!num_kanal) { @@ -363,7 +368,7 @@ int main(int argc, char *argv[]) r2000_check_channels(); - main_mobile("radiocom2000", &quit, NULL, station_id, 9); + main_mobile_loop("radiocom2000", &quit, NULL, station_id); fail: /* destroy transceiver instance */ diff --git a/src/r2000/r2000.c b/src/r2000/r2000.c index 26df685..1b3013f 100644 --- a/src/r2000/r2000.c +++ b/src/r2000/r2000.c @@ -120,6 +120,21 @@ double r2000_channel2freq(int band, int channel, int uplink) return freq * 1e6; } +/* check if number is a valid station ID */ +const char *r2000_number_valid(const char *number) +{ + /* assume that the number has valid length(s) and digits */ + + if ((number[0] - '0') > 7) + return "Digit 1 (station mobile type) exceeds 7."; + if ((number[1] - '0') * 100 + (number[2] - '0') * 10 + (number[3] - '0') > 511) + return "Digit 2 to 5 (relais number) exceeds 511."; + if (atoi(number + 4) > 65535) + return "Digit 6 to 9 (mobile number) exceeds 65535."; + + return NULL; +} + const char *r2000_state_name(enum r2000_state state) { static char invalid[16]; @@ -289,49 +304,10 @@ static const char *subscriber2string(r2000_subscriber_t *subscr) /* convert 9-digits dial string to station mobile data */ static int string2subscriber(const char *dialstring, r2000_subscriber_t *subscr) { - char check[6]; - int type, relais, mor; - int i; - - if (strlen(dialstring) != 9) { - PDEBUG(DR2000, DEBUG_NOTICE, "Wrong number of digits, use 9 digits: TRRRXXXXX (T=type, R=relais, X=mobile number)\n"); - return -1; - } - - for (i = 0; i < (int)strlen(dialstring); i++) { - if (dialstring[i] < '0' || dialstring[i] > '9') { - PDEBUG(DR2000, DEBUG_NOTICE, "Invalid digit in dial string, use only 0..9.\n"); - return -1; - } - } - - memcpy(check, dialstring, 1); - check[1] = '\0'; - type = atoi(check); - if (type < 1 || type > 511) { - PDEBUG(DR2000, DEBUG_NOTICE, "Invalid station type in dial string, use 0..7 as station mobile type.\n"); - return -1; - } - - memcpy(check, dialstring + 1, 3); - check[3] = '\0'; - relais = atoi(check); - if (relais < 1 || relais > 511) { - PDEBUG(DR2000, DEBUG_NOTICE, "Invalid relais number in dial string, use 000..511 as relais number.\n"); - return -1; - } - - memcpy(check, dialstring + 4, 5); - check[5] = '\0'; - mor = atoi(check); - if (mor > 65535) { - PDEBUG(DR2000, DEBUG_NOTICE, "Invalid mobile number in dial string, use 00000..65535 as mobile number.\n"); - return -1; - } + subscr->type = dialstring[0] - '0'; + subscr->relais = (dialstring[1] - '0') * 100 + (dialstring[2] - '0') * 10 + (dialstring[3] - '0'); + subscr->mor = atoi(dialstring + 4); - subscr->type = type; - subscr->relais = relais; - subscr->mor = mor; return 0; } diff --git a/src/r2000/r2000.h b/src/r2000/r2000.h index 15f1fe9..07d7c1b 100644 --- a/src/r2000/r2000.h +++ b/src/r2000/r2000.h @@ -129,6 +129,7 @@ void r2000_destroy(sender_t *sender); void r2000_go_idle(r2000_t *r2000); void r2000_band_list(void); double r2000_channel2freq(int band, int channel, int uplink); +const char *r2000_number_valid(const char *number); const char *r2000_get_frame(r2000_t *r2000); void r2000_receive_frame(r2000_t *r2000, const char *bits, double quality, double level); void r2000_receive_super(r2000_t *r2000, uint8_t super, double quality, double level); diff --git a/src/tacs/main.c b/src/tacs/main.c index df3e2cc..85333ad 100644 --- a/src/tacs/main.c +++ b/src/tacs/main.c @@ -1,3 +1,4 @@ +#include #include "../amps/main.h" #include "../amps/tones.h" #include "../amps/outoforder.h" @@ -5,6 +6,12 @@ const int tacs = 1; const int jtacs = 0; +const char *number_prefixes[] = { + "0xxxxxxxxxx", + "+44xxxxxxxxxx", + NULL +}; + int main(int argc, char *argv[]) { /* init common tones */ diff --git a/src/test/test_dms.c b/src/test/test_dms.c index 2ff50ba..23a91db 100644 --- a/src/test/test_dms.c +++ b/src/test/test_dms.c @@ -71,7 +71,7 @@ void free_nmt(nmt_t *nmt) free(nmt); } -extern void main_mobile(); +extern void main_mobile_loop(); int main(void) { @@ -80,7 +80,7 @@ int main(void) int i, j; /* this is never called, it forces the linker to add mobile functions */ - if (debuglevel == -1000) main_mobile(); + if (debuglevel == -1000) main_mobile_loop(); debuglevel = DEBUG_DEBUG; dms_allow_loopback = 1; diff --git a/src/test/test_sms.c b/src/test/test_sms.c index f65186d..36c892b 100644 --- a/src/test/test_sms.c +++ b/src/test/test_sms.c @@ -98,7 +98,7 @@ void sms_deliver_report(nmt_t *nmt, uint8_t ref, int error, uint8_t cause) printf("(got deliver report from SMS layer)\n"); } -extern void main_mobile(); +extern void main_mobile_loop(); int main(void) { @@ -107,7 +107,7 @@ int main(void) int rc; /* this is never called, it forces the linker to add mobile functions */ - if (debuglevel == -1000) main_mobile(); + if (debuglevel == -1000) main_mobile_loop(); debuglevel = DEBUG_DEBUG; diff --git a/src/zeitansage/main.c b/src/zeitansage/main.c index ede428a..7112f7f 100644 --- a/src/zeitansage/main.c +++ b/src/zeitansage/main.c @@ -69,6 +69,12 @@ static int handle_options(int short_option, int argi, char **argv) return 1; } +static const struct number_lengths number_lengths[] = { + { 0, "no number" }, + { 4, "number '1191'" }, + { 0, NULL }, +}; + int main(int argc, char *argv[]) { int rc, argi; @@ -78,7 +84,8 @@ int main(int argc, char *argv[]) /* init system specific tones */ init_samples(); - main_mobile_init(); + /* init mobile interface */ + main_mobile_init("0123456789", number_lengths, NULL, NULL); /* handle options / config file */ add_options(); @@ -93,7 +100,7 @@ int main(int argc, char *argv[]) fm_init(fast_math); zeit_init(audio_level_dBm, alerting); - main_mobile("zeitansage", &quit, NULL, "1191", 4); + main_mobile_loop("zeitansage", &quit, NULL, "1191"); //fail: /* exits */ -- cgit v1.2.3