diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-12-24 21:43:14 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-12-24 21:43:14 +0100 |
commit | ee139e725386b1df7e482ea76b143fc931a48470 (patch) | |
tree | b0357b2a8b90918d9f73de1314aae9eb72c33111 | |
parent | a29e43a26fae23d5132461cf7bfa43a1ca64761f (diff) | |
parent | abd0cac0c52d52d40ac0d51710010fee28200f3d (diff) |
Merge branch 'zecke/subscr'
-rw-r--r-- | openbsc/include/openbsc/db.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 3 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 3 | ||||
-rw-r--r-- | openbsc/src/bsc_vty.c | 14 | ||||
-rw-r--r-- | openbsc/src/db.c | 72 | ||||
-rw-r--r-- | openbsc/src/gsm_subscriber.c | 5 | ||||
-rw-r--r-- | openbsc/src/gsm_subscriber_base.c | 17 | ||||
-rw-r--r-- | openbsc/src/vty_interface_layer3.c | 34 |
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; } |