aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2021-10-07 19:35:56 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2021-11-07 20:00:42 +0100
commit423bc4242908a4b2082a23bf817e62db2e28c58e (patch)
tree93f8abbccc479cb582fa64435eade239a842cab4
parent3a73f31d7e95cb825c4166e2156fa8e5c39c76e7 (diff)
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.
-rw-r--r--src/amps/amps.c24
-rw-r--r--src/amps/amps_tacs_main.c19
-rw-r--r--src/amps/main.c7
-rw-r--r--src/amps/main.h2
-rw-r--r--src/anetz/anetz.c59
-rw-r--r--src/anetz/anetz.h1
-rw-r--r--src/anetz/main.c22
-rw-r--r--src/bnetz/bnetz.c20
-rw-r--r--src/bnetz/main.c24
-rw-r--r--src/cnetz/cnetz.c58
-rw-r--r--src/cnetz/cnetz.h1
-rw-r--r--src/cnetz/main.c30
-rw-r--r--src/eurosignal/eurosignal.c28
-rw-r--r--src/eurosignal/main.c61
-rwxr-xr-xsrc/fuvst/fuvst.c57
-rwxr-xr-xsrc/fuvst/fuvst.h1
-rwxr-xr-xsrc/fuvst/main.c27
-rw-r--r--src/fuvst/sniffer.c5
-rw-r--r--src/imts/imts.c49
-rw-r--r--src/imts/imts.h4
-rw-r--r--src/imts/main.c51
-rw-r--r--src/jolly/jolly.c12
-rw-r--r--src/jolly/main.c20
-rw-r--r--src/jtacs/main.c3
-rw-r--r--src/libmobile/call.c54
-rw-r--r--src/libmobile/console.c61
-rw-r--r--src/libmobile/console.h2
-rw-r--r--src/libmobile/main_mobile.c169
-rw-r--r--src/libmobile/main_mobile.h18
-rw-r--r--src/mpt1327/main.c22
-rwxr-xr-xsrc/mpt1327/mpt1327.c47
-rwxr-xr-xsrc/mpt1327/mpt1327.h1
-rw-r--r--src/nmt/main.c20
-rw-r--r--src/nmt/nmt.c8
-rw-r--r--src/r2000/main.c17
-rw-r--r--src/r2000/r2000.c60
-rw-r--r--src/r2000/r2000.h1
-rw-r--r--src/tacs/main.c7
-rw-r--r--src/test/test_dms.c4
-rw-r--r--src/test/test_sms.c4
-rw-r--r--src/zeitansage/main.c11
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 <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 */
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 <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 */
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 <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 */
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 <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 */
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 <stdio.h>
#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 <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage);
+ printf("Usage: %s -k <kanal/channel> %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 <stdio.h>
#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 */