aboutsummaryrefslogtreecommitdiffstats
path: root/src/cnetz/database.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cnetz/database.c')
-rw-r--r--src/cnetz/database.c95
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;
}
}