aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-12-24 21:43:14 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-12-24 21:43:14 +0100
commitee139e725386b1df7e482ea76b143fc931a48470 (patch)
treeb0357b2a8b90918d9f73de1314aae9eb72c33111
parenta29e43a26fae23d5132461cf7bfa43a1ca64761f (diff)
parentabd0cac0c52d52d40ac0d51710010fee28200f3d (diff)
Merge branch 'zecke/subscr'
-rw-r--r--openbsc/include/openbsc/db.h1
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h3
-rw-r--r--openbsc/src/bsc_vty.c14
-rw-r--r--openbsc/src/db.c72
-rw-r--r--openbsc/src/gsm_subscriber.c5
-rw-r--r--openbsc/src/gsm_subscriber_base.c17
-rw-r--r--openbsc/src/vty_interface_layer3.c34
8 files changed, 129 insertions, 20 deletions
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index 8bf361fc8..ba7c5a74b 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -49,6 +49,7 @@ int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber);
int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, u_int32_t* token);
int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei);
int db_sync_equipment(struct gsm_equipment *equip);
+int db_subscriber_update(struct gsm_subscriber *subscriber);
/* auth info */
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index b9ec94cf9..f42ae1b4a 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -730,6 +730,9 @@ struct gsm_network {
/* MSC data in case we are a true BSC */
struct osmo_msc_data *msc_data;
int hardcoded_rtp_payload;
+
+ /* subscriber related features */
+ int keep_subscr;
};
#define SMS_HDR_SIZE 128
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index c688c0195..29317e822 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -90,6 +90,9 @@ struct gsm_subscriber *subscr_active_by_imsi(struct gsm_network *net,
char *subscr_name(struct gsm_subscriber *subscr);
+int subscr_purge_inactive(struct gsm_network *net);
+void subscr_update_from_db(struct gsm_subscriber *subscr);
+
/* internal */
struct gsm_subscriber *subscr_alloc(void);
extern struct llist_head active_subscribers;
diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c
index 82737e3c7..71fd9b5be 100644
--- a/openbsc/src/bsc_vty.c
+++ b/openbsc/src/bsc_vty.c
@@ -550,6 +550,8 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " timer t3122 %u%s", gsmnet->T3122, VTY_NEWLINE);
vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE);
vty_out(vty, " dtx-used %u%s", gsmnet->dtx_enabled, VTY_NEWLINE);
+ vty_out(vty, " subscriber-keep-in-ram %d%s",
+ gsmnet->keep_subscr, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1360,6 +1362,17 @@ DEFUN(cfg_net_dtx,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_subscr_keep,
+ cfg_net_subscr_keep_cmd,
+ "subscriber-keep-in-ram (0|1)",
+ "Keep unused subscribers in RAM.\n"
+ "Delete unused subscribers\n" "Keep unused subscribers\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->keep_subscr = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
/* per-BTS configuration */
DEFUN(cfg_bts,
cfg_bts_cmd,
@@ -2552,6 +2565,7 @@ int bsc_vty_init(void)
install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
+ install_element(GSMNET_NODE, &cfg_net_subscr_keep_cmd);
install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
install_element(GSMNET_NODE, &cfg_bts_cmd);
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index d67208193..ec1e72ce9 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -558,13 +558,35 @@ int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
return 0;
}
+static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result)
+{
+ const char *string;
+ string = dbi_result_get_string(result, "imsi");
+ if (string)
+ strncpy(subscr->imsi, string, GSM_IMSI_LENGTH);
+
+ string = dbi_result_get_string(result, "tmsi");
+ if (string)
+ subscr->tmsi = tmsi_from_string(string);
+
+ string = dbi_result_get_string(result, "name");
+ if (string)
+ strncpy(subscr->name, string, GSM_NAME_LENGTH);
+
+ string = dbi_result_get_string(result, "extension");
+ if (string)
+ strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH);
+
+ subscr->lac = dbi_result_get_uint(result, "lac");
+ subscr->authorized = dbi_result_get_uint(result, "authorized");
+}
+
#define BASE_QUERY "SELECT * FROM Subscriber "
struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
enum gsm_subscriber_field field,
const char *id)
{
dbi_result result;
- const char *string;
char *quoted;
struct gsm_subscriber *subscr;
@@ -621,24 +643,8 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
subscr = subscr_alloc();
subscr->net = net;
subscr->id = dbi_result_get_ulonglong(result, "id");
- string = dbi_result_get_string(result, "imsi");
- if (string)
- strncpy(subscr->imsi, string, GSM_IMSI_LENGTH);
-
- string = dbi_result_get_string(result, "tmsi");
- if (string)
- subscr->tmsi = tmsi_from_string(string);
-
- string = dbi_result_get_string(result, "name");
- if (string)
- strncpy(subscr->name, string, GSM_NAME_LENGTH);
-
- string = dbi_result_get_string(result, "extension");
- if (string)
- strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH);
- subscr->lac = dbi_result_get_uint(result, "lac");
- subscr->authorized = dbi_result_get_uint(result, "authorized");
+ db_set_from_query(subscr, result);
DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n",
subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension,
subscr->lac, subscr->authorized);
@@ -649,6 +655,36 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
return subscr;
}
+int db_subscriber_update(struct gsm_subscriber *subscr)
+{
+ char buf[32];
+ char *quoted;
+ dbi_result result;
+
+ /* Copy the id to a string as queryf with %llu is failing */
+ sprintf(buf, "%llu", subscr->id);
+ result = dbi_conn_queryf(conn,
+ BASE_QUERY
+ "WHERE id = %s", buf);
+
+ if (!result) {
+ LOGP(DDB, LOGL_ERROR, "Failed to query Subscriber: %llu\n", subscr->id);
+ return -EIO;
+ }
+ if (!dbi_result_next_row(result)) {
+ DEBUGP(DDB, "Failed to find the Subscriber. %llu\n",
+ subscr->id);
+ dbi_result_free(result);
+ return -EIO;
+ }
+
+ db_set_from_query(subscr, result);
+ dbi_result_free(result);
+ get_equipment_by_subscr(subscr);
+
+ return 0;
+}
+
int db_sync_subscriber(struct gsm_subscriber *subscriber)
{
dbi_result result;
diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c
index ed76e453b..f066eca67 100644
--- a/openbsc/src/gsm_subscriber.c
+++ b/openbsc/src/gsm_subscriber.c
@@ -318,4 +318,7 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
return db_sync_subscriber(s);
}
-
+void subscr_update_from_db(struct gsm_subscriber *sub)
+{
+ db_subscriber_update(sub);
+}
diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c
index 3136ebedd..8872a9ade 100644
--- a/openbsc/src/gsm_subscriber_base.c
+++ b/openbsc/src/gsm_subscriber_base.c
@@ -86,7 +86,7 @@ struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
subscr->use_count--;
DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
subscr->extension, subscr->use_count);
- if (subscr->use_count <= 0)
+ if (subscr->use_count <= 0 && !subscr->net->keep_subscr)
subscr_free(subscr);
return NULL;
}
@@ -133,3 +133,18 @@ struct gsm_subscriber *subscr_active_by_imsi(struct gsm_network *net, const char
return NULL;
}
+
+int subscr_purge_inactive(struct gsm_network *net)
+{
+ struct gsm_subscriber *subscr, *tmp;
+ int purged = 0;
+
+ llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscriber(), entry) {
+ if (subscr->net == net && subscr->use_count <= 0) {
+ subscr_free(subscr);
+ purged += 1;
+ }
+ }
+
+ return purged;
+}
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index cc6bd9470..055265329 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -536,6 +536,38 @@ DEFUN(ena_subscr_a3a8,
return rc ? CMD_WARNING : CMD_SUCCESS;
}
+DEFUN(subscriber_purge,
+ subscriber_purge_cmd,
+ "subscriber purge-inactive",
+ "Operations on a Subscriber\n" "Purge subscribers with a zero use count.\n")
+{
+ struct gsm_network *net = gsmnet_from_vty(vty);
+ int purged;
+
+ purged = subscr_purge_inactive(net);
+ vty_out(vty, "%d subscriber(s) were purged.%s", purged, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN(subscriber_update,
+ subscriber_update_cmd,
+ "subscriber " SUBSCR_TYPES " ID update",
+ SUBSCR_HELP "Update the subscriber data from the dabase.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
+
+ if (!subscr) {
+ vty_out(vty, "%% No subscriber found for %s %s%s",
+ argv[0], argv[1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ subscr_update_from_db(subscr);
+ subscr_put(subscr);
+ return CMD_SUCCESS;
+}
+
static int scall_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
@@ -613,12 +645,14 @@ int bsc_vty_init_extra(void)
install_element_ve(&subscriber_silent_call_start_cmd);
install_element_ve(&subscriber_silent_call_stop_cmd);
install_element_ve(&subscriber_ussd_notify_cmd);
+ install_element_ve(&subscriber_update_cmd);
install_element_ve(&show_stats_cmd);
install_element(ENABLE_NODE, &ena_subscr_name_cmd);
install_element(ENABLE_NODE, &ena_subscr_extension_cmd);
install_element(ENABLE_NODE, &ena_subscr_authorized_cmd);
install_element(ENABLE_NODE, &ena_subscr_a3a8_cmd);
+ install_element(ENABLE_NODE, &subscriber_purge_cmd);
return 0;
}