From ec286f3d943cb90637876da06886b39e6b7b23d1 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 11 Jun 2022 18:50:55 +0200 Subject: [PATCH] C-Netz: Add options to change 'Meldeaufruf' timer and counter. --- src/cnetz/cnetz.c | 38 +++++++++++++++++++------------------- src/cnetz/database.c | 28 +++++++++++++++++++--------- src/cnetz/main.c | 16 +++++++++++++++- src/cnetz/sysinfo.c | 5 ++++- src/cnetz/sysinfo.h | 4 +++- 5 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c index a5b81ac..2ffac27 100644 --- a/src/cnetz/cnetz.c +++ b/src/cnetz/cnetz.c @@ -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 */ } diff --git a/src/cnetz/database.c b/src/cnetz/database.c index 2645191..d52c6da 100644 --- a/src/cnetz/database.c +++ b/src/cnetz/database.c @@ -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; } } diff --git a/src/cnetz/main.c b/src/cnetz/main.c index cdd3c83..cd8fbe2 100644 --- a/src/cnetz/main.c +++ b/src/cnetz/main.c @@ -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=\n"); + printf(" Time to wait until pinging the phone wether it is still available.\n"); + printf(" (default = %d)\n", meldeinterval); + printf(" -S --sysinfo meldeaufrufe=\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) { diff --git a/src/cnetz/sysinfo.c b/src/cnetz/sysinfo.c index 59205d5..43a73ef 100644 --- a/src/cnetz/sysinfo.c +++ b/src/cnetz/sysinfo.c @@ -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; } diff --git a/src/cnetz/sysinfo.h b/src/cnetz/sysinfo.h index 0474dcd..d8c8be1 100644 --- a/src/cnetz/sysinfo.h +++ b/src/cnetz/sysinfo.h @@ -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);