diff options
Diffstat (limited to 'src/cnetz/database.c')
-rw-r--r-- | src/cnetz/database.c | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/src/cnetz/database.c b/src/cnetz/database.c index 3a7a30b..4bdfb2c 100644 --- a/src/cnetz/database.c +++ b/src/cnetz/database.c @@ -22,32 +22,47 @@ #include <stdlib.h> #include <string.h> #include "../libsample/sample.h" -#include "../libdebug/debug.h" +#include "../liblogging/logging.h" +#include "../libmobile/get_time.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 { struct cnetz_database *next; + int ogk_kanal; /* available on which channel */ uint8_t futln_nat; /* who ... */ uint8_t futln_fuvst; uint16_t futln_rest; int futelg_bit; /* chip card inside */ int extended; /* mobile supports extended frequencies */ - struct timer timer; /* timer for next availability check */ + int eingebucht; /* set if still available */ + double last_seen; + int busy; /* set if currently in a call */ + struct osmo_timer_list timer; /* timer for next availability check */ int retry; /* counts number of retries */ } cnetz_db_t; 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) { @@ -58,39 +73,39 @@ static void remove_db(cnetz_db_t *db) while (*dbp && *dbp != db) dbp = &((*dbp)->next); if (!(*dbp)) { - PDEBUG(DDB, DEBUG_ERROR, "Subscriber not in list, please fix!!\n"); + LOGP(DDB, LOGL_ERROR, "Subscriber not in list, please fix!!\n"); abort(); } *dbp = db->next; - PDEBUG(DDB, DEBUG_INFO, "Removing subscriber '%d,%d,%d' from database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); + LOGP(DDB, LOGL_INFO, "Removing subscriber '%d,%d,%05d' from database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); - timer_exit(&db->timer); + osmo_timer_del(&db->timer); free(db); } /* Timeout handling */ -static void db_timeout(struct timer *timer) +static void db_timeout(void *data) { - cnetz_db_t *db = (cnetz_db_t *)timer->priv; + cnetz_db_t *db = data; int rc; - PDEBUG(DDB, DEBUG_INFO, "Check, if subscriber '%d,%d,%d' is still available.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); + LOGP(DDB, LOGL_INFO, "Check, if subscriber '%d,%d,%05d' is still available.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); - rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest); + rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal); if (rc < 0) { /* OgK is used for speech, but this never happens in a real * 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 */ + LOGP(DDB, LOGL_INFO, "OgK busy, so we assume a positive response.\n"); + osmo_timer_schedule(&db->timer, si.meldeinterval,0); /* when to check avaiability again */ db->retry = 0; } } /* create/update db entry */ -int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed) +int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal, int *futelg_bit, int *extended, int busy, int failed) { cnetz_db_t *db, **dbp; @@ -106,11 +121,12 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t if (!db) { db = calloc(1, sizeof(*db)); if (!db) { - PDEBUG(DDB, DEBUG_ERROR, "No memory!\n"); + LOGP(DDB, LOGL_ERROR, "No memory!\n"); return 0; } - timer_init(&db->timer, db_timeout, db); + osmo_timer_setup(&db->timer, db_timeout, db); + db->eingebucht = 1; db->futln_nat = futln_nat; db->futln_fuvst = futln_fuvst; db->futln_rest = futln_rest; @@ -121,30 +137,37 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t dbp = &((*dbp)->next); *dbp = db; - PDEBUG(DDB, DEBUG_INFO, "Adding subscriber '%d,%d,%d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); + LOGP(DDB, LOGL_INFO, "Adding subscriber '%d,%d,%05d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); } + if (ogk_kanal) + db->ogk_kanal = ogk_kanal; + if (futelg_bit && *futelg_bit >= 0) db->futelg_bit = *futelg_bit; if (extended && *extended >= 0) db->extended = *extended; + db->busy = busy; if (busy) { - PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); - timer_stop(&db->timer); + LOGP(DDB, LOGL_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal); + osmo_timer_del(&db->timer); } else if (!failed) { - PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); - timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability (again) */ + LOGP(DDB, LOGL_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); + osmo_timer_schedule(&db->timer, si.meldeinterval,0); /* 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,%d' failed (try %d of %d).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->retry, MELDE_MAXIMAL); - if (db->retry == MELDE_MAXIMAL) { - remove_db(db); + LOGP(DDB, LOGL_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) { + LOGP(DDB, LOGL_INFO, "Marking subscriber as gone.\n"); + db->eingebucht = 0; return db->extended; } - timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */ + osmo_timer_schedule(&db->timer, (si.meldeinterval < MELDE_WIEDERHOLUNG) ? si.meldeinterval : MELDE_WIEDERHOLUNG,0); /* when to do retry */ } if (futelg_bit) @@ -154,14 +177,17 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t return 0; } -int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended) +int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *ogk_kanal, int *futelg_bit, int *extended) { cnetz_db_t *db = cnetz_db_head; while (db) { - if (db->futln_nat == futln_nat + if (db->eingebucht + && db->futln_nat == futln_nat && db->futln_fuvst == futln_fuvst && db->futln_rest == futln_rest) { + if (ogk_kanal) + *ogk_kanal = db->ogk_kanal; if (futelg_bit) *futelg_bit = db->futelg_bit; if (extended) @@ -182,15 +208,22 @@ void flush_db(void) void dump_db(void) { cnetz_db_t *db = cnetz_db_head; + double now = get_time(); + int last; + char attached[16]; - PDEBUG(DDB, DEBUG_NOTICE, "Dump of subscriber database:\n"); + LOGP(DDB, LOGL_NOTICE, "Dump of subscriber database:\n"); if (!db) { - PDEBUG(DDB, DEBUG_NOTICE, " - No subscribers attached!\n"); + LOGP(DDB, LOGL_NOTICE, " - No subscribers attached!\n"); return; } + LOGP(DDB, LOGL_NOTICE, "Subscriber\tAttached\tBusy\t\tLast seen\tMeldeaufrufe\n"); + LOGP(DDB, LOGL_NOTICE, "-------------------------------------------------------------------------------\n"); while (db) { - PDEBUG(DDB, DEBUG_NOTICE, " - Subscriber '%d,%d,%d' is attached.\n", db->futln_nat, db->futln_fuvst, db->futln_rest); + last = (db->busy) ? 0 : (uint32_t)(now - db->last_seen); + sprintf(attached, "YES (OGK %d)", db->ogk_kanal); + LOGP(DDB, LOGL_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; } } |