diff options
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 2 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 23 | ||||
-rw-r--r-- | openbsc/src/libmsc/db.c | 59 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_subscriber.c | 13 | ||||
-rw-r--r-- | openbsc/tests/vty_test_runner.py | 32 |
5 files changed, 101 insertions, 28 deletions
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 32e0a4e96..6b577b0bf 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -15,6 +15,8 @@ #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 #define tmsi_from_string(str) strtoul(str, NULL, 10) +#define GSM_SUBSCRIBER_NO_EXPIRATION 0x0 + struct vty; struct gsm_equipment { diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b2b7977c7..45df90f5f 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -506,8 +506,13 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) (sp->penalty_time*20)+20, VTY_NEWLINE); } - vty_out(vty, " periodic location update %u%s", - bts->si_common.chan_desc.t3212 * 6, VTY_NEWLINE); + /* Is periodic LU enabled or disabled? */ + if (bts->si_common.chan_desc.t3212 == 0) + vty_out(vty, " no periodic location update%s", VTY_NEWLINE); + else + vty_out(vty, " periodic location update %u%s", + bts->si_common.chan_desc.t3212 * 6, VTY_NEWLINE); + vty_out(vty, " channel allocator %s%s", bts->chan_alloc_reverse ? "descending" : "ascending", VTY_NEWLINE); @@ -2036,6 +2041,19 @@ DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_no_per_loc_upd, cfg_bts_no_per_loc_upd_cmd, + "no periodic location update", + NO_STR + "Periodic Location Updating Interval\n" + "Periodic Location Updating Interval\n" + "Periodic Location Updating Interval\n") +{ + struct gsm_bts *bts = vty->index; + + bts->si_common.chan_desc.t3212 = 0; + return CMD_SUCCESS; +} + #define GPRS_TEXT "GPRS Packet Network\n" DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd, @@ -3053,6 +3071,7 @@ int bsc_vty_init(const struct log_info *cat) install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd); install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd); install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd); + install_element(BTS_NODE, &cfg_bts_no_per_loc_upd_cmd); install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd); install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd); install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd); diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 8a7ff90ca..21abce9de 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -639,7 +639,7 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) if (!dbi_result_field_is_null(result, "expire_lu")) subscr->expire_lu = dbi_result_get_datetime(result, "expire_lu"); else - subscr->expire_lu = 0; + subscr->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION; subscr->authorized = dbi_result_get_uint(result, "authorized"); } @@ -766,23 +766,42 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) } else q_tmsi = strdup("NULL"); - result = dbi_conn_queryf(conn, - "UPDATE Subscriber " - "SET updated = datetime('now'), " - "name = %s, " - "extension = %s, " - "authorized = %i, " - "tmsi = %s, " - "lac = %i, " - "expire_lu = datetime(%i, 'unixepoch') " - "WHERE imsi = %s ", - q_name, - q_extension, - subscriber->authorized, - q_tmsi, - subscriber->lac, - (int) subscriber->expire_lu, - subscriber->imsi); + if (subscriber->expire_lu == GSM_SUBSCRIBER_NO_EXPIRATION) { + result = dbi_conn_queryf(conn, + "UPDATE Subscriber " + "SET updated = datetime('now'), " + "name = %s, " + "extension = %s, " + "authorized = %i, " + "tmsi = %s, " + "lac = %i, " + "expire_lu = NULL " + "WHERE imsi = %s ", + q_name, + q_extension, + subscriber->authorized, + q_tmsi, + subscriber->lac, + subscriber->imsi); + } else { + result = dbi_conn_queryf(conn, + "UPDATE Subscriber " + "SET updated = datetime('now'), " + "name = %s, " + "extension = %s, " + "authorized = %i, " + "tmsi = %s, " + "lac = %i, " + "expire_lu = datetime(%i, 'unixepoch') " + "WHERE imsi = %s ", + q_name, + q_extension, + subscriber->authorized, + q_tmsi, + subscriber->lac, + (int) subscriber->expire_lu, + subscriber->imsi); + } free(q_tmsi); free(q_name); @@ -852,8 +871,8 @@ int db_subscriber_expire(void *priv, void (*callback)(void *priv, long long unsi "SELECT id " "FROM Subscriber " "WHERE lac != 0 AND " - "( expire_lu is NULL " - "OR expire_lu < datetime('now') ) " + "( expire_lu is NOT NULL " + "AND expire_lu < datetime('now') ) " "LIMIT 1"); if (!result) { LOGP(DDB, LOGL_ERROR, "Failed to get expired subscribers\n"); diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index 6abb0d832..5ace8f666 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -333,8 +333,14 @@ int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts) * periodic updating in decihours. Mark the subscriber as * inactive if it missed two consecutive location updates. * Timeout is twice the t3212 value plus one minute */ - s->expire_lu = time(NULL) + + + /* Is expiration handling enabled? */ + if (bts->si_common.chan_desc.t3212 == 0) + s->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION; + else + s->expire_lu = time(NULL) + (bts->si_common.chan_desc.t3212 * 60 * 6 * 2) + 60; + rc = db_sync_subscriber(s); db_subscriber_update(s); return rc; @@ -354,11 +360,6 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason) LOGP(DMM, LOGL_INFO, "Subscriber %s ATTACHED LAC=%u\n", subscr_name(s), s->lac); - /* FIXME: We should allow 0 for T3212 as well to disable the - * location update period. In that case we will need a way to - * indicate that in the database and then reenable that value in - * VTY. - */ /* * The below will set a new expire_lu but as a side-effect * the new lac will be saved in the database. diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 9d283fd97..fb01b8976 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -55,6 +55,37 @@ class TestVTYBase(unittest.TestCase): self.vty = None osmoutil.end_proc(self.proc) +class TestVTYNITB(TestVTYBase): + + def vty_command(self): + return ["./src/osmo-nitb/osmo-nitb", "-c", + "doc/examples/osmo-nitb/nanobts/openbsc.cfg"] + + def vty_app(self): + return (4242, "./src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb") + + def testEnableDisablePeriodicLU(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("network") + self.vty.command("bts 0") + + # Test invalid input + self.vty.verify("periodic location update 0", ['% Unknown command.']) + self.vty.verify("periodic location update 5", ['% Unknown command.']) + self.vty.verify("periodic location update 1531", ['% Unknown command.']) + + # Enable periodic lu.. + self.vty.verify("periodic location update 60", ['']) + res = self.vty.command("write terminal") + self.assertGreater(res.find('periodic location update 60'), 0) + self.assertEquals(res.find('no periodic location update'), -1) + + # Now disable it.. + self.vty.verify("no periodic location update", ['']) + res = self.vty.command("write terminal") + self.assertEquals(res.find('periodic location update 60'), -1) + self.assertGreater(res.find('no periodic location update'), 0) class TestVTYNAT(TestVTYBase): @@ -105,6 +136,7 @@ if __name__ == '__main__': os.chdir(workdir) print "Running tests for specific VTY commands" suite = unittest.TestSuite() + suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYNITB)) add_nat_test(suite, workdir) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) |