forked from cellular-infrastructure/osmocom-analog
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:
parent
3a73f31d7e
commit
423bc42429
|
@ -893,30 +893,8 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
transaction_t *trans;
|
transaction_t *trans;
|
||||||
uint32_t min1;
|
uint32_t min1;
|
||||||
uint16_t min2;
|
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);
|
amps_number2min(dialing, &min1, &min2);
|
||||||
|
|
||||||
/* 2. check if the subscriber is attached */
|
/* 2. check if the subscriber is attached */
|
||||||
|
|
|
@ -99,8 +99,7 @@ void print_help(const char *arg0)
|
||||||
printf(" If 1, be sure to have a round-trip delay (latency) not more than 5 ms\n");
|
printf(" If 1, be sure to have a round-trip delay (latency) not more than 5 ms\n");
|
||||||
printf(" -O --tolerant\n");
|
printf(" -O --tolerant\n");
|
||||||
printf(" Be more tolerant when hunting for sync sequence\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");
|
main_mobile_print_station_id();
|
||||||
printf(" start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +226,11 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main_amps_tacs(const char *name, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -237,7 +241,7 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
|
||||||
/* override default */
|
/* override default */
|
||||||
dsp_samplerate = 96000;
|
dsp_samplerate = 96000;
|
||||||
|
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -257,10 +261,9 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 10) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 10 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "tones.h"
|
#include "tones.h"
|
||||||
#include "noanswer.h"
|
#include "noanswer.h"
|
||||||
|
@ -8,6 +9,12 @@
|
||||||
const int tacs = 0;
|
const int tacs = 0;
|
||||||
const int jtacs = 0;
|
const int jtacs = 0;
|
||||||
|
|
||||||
|
const char *number_prefixes[] = {
|
||||||
|
"1xxxxxxxxxx",
|
||||||
|
"+1xxxxxxxxxx",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* init common tones */
|
/* init common tones */
|
||||||
|
|
|
@ -2,5 +2,7 @@
|
||||||
extern const int tacs;
|
extern const int tacs;
|
||||||
extern const int jtacs;
|
extern const int jtacs;
|
||||||
|
|
||||||
|
extern const char *number_prefixes[];
|
||||||
|
|
||||||
int main_amps_tacs(const char *name, int argc, char *argv[]);
|
int main_amps_tacs(const char *name, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
|
@ -125,29 +125,19 @@ static struct anetz_dekaden {
|
||||||
{ { 1, 2, 2, 2 } }, /* 9 */
|
{ { 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. */
|
If number is invalid, NULL is returned. */
|
||||||
|
static char anetz_nummer2freq_error[256];
|
||||||
static double *anetz_nummer2freq(const char *nummer)
|
static double *anetz_nummer2freq(const char *nummer)
|
||||||
{
|
{
|
||||||
int f[4];
|
int f[4];
|
||||||
static double freq[4];
|
static double freq[4];
|
||||||
int *dekade;
|
int *dekade;
|
||||||
int i, j, digit;
|
int i, digit;
|
||||||
|
|
||||||
/* get last 5 digits */
|
/* skip prefix */
|
||||||
if (strlen(nummer) < 5) {
|
if (strlen(nummer) == 7)
|
||||||
PDEBUG(DANETZ, DEBUG_ERROR, "Number must have at least 5 digits!\n");
|
nummer += 2;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get decade */
|
/* get decade */
|
||||||
dekade = anetz_gruppenkennziffer[*nummer - '0'].dekade;
|
dekade = anetz_gruppenkennziffer[*nummer - '0'].dekade;
|
||||||
|
@ -161,18 +151,35 @@ static double *anetz_nummer2freq(const char *nummer)
|
||||||
digit = 10;
|
digit = 10;
|
||||||
f[i] = (dekade[i] - 1) * 10 + digit;
|
f[i] = (dekade[i] - 1) * 10 + digit;
|
||||||
freq[i] = anetz_dauerruf_frq(f[i]);
|
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]);
|
/* check if any frequency is used twice */
|
||||||
return NULL;
|
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]);
|
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;
|
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 */
|
/* global init */
|
||||||
int anetz_init(void)
|
int anetz_init(void)
|
||||||
{
|
{
|
||||||
|
@ -381,15 +388,13 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
anetz_t *anetz;
|
anetz_t *anetz;
|
||||||
double *freq;
|
double *freq;
|
||||||
|
|
||||||
/* 1. check if number is invalid, return INVALNUMBER */
|
/* 1. determine paging frequencies */
|
||||||
if (strlen(dialing) > 7) {
|
freq = anetz_nummer2freq(dialing);
|
||||||
inval:
|
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);
|
PDEBUG(DANETZ, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
|
||||||
return -CAUSE_INVALNUMBER;
|
return -CAUSE_INVALNUMBER;
|
||||||
}
|
}
|
||||||
freq = anetz_nummer2freq(dialing);
|
|
||||||
if (!freq)
|
|
||||||
goto inval;
|
|
||||||
|
|
||||||
/* 2. check if given number is already in a call, return BUSY */
|
/* 2. check if given number is already in a call, return BUSY */
|
||||||
for (sender = sender_head; sender; sender = sender->next) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ typedef struct anetz {
|
||||||
|
|
||||||
|
|
||||||
double anetz_kanal2freq(int kanal, int unterband);
|
double anetz_kanal2freq(int kanal, int unterband);
|
||||||
|
const char *anetz_number_valid(const char *number);
|
||||||
int anetz_init(void);
|
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);
|
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);
|
void anetz_destroy(sender_t *sender);
|
||||||
|
|
|
@ -65,8 +65,7 @@ void print_help(const char *arg0)
|
||||||
printf(" and stays below this level, the connection is released.\n");
|
printf(" and stays below this level, the connection is released.\n");
|
||||||
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
|
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
|
||||||
printf(" Only works with SDR! (disabled by default)\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");
|
main_mobile_print_station_id();
|
||||||
printf(" for every start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +120,12 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -134,7 +139,7 @@ int main(int argc, char *argv[])
|
||||||
init_freiton();
|
init_freiton();
|
||||||
init_besetzton();
|
init_besetzton();
|
||||||
|
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, NULL, anetz_number_valid);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -147,12 +152,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 5 && strlen(station_id) != 7) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 7 or (the last) 5 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
if (strlen(station_id) > 5)
|
|
||||||
station_id += strlen(station_id) - 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -693,22 +693,8 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
{
|
{
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
bnetz_t *bnetz;
|
bnetz_t *bnetz;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* 1. check if number is invalid, return INVALNUMBER */
|
/* 1. check if given number is already in a call, return BUSY */
|
||||||
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 */
|
|
||||||
for (sender = sender_head; sender; sender = sender->next) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
bnetz = (bnetz_t *) sender;
|
bnetz = (bnetz_t *) sender;
|
||||||
if (!strcmp(bnetz->station_id, dialing))
|
if (!strcmp(bnetz->station_id, dialing))
|
||||||
|
@ -719,7 +705,7 @@ inval:
|
||||||
return -CAUSE_BUSY;
|
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) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
bnetz = (bnetz_t *) sender;
|
bnetz = (bnetz_t *) sender;
|
||||||
if (bnetz->state == BNETZ_FREI)
|
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);
|
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->callref = callref;
|
||||||
bnetz_page(bnetz, dialing, 1);
|
bnetz_page(bnetz, dialing, 1);
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,7 @@ void print_help(const char *arg0)
|
||||||
printf(" and stays below this level, the connection is released.\n");
|
printf(" and stays below this level, the connection is released.\n");
|
||||||
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
|
printf(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
|
||||||
printf(" Only works with SDR! (disabled by default)\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");
|
main_mobile_print_station_id();
|
||||||
printf(" start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +123,16 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -135,7 +144,7 @@ int main(int argc, char *argv[])
|
||||||
init_besetzton();
|
init_besetzton();
|
||||||
init_ansage();
|
init_ansage();
|
||||||
|
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -148,10 +157,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 5) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 5 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -178,6 +178,28 @@ double cnetz_kanal2freq(int kanal, int unterband)
|
||||||
return freq * 1e6;
|
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 */
|
/* convert power level to P-bits by selecting next higher level */
|
||||||
static uint8_t cnetz_power2bits(int power)
|
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_nat;
|
||||||
uint8_t futln_fuvst;
|
uint8_t futln_fuvst;
|
||||||
int futln_rest; /* use int for checking size > 65535 */
|
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';
|
futln_nat = dialing[0] - '0';
|
||||||
if (len == 7)
|
if (dialing[7]) {
|
||||||
futln_fuvst = dialing[1] - '0';
|
|
||||||
else {
|
|
||||||
futln_fuvst = (dialing[1] - '0') * 10 + (dialing[2] - '0');
|
futln_fuvst = (dialing[1] - '0') * 10 + (dialing[2] - '0');
|
||||||
if (futln_fuvst > 31) {
|
futln_rest = atoi(dialing + 3);
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Digit 2 and 3 '%02d' must not exceed '31', but they do!\n", futln_fuvst);
|
} else {
|
||||||
goto inval;
|
futln_fuvst = dialing[1] - '0';
|
||||||
}
|
futln_rest = atoi(dialing + 2);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. check if the subscriber is attached */
|
/* 2. check if the subscriber is attached */
|
||||||
|
|
|
@ -133,6 +133,7 @@ struct cnetz {
|
||||||
transaction_t *trans_list; /* list of transactions */
|
transaction_t *trans_list; /* list of transactions */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *cnetz_number_valid(const char *number);
|
||||||
double cnetz_kanal2freq(int kanal, int unterband);
|
double cnetz_kanal2freq(int kanal, int unterband);
|
||||||
void cnetz_channel_list(void);
|
void cnetz_channel_list(void);
|
||||||
int cnetz_channel_by_short_name(const char *short_name);
|
int cnetz_channel_by_short_name(const char *short_name);
|
||||||
|
|
|
@ -226,8 +226,7 @@ void print_help(const char *arg0)
|
||||||
printf(" requires a DC coupled signal, which is produced by SDR.\n");
|
printf(" 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(" 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(" 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");
|
main_mobile_print_station_id();
|
||||||
printf(" start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
printf("Press 'i' key to dump list of currently attached subscribers.\n");
|
printf("Press 'i' key to dump list of currently attached subscribers.\n");
|
||||||
}
|
}
|
||||||
|
@ -458,10 +457,24 @@ error_fuz:
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
const char *station_id = "";
|
const char *station_id = NULL;
|
||||||
int mandatory = 0;
|
int mandatory = 0;
|
||||||
int polarity;
|
int polarity;
|
||||||
int teilnehmergruppensperre = 0;
|
int teilnehmergruppensperre = 0;
|
||||||
|
@ -475,7 +488,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
init_station();
|
init_station();
|
||||||
|
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, number_prefixes, cnetz_number_valid);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -488,10 +501,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 7) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* resolve name of base station */
|
/* 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:
|
fail:
|
||||||
flush_db();
|
flush_db();
|
||||||
|
|
|
@ -660,35 +660,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
euro_t *euro;
|
euro_t *euro;
|
||||||
euro_call_t *call;
|
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 */
|
/* find transmitter */
|
||||||
for (sender = sender_head; sender; sender = sender->next) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
|
|
|
@ -81,8 +81,7 @@ void print_help(const char *arg0)
|
||||||
printf(" to page a recevier.\n");
|
printf(" to page a recevier.\n");
|
||||||
printf(" --repeat <num>\n");
|
printf(" --repeat <num>\n");
|
||||||
printf(" Repead paging ID <num> times when transmitting. (default = %d)\n", repeat);
|
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");
|
main_mobile_print_station_id();
|
||||||
printf(" start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,25 +101,6 @@ static void add_options(void)
|
||||||
option_add(OPT_REPEAT, "repeat", 1);
|
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)
|
static int handle_options(int short_option, int argi, char **argv)
|
||||||
{
|
{
|
||||||
switch (short_option) {
|
switch (short_option) {
|
||||||
|
@ -134,20 +114,20 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
rx = 1;
|
rx = 1;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
if (check_id(argv[argi]))
|
if (main_mobile_number_ask(argv[argi], "ID (--id)"))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
euro_add_id(argv[argi]);
|
euro_add_id(mobile_number_remove_prefix(argv[argi]));
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
degraded = 1;
|
degraded = 1;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (check_id(argv[argi]))
|
if (main_mobile_number_ask(argv[argi], "ID to scan from"))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
scan_from = atoi(argv[argi++]);
|
scan_from = atoi(mobile_number_remove_prefix((argv[argi++])));
|
||||||
if (check_id(argv[argi]))
|
if (main_mobile_number_ask(argv[argi], "ID to scan to"))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
scan_to = atoi(argv[argi++]) + 1;
|
scan_to = atoi(mobile_number_remove_prefix(argv[argi++])) + 1;
|
||||||
break;
|
break;
|
||||||
case OPT_RANDOM:
|
case OPT_RANDOM:
|
||||||
random_id = 1;
|
random_id = 1;
|
||||||
|
@ -162,6 +142,21 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -178,8 +173,7 @@ int main(int argc, char *argv[])
|
||||||
init_es_kaudn();
|
init_es_kaudn();
|
||||||
|
|
||||||
/* init mobile interface */
|
/* init mobile interface */
|
||||||
console_digits = "0123456789ABCDE";
|
main_mobile_init("0123456789ABCDEabcde", number_lengths, number_prefixes, NULL);
|
||||||
main_mobile_init();
|
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -192,10 +186,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 6) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given receiver ID '%s' does not have 6 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -52,6 +52,28 @@ extern int alarms;
|
||||||
extern int authentication;
|
extern int authentication;
|
||||||
extern int warmstart;
|
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)
|
static int send_bit(void *inst)
|
||||||
{
|
{
|
||||||
fuvst_t *fuvst = (fuvst_t *)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;
|
uint8_t futln_fuvst;
|
||||||
int futln_rest; /* use int for checking size > 65535 */
|
int futln_rest; /* use int for checking size > 65535 */
|
||||||
int len;
|
int len;
|
||||||
int i;
|
|
||||||
transaction_t *trans;
|
transaction_t *trans;
|
||||||
uint8_t ident;
|
uint8_t ident;
|
||||||
uint8_t opcode, *data;
|
uint8_t opcode, *data;
|
||||||
|
|
||||||
/* 1. check if number is invalid, return INVALNUMBER */
|
/* 1. split number into elements */
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
futln_nat = dialing[0] - '0';
|
futln_nat = dialing[0] - '0';
|
||||||
if (len == 7)
|
if (dialing[7]) {
|
||||||
futln_fuvst = dialing[1] - '0';
|
|
||||||
else {
|
|
||||||
futln_fuvst = (dialing[1] - '0') * 10 + (dialing[2] - '0');
|
futln_fuvst = (dialing[1] - '0') * 10 + (dialing[2] - '0');
|
||||||
if (futln_fuvst > 31) {
|
futln_rest = atoi(dialing + 3);
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Digit 2 and 3 '%02d' must not exceed '31', but they do!\n", futln_fuvst);
|
} else {
|
||||||
goto inval;
|
futln_fuvst = dialing[1] - '0';
|
||||||
}
|
futln_rest = atoi(dialing + 2);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. base station ready? */
|
/* 2. base station ready? */
|
||||||
|
|
|
@ -22,6 +22,7 @@ typedef struct fuvst {
|
||||||
struct SysMeld SM; /* collects alarm messages */
|
struct SysMeld SM; /* collects alarm messages */
|
||||||
} fuvst_t;
|
} 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);
|
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 fuvst_destroy(sender_t *sender);
|
||||||
void add_emergency(const char *number);
|
void add_emergency(const char *number);
|
||||||
|
|
|
@ -73,6 +73,7 @@ void print_help(const char *arg0)
|
||||||
printf(" Don't do any link error checking at MTP.\n");
|
printf(" Don't do any link error checking at MTP.\n");
|
||||||
printf(" -C --bs-config <filename>\n");
|
printf(" -C --bs-config <filename>\n");
|
||||||
printf(" Give DKO config file (6 KBytes tape file) to be loaded at boot time.\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();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +155,20 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -166,10 +181,11 @@ int main(int argc, char *argv[])
|
||||||
init_besetzton();
|
init_besetzton();
|
||||||
init_ansage();
|
init_ansage();
|
||||||
|
|
||||||
|
/* init mobile interface */
|
||||||
allow_sdr = 0;
|
allow_sdr = 0;
|
||||||
uses_emphasis = 0;
|
uses_emphasis = 0;
|
||||||
check_channel = 0;
|
check_channel = 0;
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, number_prefixes, cnetz_number_valid);
|
||||||
|
|
||||||
config_init();
|
config_init();
|
||||||
|
|
||||||
|
@ -189,10 +205,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 7) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_kanal == 1 && num_device == 0)
|
if (num_kanal == 1 && num_device == 0)
|
||||||
|
@ -270,7 +285,7 @@ int main(int argc, char *argv[])
|
||||||
if (config_loaded)
|
if (config_loaded)
|
||||||
printf("BS-Config: %s\n", config_name);
|
printf("BS-Config: %s\n", config_name);
|
||||||
|
|
||||||
main_mobile("fuvst", &quit, NULL, station_id, 7);
|
main_mobile_loop("fuvst", &quit, NULL, station_id);
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -179,10 +179,11 @@ int main(int argc, char *argv[])
|
||||||
func_mtp_receive_lssu = receive_lssu;
|
func_mtp_receive_lssu = receive_lssu;
|
||||||
func_mtp_receive_msu = receive_msu;
|
func_mtp_receive_msu = receive_msu;
|
||||||
|
|
||||||
|
/* init mobile interface */
|
||||||
allow_sdr = 0;
|
allow_sdr = 0;
|
||||||
uses_emphasis = 0;
|
uses_emphasis = 0;
|
||||||
check_channel = 0;
|
check_channel = 0;
|
||||||
main_mobile_init();
|
main_mobile_init(NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -225,7 +226,7 @@ int main(int argc, char *argv[])
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
main_mobile(NULL, &quit, NULL, NULL, 0);
|
main_mobile_loop(NULL, &quit, NULL, NULL);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -262,6 +262,21 @@ double imts_is_canada_only(const char *kanal)
|
||||||
return 0;
|
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 */
|
/* global init */
|
||||||
int imts_init(void)
|
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);
|
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. */
|
/* 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;
|
imts_t *imts;
|
||||||
int rc;
|
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);
|
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->fast_seize = fast_seize;
|
||||||
imts->mode = mode;
|
imts->mode = mode;
|
||||||
imts->operator = operator;
|
imts->operator = operator;
|
||||||
|
@ -809,8 +823,9 @@ static void ani_after_digit(imts_t *imts)
|
||||||
/* update status while receiving station ID */
|
/* update status while receiving station ID */
|
||||||
imts_display_status();
|
imts_display_status();
|
||||||
/* if all digits have been received */
|
/* 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);
|
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);
|
imts_set_dsp_mode(imts, DSP_MODE_TONE, TONE_DIALTONE, 0.0, 0);
|
||||||
timer_start(&imts->timer, DIALTONE_TO);
|
timer_start(&imts->timer, DIALTONE_TO);
|
||||||
imts->dial_number[0] = '\0';
|
imts->dial_number[0] = '\0';
|
||||||
|
@ -821,6 +836,11 @@ static void ani_after_digit(imts_t *imts)
|
||||||
}
|
}
|
||||||
timer_start(&imts->timer, ANI_TO);
|
timer_start(&imts->timer, ANI_TO);
|
||||||
} else {
|
} 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");
|
PDEBUG_CHAN(DIMTS, DEBUG_NOTICE, "Timeout receiving ANI from mobile phone, releasing!\n");
|
||||||
imts_release(imts);
|
imts_release(imts);
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1164,6 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
char number[8];
|
char number[8];
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
imts_t *imts;
|
imts_t *imts;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* 1. 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) {
|
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;
|
return -CAUSE_NOCHANNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3. check if number is invalid, return INVALNUMBER */
|
/* 3. convert 10 digit numbers to 7 digit station ID */
|
||||||
if (strlen(dialing) == 12 && !strncmp(dialing, "+1", 2))
|
if (strlen(dialing) == 10) {
|
||||||
dialing += 2;
|
|
||||||
if (strlen(dialing) == 11 && !strncmp(dialing, "1", 1))
|
|
||||||
dialing += 1;
|
|
||||||
if (strlen(dialing) == 10 && imts->station_length == 7) {
|
|
||||||
strncpy(number, dialing, 3);
|
strncpy(number, dialing, 3);
|
||||||
strcpy(number + 3, dialing + 6);
|
strcpy(number + 3, dialing + 6);
|
||||||
dialing = number;
|
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 */
|
/* 4. trying to page mobile station */
|
||||||
|
PDEBUG_CHAN(DIMTS, DEBUG_INFO, "Call to mobile station, paging number: %s\n", dialing);
|
||||||
imts->callref = callref;
|
imts->callref = callref;
|
||||||
imts_paging(imts, dialing, 0);
|
imts_paging(imts, dialing, 0);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ typedef struct imts {
|
||||||
emphasis_t estate;
|
emphasis_t estate;
|
||||||
int callref; /* call reference */
|
int callref; /* call reference */
|
||||||
char station_id[11]; /* current station ID (also used for test pattern) */
|
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 */
|
char dial_number[33]; /* number dialing */
|
||||||
struct timer timer;
|
struct timer timer;
|
||||||
int last_tone; /* last tone received */
|
int last_tone; /* last tone received */
|
||||||
|
@ -126,10 +125,11 @@ typedef struct imts {
|
||||||
} imts_t;
|
} imts_t;
|
||||||
|
|
||||||
|
|
||||||
|
const char *mts_number_valid(const char *number);
|
||||||
void imts_list_channels(void);
|
void imts_list_channels(void);
|
||||||
double imts_channel2freq(const char *kanal, int uplink);
|
double imts_channel2freq(const char *kanal, int uplink);
|
||||||
int imts_init(void);
|
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_destroy(sender_t *sender);
|
||||||
void imts_loss_indication(imts_t *imts, double loss_time);
|
void imts_loss_indication(imts_t *imts, double loss_time);
|
||||||
void imts_signal_indication(imts_t *imts);
|
void imts_signal_indication(imts_t *imts);
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
/* settings */
|
/* settings */
|
||||||
static double squelch_db = -INFINITY;
|
static double squelch_db = -INFINITY;
|
||||||
static int ptt = 0;
|
static int ptt = 0;
|
||||||
static int station_length = 0; /* defined by mode */
|
|
||||||
static double fast_seize = 0.0;
|
static double fast_seize = 0.0;
|
||||||
static enum mode mode = MODE_IMTS;
|
static enum mode mode = MODE_IMTS;
|
||||||
static char operator[32] = "010";
|
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(" 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(" 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(" 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(" -F --fast-seize <delay in ms>\n");
|
||||||
printf(" To compensate audio processing latency, give delay when to respond,\n");
|
printf(" To compensate audio processing latency, give delay when to respond,\n");
|
||||||
printf(" after detection of Guard tone from mobile phone.\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(" 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(" 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(" 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);
|
main_mobile_print_station_id();
|
||||||
printf(" every start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +94,6 @@ static void add_options(void)
|
||||||
main_mobile_add_options();
|
main_mobile_add_options();
|
||||||
option_add('S', "squelch", 1);
|
option_add('S', "squelch", 1);
|
||||||
option_add('P', "push-to-talk", 0);
|
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('F', "fast-seize", 1);
|
||||||
option_add('D', "decoder-test", 3);
|
option_add('D', "decoder-test", 3);
|
||||||
option_add('M', "mts", 0);
|
option_add('M', "mts", 0);
|
||||||
|
@ -119,12 +112,6 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
case 'P':
|
case 'P':
|
||||||
ptt = 1;
|
ptt = 1;
|
||||||
break;
|
break;
|
||||||
case '5':
|
|
||||||
station_length = 5;
|
|
||||||
break;
|
|
||||||
case '7':
|
|
||||||
station_length = 7;
|
|
||||||
break;
|
|
||||||
case 'F':
|
case 'F':
|
||||||
fast_seize = atof(argv[argi]) / 1000.0;
|
fast_seize = atof(argv[argi]) / 1000.0;
|
||||||
if (fast_seize < 0.0)
|
if (fast_seize < 0.0)
|
||||||
|
@ -150,6 +137,19 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -163,7 +163,8 @@ int main(int argc, char *argv[])
|
||||||
init_invalidnumber();
|
init_invalidnumber();
|
||||||
init_congestion();
|
init_congestion();
|
||||||
|
|
||||||
main_mobile_init();
|
/* init mobile interface */
|
||||||
|
main_mobile_init("0123456789", number_lengths, number_prefixes, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -174,19 +175,15 @@ int main(int argc, char *argv[])
|
||||||
if (argi <= 0)
|
if (argi <= 0)
|
||||||
return argi;
|
return argi;
|
||||||
|
|
||||||
if (!station_length) {
|
/* set check for MTS mode */
|
||||||
if (mode == MODE_IMTS)
|
if (mode == MODE_MTS)
|
||||||
station_length = 7;
|
main_mobile_set_number_check_valid(mts_number_valid);
|
||||||
else
|
|
||||||
station_length = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if ((int)strlen(station_id) != station_length) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have %d digits\n", station_id, station_length);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
if (!num_kanal) {
|
||||||
|
@ -266,7 +263,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* create transceiver instance */
|
/* create transceiver instance */
|
||||||
for (i = 0; i < num_kanal; i++) {
|
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) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
||||||
goto fail;
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -480,13 +480,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
jolly_t *jolly;
|
jolly_t *jolly;
|
||||||
|
|
||||||
/* 1. check if number is invalid, return INVALNUMBER */
|
/* 1. check if given number is already in a call, return BUSY */
|
||||||
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 */
|
|
||||||
for (sender = sender_head; sender; sender = sender->next) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
jolly = (jolly_t *) sender;
|
jolly = (jolly_t *) sender;
|
||||||
if (!strcmp(jolly->station_id, dialing))
|
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;
|
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) {
|
for (sender = sender_head; sender; sender = sender->next) {
|
||||||
jolly = (jolly_t *) sender;
|
jolly = (jolly_t *) sender;
|
||||||
if (jolly->state == STATE_IDLE)
|
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");
|
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->callref = callref;
|
||||||
jolly_page(jolly, dialing);
|
jolly_page(jolly, dialing);
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,7 @@ void print_help(const char *arg0)
|
||||||
printf(" Use transceiver as repeater, so multiple radios can communicate with\n");
|
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(" 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(" 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");
|
main_mobile_print_station_id();
|
||||||
printf(" for every start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +117,11 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct number_lengths number_lengths[] = {
|
||||||
|
{ 4, "number" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -130,7 +134,8 @@ int main(int argc, char *argv[])
|
||||||
init_besetzton();
|
init_besetzton();
|
||||||
// init_ansage();
|
// init_ansage();
|
||||||
|
|
||||||
main_mobile_init();
|
/* init mobile interface */
|
||||||
|
main_mobile_init("0123456789", number_lengths, NULL, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -143,10 +148,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 4) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 4 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
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);
|
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:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include "../amps/main.h"
|
#include "../amps/main.h"
|
||||||
#include "../amps/tones.h"
|
#include "../amps/tones.h"
|
||||||
#include "../amps/outoforder.h"
|
#include "../amps/outoforder.h"
|
||||||
|
@ -5,6 +6,8 @@
|
||||||
const int tacs = 1;
|
const int tacs = 1;
|
||||||
const int jtacs = 1;
|
const int jtacs = 1;
|
||||||
|
|
||||||
|
const char *number_prefixes[] = { NULL };
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* init common tones */
|
/* init common tones */
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "cause.h"
|
#include "cause.h"
|
||||||
#include "sender.h"
|
#include "sender.h"
|
||||||
#include "call.h"
|
#include "call.h"
|
||||||
|
#include "main_mobile.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
#define DISC_TIMEOUT 30
|
#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;
|
uint16_t sip_cause;
|
||||||
uint8_t type, plan, present, screen, caller_type;
|
uint8_t type, plan, present, screen, caller_type;
|
||||||
char caller_id[33], number[33];
|
char caller_id[33], number[33];
|
||||||
|
const char *suffix, *invalid;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
process = get_process(callref);
|
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);
|
sdp = osmo_cc_helper_audio_accept(&ep->session_config, process, codecs, down_audio, msg, &process->session, &process->codec, 0);
|
||||||
if (!sdp) {
|
if (!sdp) {
|
||||||
disconnect_process(callref, 47);
|
disconnect_process(callref, 47);
|
||||||
|
indicate_disconnect_release(callref, 47, OSMO_CC_MSG_REJ_IND);
|
||||||
break;
|
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)
|
if (present == OSMO_CC_PRESENT_RESTRICTED)
|
||||||
caller_type = TYPE_ANONYMOUS;
|
caller_type = TYPE_ANONYMOUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dialing */
|
/* dialing */
|
||||||
rc = osmo_cc_get_ie_called(msg, 0, &type, &plan, number, sizeof(number));
|
rc = osmo_cc_get_ie_called(msg, 0, &type, &plan, number, sizeof(number));
|
||||||
if (rc < 0)
|
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);
|
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) {
|
if (rc < 0) {
|
||||||
PDEBUG(DCALL, DEBUG_NOTICE, "Call rejected, cause %d\n", -rc);
|
PDEBUG(DCALL, DEBUG_NOTICE, "Call rejected, cause %d\n", -rc);
|
||||||
if (!connect_on_setup) {
|
if (!connect_on_setup) {
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "../libosmocc/endpoint.h"
|
#include "../libosmocc/endpoint.h"
|
||||||
#include "../libosmocc/helper.h"
|
#include "../libosmocc/helper.h"
|
||||||
#include "testton.h"
|
#include "testton.h"
|
||||||
|
#include "../libmobile/main_mobile.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "cause.h"
|
#include "cause.h"
|
||||||
#include "../libmobile/call.h"
|
#include "../libmobile/call.h"
|
||||||
|
@ -77,7 +78,8 @@ typedef struct console {
|
||||||
int test_audio_pos; /* position for test tone toward mobile */
|
int test_audio_pos; /* position for test tone toward mobile */
|
||||||
sample_t tx_buffer[160];/* transmit audio buffer */
|
sample_t tx_buffer[160];/* transmit audio buffer */
|
||||||
int tx_buffer_pos; /* current position in 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 loopback; /* loopback test for echo */
|
||||||
int echo_test; /* send echo back to mobile phone */
|
int echo_test; /* send echo back to mobile phone */
|
||||||
const char *digits; /* list of dialable digits */
|
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);
|
osmo_cc_free_msg(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (caller_id[0]) {
|
if (caller_id[0])
|
||||||
strncpy(console.station_id, caller_id, console.num_digits);
|
strncpy(console.station_id, caller_id, sizeof(console.station_id) - 1);
|
||||||
console.station_id[console.num_digits] = '\0';
|
|
||||||
}
|
|
||||||
strncpy(console.dialing, number, sizeof(console.dialing) - 1);
|
strncpy(console.dialing, number, sizeof(console.dialing) - 1);
|
||||||
console.dialing[sizeof(console.dialing) - 1] = '\0';
|
console.dialing[sizeof(console.dialing) - 1] = '\0';
|
||||||
console_new_state(CONSOLE_CONNECT);
|
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);
|
PDEBUG(DCC, DEBUG_INFO, "Call connected to '%s'\n", caller_id);
|
||||||
osmo_cc_helper_audio_negotiate(msg, &console.session, &console.codec);
|
osmo_cc_helper_audio_negotiate(msg, &console.session, &console.codec);
|
||||||
console_new_state(CONSOLE_CONNECT);
|
console_new_state(CONSOLE_CONNECT);
|
||||||
strncpy(console.station_id, caller_id, console.num_digits);
|
if (caller_id[0])
|
||||||
console.station_id[console.num_digits] = '\0';
|
strncpy(console.station_id, caller_id, sizeof(console.station_id) - 1);
|
||||||
request_answer_ack(console.callref);
|
request_answer_ack(console.callref);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -358,9 +358,10 @@ static void _print_console_text(void)
|
||||||
printf("\033[0;39m");
|
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 rc = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
init_testton();
|
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;
|
print_console_text = _print_console_text;
|
||||||
|
|
||||||
memset(&console, 0, sizeof(console));
|
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);
|
strncpy(console.audiodev, audiodev, sizeof(console.audiodev) - 1);
|
||||||
console.samplerate = samplerate;
|
console.samplerate = samplerate;
|
||||||
console.buffer_size = buffer * samplerate / 1000;
|
console.buffer_size = buffer * samplerate / 1000;
|
||||||
console.num_digits = num_digits;
|
|
||||||
console.loopback = loopback;
|
console.loopback = loopback;
|
||||||
console.echo_test = echo_test;
|
console.echo_test = echo_test;
|
||||||
console.digits = digits;
|
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])
|
if (!audiodev[0])
|
||||||
return 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)
|
static void process_ui(int c)
|
||||||
{
|
{
|
||||||
char text[256] = "";
|
char text[256] = "";
|
||||||
|
@ -460,7 +471,7 @@ static void process_ui(int c)
|
||||||
switch (console.state) {
|
switch (console.state) {
|
||||||
case CONSOLE_IDLE:
|
case CONSOLE_IDLE:
|
||||||
if (c > 0) {
|
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++) {
|
for (i = 0; i < (int)strlen(console.digits); i++) {
|
||||||
if (c == console.digits[i]) {
|
if (c == console.digits[i]) {
|
||||||
console.station_id[strlen(console.station_id) + 1] = '\0';
|
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))
|
if ((c == 8 || c == 127) && strlen(console.station_id))
|
||||||
console.station_id[strlen(console.station_id) - 1] = '\0';
|
console.station_id[strlen(console.station_id) - 1] = '\0';
|
||||||
dial_after_hangup:
|
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);
|
PDEBUG(DCC, DEBUG_INFO, "Outgoing call to '%s'\n", console.station_id);
|
||||||
console.dialing[0] = '\0';
|
console.dialing[0] = '\0';
|
||||||
console_new_state(CONSOLE_SETUP_RT);
|
console_new_state(CONSOLE_SETUP_RT);
|
||||||
|
@ -479,10 +495,19 @@ dial_after_hangup:
|
||||||
request_setup(console.callref, console.station_id);
|
request_setup(console.callref, console.station_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (console.num_digits != (int)strlen(console.station_id))
|
sprintf(text, "on-hook: %s%s ", console.station_id, "................................" + 32 - console.number_max_length + 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));
|
len = strlen(console.station_id);
|
||||||
else
|
for (i = 0; console.number_lengths[i].usage; i++) {
|
||||||
sprintf(text, "on-hook: %s (press d=dial)\r", console.station_id);
|
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;
|
break;
|
||||||
case CONSOLE_SETUP_RO:
|
case CONSOLE_SETUP_RO:
|
||||||
case CONSOLE_SETUP_RT:
|
case CONSOLE_SETUP_RT:
|
||||||
|
@ -538,7 +563,7 @@ dial_after_hangup:
|
||||||
* returns 1 on exit (ctrl+c) */
|
* returns 1 on exit (ctrl+c) */
|
||||||
void process_console(int c)
|
void process_console(int c)
|
||||||
{
|
{
|
||||||
if (!console.loopback && console.num_digits)
|
if (!console.loopback && console.number_max_length)
|
||||||
process_ui(c);
|
process_ui(c);
|
||||||
|
|
||||||
if (console.session)
|
if (console.session)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
void console_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg);
|
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);
|
void console_cleanup(void);
|
||||||
int console_open_audio(int buffer_size, double interval);
|
int console_open_audio(int buffer_size, double interval);
|
||||||
int console_start_audio(void);
|
int console_start_audio(void);
|
||||||
|
|
|
@ -80,21 +80,147 @@ const char *write_tx_wave = NULL;
|
||||||
const char *write_rx_wave = NULL;
|
const char *write_rx_wave = NULL;
|
||||||
const char *read_tx_wave = NULL;
|
const char *read_tx_wave = NULL;
|
||||||
const char *read_rx_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");
|
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;
|
got_init = 1;
|
||||||
#ifdef HAVE_SDR
|
#ifdef HAVE_SDR
|
||||||
sdr_config_init(DEFAULT_LO_OFFSET);
|
sdr_config_init(DEFAULT_LO_OFFSET);
|
||||||
#endif
|
#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)
|
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("\nGlobal options:\n");
|
||||||
/* - - */
|
/* - - */
|
||||||
printf(" -h --help\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");
|
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)
|
void main_mobile_print_hotkeys(void)
|
||||||
{
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -440,7 +593,7 @@ static int get_char()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through all transceiver instances of one network. */
|
/* 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;
|
int buffer_size;
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
|
@ -454,6 +607,10 @@ void main_mobile(const char *name, int *quit, void (*myhandler)(void), const cha
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* station id preset */
|
||||||
|
if (station_id)
|
||||||
|
station_id = mobile_number_remove_prefix(station_id);
|
||||||
|
|
||||||
/* size of dsp buffer in samples */
|
/* size of dsp buffer in samples */
|
||||||
buffer_size = dsp_samplerate * dsp_buffer / 1000;
|
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 */
|
/* init OSMO-CC */
|
||||||
if (!use_osmocc_sock)
|
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 */
|
/* init call control instance */
|
||||||
rc = call_init(name, (use_osmocc_sock) ? send_patterns : 0, release_on_disconnect, use_osmocc_sock, cc_argc, cc_argv);
|
rc = call_init(name, (use_osmocc_sock) ? send_patterns : 0, release_on_disconnect, use_osmocc_sock, cc_argc, cc_argv);
|
||||||
|
|
|
@ -22,11 +22,23 @@ extern const char *write_rx_wave;
|
||||||
extern const char *write_tx_wave;
|
extern const char *write_tx_wave;
|
||||||
extern const char *read_rx_wave;
|
extern const char *read_rx_wave;
|
||||||
extern const char *read_tx_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_help(const char *arg0, const char *ext_usage);
|
||||||
void main_mobile_print_hotkeys(void);
|
void main_mobile_print_hotkeys(void);
|
||||||
|
void main_mobile_print_station_id(void);
|
||||||
void main_mobile_add_options(void);
|
void main_mobile_add_options(void);
|
||||||
int main_mobile_handle_options(int short_option, int argi, char **argv);
|
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;
|
extern int quit;
|
||||||
void sighandler(int sigset);
|
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);
|
void dump_info(void);
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,7 @@ void print_help(const char *arg0)
|
||||||
printf(" and stays below this level, the connection is released.\n");
|
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(" Use 'auto' to do automatic noise floor calibration to detect loss.\n");
|
||||||
printf(" Only works with SDR! (disabled by default)\n");
|
printf(" Only works with SDR! (disabled by default)\n");
|
||||||
|
main_mobile_print_station_id();
|
||||||
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_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
printf("Press 'i' key to dump list of seen Radio Units.\n");
|
printf("Press 'i' key to dump list of seen Radio Units.\n");
|
||||||
}
|
}
|
||||||
|
@ -252,6 +250,11 @@ sysdef_oor:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct number_lengths number_lengths[] = {
|
||||||
|
{ 7, "number 'pppiiii' (prefix, ident)" },
|
||||||
|
{ 0, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -264,8 +267,8 @@ int main(int argc, char *argv[])
|
||||||
init_besetzton();
|
init_besetzton();
|
||||||
// init_ansage();
|
// init_ansage();
|
||||||
|
|
||||||
console_digits = "0123456789*#";
|
/* init mobile interface */
|
||||||
main_mobile_init();
|
main_mobile_init("0123456789", number_lengths, NULL, mpt1327_number_valid);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -278,10 +281,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 7) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 4 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
if (!num_kanal) {
|
||||||
|
@ -380,7 +382,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
mpt1327_check_channels();
|
mpt1327_check_channels();
|
||||||
|
|
||||||
main_mobile("mpt1327", &quit, NULL, station_id, 7);
|
main_mobile_loop("mpt1327", &quit, NULL, station_id);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
|
|
||||||
/* Timers and counters */
|
/* Timers and counters */
|
||||||
#define RESPONSE_TIMEOUT 1.0
|
#define RESPONSE_TIMEOUT 1.0
|
||||||
#define REPEAT_GTC 1
|
#define REPEAT_GTC 1
|
||||||
|
@ -88,8 +89,30 @@
|
||||||
#define REPEAT_AHYX 3
|
#define REPEAT_AHYX 3
|
||||||
#define REPEAT_CLEAR 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;
|
static mpt1327_sysdef_t sysdef;
|
||||||
|
@ -1536,28 +1559,10 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
mpt1327_t *tc;
|
mpt1327_t *tc;
|
||||||
uint8_t prefix;
|
uint8_t prefix;
|
||||||
uint16_t ident;
|
uint16_t ident;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* 1. check if number is invalid, return INVALNUMBER */
|
/* 1. split number into prefix and ident */
|
||||||
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;
|
|
||||||
}
|
|
||||||
prefix = (dialing[0] - '0') * 100 + (dialing[1] - '0') * 10 + (dialing[2] - '0');
|
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);
|
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 */
|
/* 2. check if given number is already in a call, return BUSY */
|
||||||
unit = get_unit(prefix, ident);
|
unit = get_unit(prefix, ident);
|
||||||
|
|
|
@ -139,6 +139,7 @@ typedef struct mpt1327 {
|
||||||
void init_sysdef (uint16_t sys, int wt, int per, int pon, int timeout);
|
void init_sysdef (uint16_t sys, int wt, int per, int pon, int timeout);
|
||||||
void flush_units(void);
|
void flush_units(void);
|
||||||
double mpt1327_channel2freq(enum mpt1327_band band, int channel, int uplink);
|
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);
|
const char *mpt1327_band_name(enum mpt1327_band band);
|
||||||
void mpt1327_band_list(void);
|
void mpt1327_band_list(void);
|
||||||
int mpt1327_band_by_short_name(const char *short_name);
|
int mpt1327_band_by_short_name(const char *short_name);
|
||||||
|
|
|
@ -93,8 +93,7 @@ void print_help(const char *arg0)
|
||||||
printf(" Message Service Center). (default = '%s')\n", smsc_number);
|
printf(" Message Service Center). (default = '%s')\n", smsc_number);
|
||||||
printf(" -I --caller-id 1 | 0\n");
|
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(" 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");
|
main_mobile_print_station_id();
|
||||||
printf(" for every start of this program.\n");
|
|
||||||
main_mobile_print_hotkeys();
|
main_mobile_print_hotkeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +257,11 @@ int submit_sms(const char *sms)
|
||||||
return 0;
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -269,7 +273,8 @@ int main(int argc, char *argv[])
|
||||||
init_nmt_tones();
|
init_nmt_tones();
|
||||||
init_announcement();
|
init_announcement();
|
||||||
|
|
||||||
main_mobile_init();
|
/* init mobile interface */
|
||||||
|
main_mobile_init("0123456789", number_lengths, NULL, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -282,10 +287,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 7) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
if (!num_kanal) {
|
||||||
|
@ -407,7 +411,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
nmt_check_channels(nmt_system);
|
nmt_check_channels(nmt_system);
|
||||||
|
|
||||||
main_mobile("nmt", &quit, myhandler, station_id, 7);
|
main_mobile_loop("nmt", &quit, myhandler, station_id);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* fifo */
|
/* fifo */
|
||||||
|
|
|
@ -1712,22 +1712,16 @@ int _out_setup(int callref, const char *caller_id, enum number_type caller_type,
|
||||||
{
|
{
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
nmt_t *nmt;
|
nmt_t *nmt;
|
||||||
int i;
|
|
||||||
nmt_subscriber_t subscr;
|
nmt_subscriber_t subscr;
|
||||||
transaction_t *trans;
|
transaction_t *trans;
|
||||||
|
|
||||||
memset(&subscr, 0, sizeof(subscr));
|
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)) {
|
if (dialstring2number(dialing, &subscr.country, subscr.number)) {
|
||||||
inval:
|
|
||||||
PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
|
PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
|
||||||
return -CAUSE_INVALNUMBER;
|
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 */
|
/* 2. check if given number is already in a call, return BUSY */
|
||||||
trans = get_transaction_by_number(&subscr);
|
trans = get_transaction_by_number(&subscr);
|
||||||
|
|
|
@ -247,6 +247,11 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct number_lengths number_lengths[] = {
|
||||||
|
{ 9, "number 'trrrnnnnn' (type, relais, number)" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -257,7 +262,8 @@ int main(int argc, char *argv[])
|
||||||
/* init tones */
|
/* init tones */
|
||||||
init_radiocom_tones();
|
init_radiocom_tones();
|
||||||
|
|
||||||
main_mobile_init();
|
/* init mobile interface */
|
||||||
|
main_mobile_init("0123456789", number_lengths, NULL, r2000_number_valid);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -270,10 +276,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
station_id = argv[argi];
|
station_id = argv[argi];
|
||||||
if (strlen(station_id) != 9) {
|
rc = main_mobile_number_ask(station_id, "station ID");
|
||||||
printf("Given station ID '%s' does not have 9 digits\n", station_id);
|
if (rc)
|
||||||
return 0;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num_kanal) {
|
if (!num_kanal) {
|
||||||
|
@ -363,7 +368,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
r2000_check_channels();
|
r2000_check_channels();
|
||||||
|
|
||||||
main_mobile("radiocom2000", &quit, NULL, station_id, 9);
|
main_mobile_loop("radiocom2000", &quit, NULL, station_id);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* destroy transceiver instance */
|
/* destroy transceiver instance */
|
||||||
|
|
|
@ -120,6 +120,21 @@ double r2000_channel2freq(int band, int channel, int uplink)
|
||||||
return freq * 1e6;
|
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)
|
const char *r2000_state_name(enum r2000_state state)
|
||||||
{
|
{
|
||||||
static char invalid[16];
|
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 */
|
/* convert 9-digits dial string to station mobile data */
|
||||||
static int string2subscriber(const char *dialstring, r2000_subscriber_t *subscr)
|
static int string2subscriber(const char *dialstring, r2000_subscriber_t *subscr)
|
||||||
{
|
{
|
||||||
char check[6];
|
subscr->type = dialstring[0] - '0';
|
||||||
int type, relais, mor;
|
subscr->relais = (dialstring[1] - '0') * 100 + (dialstring[2] - '0') * 10 + (dialstring[3] - '0');
|
||||||
int i;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ void r2000_destroy(sender_t *sender);
|
||||||
void r2000_go_idle(r2000_t *r2000);
|
void r2000_go_idle(r2000_t *r2000);
|
||||||
void r2000_band_list(void);
|
void r2000_band_list(void);
|
||||||
double r2000_channel2freq(int band, int channel, int uplink);
|
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);
|
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_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);
|
void r2000_receive_super(r2000_t *r2000, uint8_t super, double quality, double level);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include "../amps/main.h"
|
#include "../amps/main.h"
|
||||||
#include "../amps/tones.h"
|
#include "../amps/tones.h"
|
||||||
#include "../amps/outoforder.h"
|
#include "../amps/outoforder.h"
|
||||||
|
@ -5,6 +6,12 @@
|
||||||
const int tacs = 1;
|
const int tacs = 1;
|
||||||
const int jtacs = 0;
|
const int jtacs = 0;
|
||||||
|
|
||||||
|
const char *number_prefixes[] = {
|
||||||
|
"0xxxxxxxxxx",
|
||||||
|
"+44xxxxxxxxxx",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* init common tones */
|
/* init common tones */
|
||||||
|
|
|
@ -71,7 +71,7 @@ void free_nmt(nmt_t *nmt)
|
||||||
free(nmt);
|
free(nmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void main_mobile();
|
extern void main_mobile_loop();
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +80,7 @@ int main(void)
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
/* this is never called, it forces the linker to add mobile functions */
|
/* 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;
|
debuglevel = DEBUG_DEBUG;
|
||||||
dms_allow_loopback = 1;
|
dms_allow_loopback = 1;
|
||||||
|
|
|
@ -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");
|
printf("(got deliver report from SMS layer)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void main_mobile();
|
extern void main_mobile_loop();
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +107,7 @@ int main(void)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* this is never called, it forces the linker to add mobile functions */
|
/* 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;
|
debuglevel = DEBUG_DEBUG;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,12 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct number_lengths number_lengths[] = {
|
||||||
|
{ 0, "no number" },
|
||||||
|
{ 4, "number '1191'" },
|
||||||
|
{ 0, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, argi;
|
int rc, argi;
|
||||||
|
@ -78,7 +84,8 @@ int main(int argc, char *argv[])
|
||||||
/* init system specific tones */
|
/* init system specific tones */
|
||||||
init_samples();
|
init_samples();
|
||||||
|
|
||||||
main_mobile_init();
|
/* init mobile interface */
|
||||||
|
main_mobile_init("0123456789", number_lengths, NULL, NULL);
|
||||||
|
|
||||||
/* handle options / config file */
|
/* handle options / config file */
|
||||||
add_options();
|
add_options();
|
||||||
|
@ -93,7 +100,7 @@ int main(int argc, char *argv[])
|
||||||
fm_init(fast_math);
|
fm_init(fast_math);
|
||||||
zeit_init(audio_level_dBm, alerting);
|
zeit_init(audio_level_dBm, alerting);
|
||||||
|
|
||||||
main_mobile("zeitansage", &quit, NULL, "1191", 4);
|
main_mobile_loop("zeitansage", &quit, NULL, "1191");
|
||||||
|
|
||||||
//fail:
|
//fail:
|
||||||
/* exits */
|
/* exits */
|
||||||
|
|
Loading…
Reference in New Issue