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.
This commit is contained in:
Andreas Eversberg 2021-10-07 19:35:56 +02:00
parent 3a73f31d7e
commit 423bc42429
41 changed files with 662 additions and 429 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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[]);

View File

@ -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) {

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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();

View File

@ -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) {

View File

@ -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 */

View File

@ -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? */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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) {

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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;
subscr->type = dialstring[0] - '0';
subscr->relais = (dialstring[1] - '0') * 100 + (dialstring[2] - '0') * 10 + (dialstring[3] - '0');
subscr->mor = atoi(dialstring + 4);
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 = type;
subscr->relais = relais;
subscr->mor = mor;
return 0;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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 */