C-Netz: Add options to change 'Meldeaufruf' timer and counter.

This commit is contained in:
Andreas Eversberg 2022-06-11 18:50:55 +02:00
parent cb9c85adb5
commit ec286f3d94
5 changed files with 60 additions and 31 deletions

View File

@ -559,7 +559,7 @@ void cnetz_go_idle(cnetz_t *cnetz)
PDEBUG(DCNETZ, DEBUG_NOTICE, "Now channel is available for queued subscriber '%s'.\n", transaction2rufnummer(trans));
trans_new_state(trans, (trans->state == TRANS_MT_QUEUE) ? TRANS_MT_DELAY : TRANS_MO_DELAY);
timer_stop(&trans->timer);
timer_start(&trans->timer, 3.0);
timer_start(&trans->timer, 3.0); /* Wait at least one frame cycles until timeout */
}
}
@ -839,15 +839,6 @@ void transaction_timeout(struct timer *timer)
cnetz_t *cnetz = trans->cnetz;
switch (trans->state) {
case TRANS_WAF:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
if (trans->try == N) {
trans_new_state(trans, TRANS_WBN);
break;
}
trans->try++;
trans_new_state(trans, TRANS_VWG);
break;
case TRANS_MT_QUEUE:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Phone in queue, but still no channel available, releasing call!\n");
call_up_release(trans->callref, CAUSE_NOCHANNEL);
@ -915,12 +906,6 @@ void transaction_timeout(struct timer *timer)
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_MFT:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
/* no response to availability check */
trans->page_failed = 1;
destroy_transaction(trans);
break;
default:
PDEBUG_CHAN(DCNETZ, DEBUG_ERROR, "Timeout unhandled in state %" PRIu64 "\n", trans->state);
}
@ -1134,9 +1119,20 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
telegramm.ogk_vorschlag = CNETZ_STD_OGK_KANAL;
telegramm.fuz_rest_nr = si.fuz_rest;
trans = search_transaction(cnetz, TRANS_VWG | TRANS_MA);
next_candidate:
trans = search_transaction(cnetz, TRANS_VWG | TRANS_WAF | TRANS_MA | TRANS_MFT);
if (trans) {
switch (trans->state) {
case TRANS_WAF:
/* no response to dial request (try again or drop connection) */
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
if (trans->try == N) {
trans_new_state(trans, TRANS_WBN);
goto next_candidate;
}
trans->try++;
trans_new_state(trans, TRANS_VWG);
/* FALLTHRU */
case TRANS_VWG:
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Wahlaufforderung' to outging call\n");
telegramm.opcode = OPCODE_WAF_M;
@ -1144,7 +1140,6 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_WAF);
timer_start(&trans->timer, 3.0); /* Wait at least two frame cycles until resending */
break;
case TRANS_MA:
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending keepalive request 'Meldeaufruf'\n");
@ -1153,8 +1148,13 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_MFT);
timer_start(&trans->timer, 3.0); /* Wait at least two frame cycles until timeout */
break;
case TRANS_MFT:
/* no response to availability check */
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
trans->page_failed = 1;
destroy_transaction(trans);
goto next_candidate;
default:
; /* MLR */
}

View File

@ -25,14 +25,13 @@
#include "../libdebug/debug.h"
#include "cnetz.h"
#include "database.h"
#include "sysinfo.h"
/* the network specs say: check every 1 - 6.5 minutes for availability
* remove from database after 3 subsequent failures
* the phone will register 20 minutes after no call / no paging from network.
*/
#define MELDE_INTERVAL 120.0
#define MELDE_WIEDERHOLUNG 60.0
#define MELDE_MAXIMAL 3
#define MELDE_WIEDERHOLUNG 60.0 /* when busy */
typedef struct cnetz_database {
@ -52,6 +51,17 @@ typedef struct cnetz_database {
cnetz_db_t *cnetz_db_head;
static const char *print_meldeaufrufe(int versuche)
{
static char text[32];
if (versuche <= 0)
return "infinite";
sprintf(text, "%d", versuche);
return text;
}
/* destroy transaction */
static void remove_db(cnetz_db_t *db)
{
@ -88,7 +98,7 @@ static void db_timeout(struct timer *timer)
* network. We just assume that the phone has responded and
* assume we had a response. */
PDEBUG(DDB, DEBUG_INFO, "OgK busy, so we assume a positive response.\n");
timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability again */
timer_start(&db->timer, si.meldeinterval); /* when to check avaiability again */
db->retry = 0;
}
}
@ -144,19 +154,19 @@ int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int o
timer_stop(&db->timer);
} else if (!failed) {
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability (again) */
timer_start(&db->timer, si.meldeinterval); /* when to check avaiability (again) */
db->retry = 0;
db->eingebucht = 1;
db->last_seen = get_time();
} else {
db->retry++;
PDEBUG(DDB, DEBUG_NOTICE, "Paging subscriber '%d,%d,%05d' on OGK channel #%d failed (try %d of %d).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal, db->retry, MELDE_MAXIMAL);
if (db->retry == MELDE_MAXIMAL) {
PDEBUG(DDB, DEBUG_NOTICE, "Paging subscriber '%d,%d,%05d' on OGK channel #%d failed (try %d of %s).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal, db->retry, print_meldeaufrufe(si.meldeaufrufe));
if (si.meldeaufrufe && db->retry == si.meldeaufrufe) {
PDEBUG(DDB, DEBUG_INFO, "Marking subscriber as gone.\n");
db->eingebucht = 0;
return db->extended;
}
timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */
timer_start(&db->timer, (si.meldeinterval < MELDE_WIEDERHOLUNG) ? si.meldeinterval : MELDE_WIEDERHOLUNG); /* when to do retry */
}
if (futelg_bit)
@ -212,7 +222,7 @@ void dump_db(void)
while (db) {
last = (db->busy) ? 0 : (uint32_t)(now - db->last_seen);
sprintf(attached, "YES (OGK %d)", db->ogk_kanal);
PDEBUG(DDB, DEBUG_NOTICE, "%d,%d,%05d\t%s\t%s\t\t%02d:%02d:%02d \t%d/%d\n", db->futln_nat, db->futln_fuvst, db->futln_rest, (db->eingebucht) ? attached : "-no-\t", (db->busy) ? "YES" : "-no-", last / 3600, (last / 60) % 60, last % 60, db->retry, MELDE_MAXIMAL);
PDEBUG(DDB, DEBUG_NOTICE, "%d,%d,%05d\t%s\t%s\t\t%02d:%02d:%02d \t%d/%s\n", db->futln_nat, db->futln_fuvst, db->futln_rest, (db->eingebucht) ? attached : "-no-\t", (db->busy) ? "YES" : "-no-", last / 3600, (last / 60) % 60, last % 60, db->retry, print_meldeaufrufe(si.meldeaufrufe));
db = db->next;
}
}

View File

@ -73,6 +73,8 @@ uint8_t reduzierung = 0; /* factor 4 */
uint8_t nachbar_prio = 0;
int8_t futln_sperre_start = -1; /* no blocking */
int8_t futln_sperre_end = -1; /* no range */
int meldeinterval = 120; /* when to ask the phone about beeing alive */
int meldeaufrufe = 3; /* how many times to ask phone about beeing alive */
enum demod_type demod = FSK_DEMOD_AUTO;
int metering = 20;
double speech_deviation = 4000.0; /* best results with all my equipment */
@ -227,6 +229,12 @@ void print_help(const char *arg0)
} else {
printf(" (default = %d-%d)\n", futln_sperre_start, futln_sperre_end);
}
printf(" -S --sysinfo meldeinterval=<seconds>\n");
printf(" Time to wait until pinging the phone wether it is still available.\n");
printf(" (default = %d)\n", meldeinterval);
printf(" -S --sysinfo meldeaufrufe=<count>\n");
printf(" Number of times we try to ping mobile until we assume it is gone.\n");
printf(" Use '0' for infinite tries. (default = %d)\n", meldeaufrufe);
printf(" -D --demod auto | slope | level\n");
printf(" Adjust demodulation algorithm. Use 'slope' to detect a level change\n");
printf(" by finding the highest slope of a bit transition. It is useful, if\n");
@ -446,6 +454,12 @@ error_fuz:
futln_sperre_end = atoi(q) & 0xf;
}
} else
if (!strncasecmp(argv[argi], "meldeinterval=", p - argv[argi])) {
meldeinterval = atoi_limit(p, 1, 20 * 60);
} else
if (!strncasecmp(argv[argi], "meldeaufrufe=", p - argv[argi])) {
meldeaufrufe = atoi_limit(p, 0, 1000000);
} else
{
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
return -EINVAL;
@ -594,7 +608,7 @@ int main(int argc, char *argv[])
case 4: timeslots=0x01010101; break;
default: timeslots=0x11111111;
}
init_sysinfo(timeslots, fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, bahn_bs, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen);
init_sysinfo(timeslots, fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, bahn_bs, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen, meldeinterval, meldeaufrufe);
dsp_init();
rc = init_telegramm();
if (rc < 0) {

View File

@ -4,7 +4,7 @@
cnetz_si si;
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen)
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe)
{
memset(&si, 0, sizeof(si));
@ -55,5 +55,8 @@ void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_
/* deny group of subscribers. (used to balance subscribers between base stations) */
si.teilnehmergruppensperre = teilnehmergruppensperre;
si.anzahl_gesperrter_teilnehmergruppen = anzahl_gesperrter_teilnehmergruppen;
si.meldeinterval = meldeinterval;
si.meldeaufrufe = meldeaufrufe;
}

View File

@ -21,9 +21,11 @@ typedef struct system_information {
uint8_t reduzierung;
int8_t teilnehmergruppensperre;
int8_t anzahl_gesperrter_teilnehmergruppen;
int meldeinterval; /* when to retry availability check */
int meldeaufrufe; /* 0 for infinite */
} cnetz_si;
extern cnetz_si si;
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen);
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe);