This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
keith gerrit-no-reply at lists.osmocom.orgkeith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hlr/+/22311 )
Change subject: Add vty command to show summary of all or filtered subscribers
......................................................................
Add vty command to show summary of all or filtered subscribers
Adds the following commands:
show subscribers all - Display summary of all entries in HLR
show subscribers filter [....] As above but filter on
show subscribers last seen - Display only subscribers with
time since Last LU update seen entries and sorts by LU..
Change-Id: I7f0573381a6d0d13841ac6d42d50f0e8389decf4
---
M include/osmocom/hlr/db.h
M src/db.c
M src/db_hlr.c
M src/hlr_vty_subscr.c
4 files changed, 219 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/11/22311/1
diff --git a/include/osmocom/hlr/db.h b/include/osmocom/hlr/db.h
index ca336a0..d5e7612 100644
--- a/include/osmocom/hlr/db.h
+++ b/include/osmocom/hlr/db.h
@@ -8,6 +8,13 @@
struct hlr;
enum stmt_idx {
+ DB_STMT_SEL_ALL,
+ DB_STMT_SEL_ALL_ORDER_LAST_SEEN,
+ DB_STMT_SEL_FILTER,
+ DB_STMT_SEL_FILTER_MSISDN,
+ DB_STMT_SEL_FILTER_IMSI,
+ DB_STMT_SEL_FILTER_CS,
+ DB_STMT_SEL_FILTER_PS,
DB_STMT_SEL_BY_IMSI,
DB_STMT_SEL_BY_MSISDN,
DB_STMT_SEL_BY_ID,
@@ -148,6 +155,8 @@
int db_subscr_exists_by_imsi(struct db_context *dbc, const char *imsi);
int db_subscr_exists_by_msisdn(struct db_context *dbc, const char *msisdn);
+int db_subscrs_get_print(struct vty *vty, struct db_context *dbc, const char *type, const char *filter,
+ void (*dump_cb)(struct vty *, struct hlr_subscriber *subscr), int *count, const char **err);
int db_subscr_get_by_imsi(struct db_context *dbc, const char *imsi,
struct hlr_subscriber *subscr);
int db_subscr_get_by_msisdn(struct db_context *dbc, const char *msisdn,
diff --git a/src/db.c b/src/db.c
index 5ec20e2..8cf0e50 100644
--- a/src/db.c
+++ b/src/db.c
@@ -51,6 +51,14 @@
"sgsn_via_proxy"
static const char *stmt_sql[] = {
+ [DB_STMT_SEL_ALL] = "SELECT " SEL_COLUMNS " FROM subscriber;",
+ [DB_STMT_SEL_ALL_ORDER_LAST_SEEN] = "SELECT " SEL_COLUMNS " FROM subscriber "
+ "WHERE last_lu_seen IS NOT NULL ORDER BY last_lu_seen;",
+ [DB_STMT_SEL_FILTER] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE msisdn LIKE $search ORDER BY msisdn",
+ [DB_STMT_SEL_FILTER_MSISDN] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE msisdn LIKE $search ORDER BY msisdn",
+ [DB_STMT_SEL_FILTER_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi LIKE $search ORDER BY imsi",
+ [DB_STMT_SEL_FILTER_CS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_cs = $search ORDER BY last_lu_seen",
+ [DB_STMT_SEL_FILTER_PS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_ps = $search ORDER BY last_lu_seen",
[DB_STMT_SEL_BY_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi = ?",
[DB_STMT_SEL_BY_MSISDN] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE msisdn = ?",
[DB_STMT_SEL_BY_ID] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE id = ?",
diff --git a/src/db_hlr.c b/src/db_hlr.c
index 6ba43c2..6a2e115 100644
--- a/src/db_hlr.c
+++ b/src/db_hlr.c
@@ -624,6 +624,95 @@
msisdn, err);
return rc;
}
+/*! Retrieve subscriber data from the HLR database.
+ * \param[in,out] vty vty.
+ * \param[in,out] dbc database context.
+ * \param[in] filter_type ASCII string of identifier type to search.
+ * \param[in] filter ASCII string to search.
+ * \param[in] dump_cb pointer to vty print function.
+ * \param[in,out] count counter for number of matched subscribers.
+ * \param[in,our] err
+ * \returns 0 on success, -ENOENT if no subscriber was found, -EIO on
+ * database error.
+ */
+int db_subscrs_get_print(struct vty *vty, struct db_context *dbc, const char *filter_type, const char *filter,
+ void (*dump_cb)(struct vty *, struct hlr_subscriber *subscr), int *count, const char **err)
+{
+ sqlite3_stmt *stmt;
+ char search[256];
+ int rc;
+ struct hlr_subscriber sub, *subscr;
+ subscr = ⊂
+ bool show_ls = false;
+
+ if (!filter_type) {
+ stmt = dbc->stmt[DB_STMT_SEL_ALL];
+ } else if (strcmp(filter_type, "imsi") == 0) {
+ stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMSI];
+ } else if (strcmp(filter_type, "msisdn") == 0) {
+ stmt = dbc->stmt[DB_STMT_SEL_FILTER_MSISDN];
+ } else if (strcmp(filter_type, "cs") == 0) {
+ stmt = dbc->stmt[DB_STMT_SEL_FILTER_CS];
+ } else if (strcmp(filter_type, "ps") == 0) {
+ stmt = dbc->stmt[DB_STMT_SEL_FILTER_PS];
+ } else if (strcmp(filter_type, "last_lu_seen") == 0) {
+ show_ls = true;
+ stmt = dbc->stmt[DB_STMT_SEL_ALL_ORDER_LAST_SEEN];
+ } else {
+ return -EIO;
+ }
+
+ if (filter && strcmp(filter_type, "last_lu_seen") != 0) {
+ if (strcmp(filter, "on") == 0) {
+ sprintf(search, "%s", "1");
+ } else if (strcmp(filter, "off") == 0) {
+ sprintf(search, "%s", "0");
+ } else {
+ sprintf(search, "%%%s%%", filter);
+ }
+ if (!db_bind_text(stmt, "$search", search)) {
+ *err = sqlite3_errmsg(dbc->db);
+ return -EIO;
+ }
+ }
+
+ rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_DONE) {
+ db_remove_reset(stmt);
+ *err = "No matching subscriber(s)";
+ return -ENOENT;
+ }
+
+ while (rc == SQLITE_ROW) {
+ *subscr = (struct hlr_subscriber){};
+ subscr->id = sqlite3_column_int64(stmt, 0);
+ copy_sqlite3_text_to_buf(subscr->imsi, stmt, 1);
+ copy_sqlite3_text_to_buf(subscr->msisdn, stmt, 2);
+ copy_sqlite3_text_to_buf(subscr->imei, stmt, 3);
+ subscr->nam_cs = sqlite3_column_int(stmt, 9);
+ subscr->nam_ps = sqlite3_column_int(stmt, 10);
+ if (show_ls)
+ parse_last_lu_seen(&subscr->last_lu_seen, (const char *)sqlite3_column_text(stmt, 14),
+ subscr->imsi, "CS");
+ dump_cb(vty, subscr);
+ rc = sqlite3_step(stmt);
+ (*count)++;
+ }
+
+ db_remove_reset(stmt);
+ if (rc != SQLITE_DONE) {
+ *err = sqlite3_errmsg(dbc->db);
+ return -EIO;
+ } else if (rc == SQLITE_DONE) {
+ *err = NULL;
+ return 0;
+ } else {
+ *err = sqlite3_errmsg(dbc->db);
+ LOGP(DAUC, LOGL_ERROR, "Cannot read subscribers from db:: %s\n", *err);
+ return rc;
+ }
+}
/*! Retrieve subscriber data from the HLR database.
* \param[in,out] dbc database context.
diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c
index f5066c1..856586e 100644
--- a/src/hlr_vty_subscr.c
+++ b/src/hlr_vty_subscr.c
@@ -44,13 +44,14 @@
return buf;
}
-static void dump_last_lu_seen(struct vty *vty, const char *domain_label, time_t last_lu_seen)
+static void dump_last_lu_seen(struct vty *vty, const char *domain_label, time_t last_lu_seen, bool only_age)
{
uint32_t age;
char datebuf[32];
if (!last_lu_seen)
return;
- vty_out(vty, " last LU seen on %s: %s", domain_label, get_datestr(&last_lu_seen, datebuf, sizeof(datebuf)));
+ if (!only_age)
+ vty_out(vty, " last LU seen on %s: %s", domain_label, get_datestr(&last_lu_seen, datebuf, sizeof(datebuf)));
if (!timestamp_age(&last_lu_seen, &age))
vty_out(vty, " (invalid timestamp)%s", VTY_NEWLINE);
else {
@@ -64,7 +65,10 @@
UNIT_AGO("h", 60*60);
UNIT_AGO("m", 60);
UNIT_AGO("s", 1);
- vty_out(vty, " ago)%s", VTY_NEWLINE);
+ if (!only_age)
+ vty_out(vty, " ago)%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " ago)");
#undef UNIT_AGO
}
}
@@ -108,8 +112,8 @@
vty_out(vty, " PS disabled%s", VTY_NEWLINE);
if (subscr->ms_purged_ps)
vty_out(vty, " PS purged%s", VTY_NEWLINE);
- dump_last_lu_seen(vty, "CS", subscr->last_lu_seen);
- dump_last_lu_seen(vty, "PS", subscr->last_lu_seen_ps);
+ dump_last_lu_seen(vty, "CS", subscr->last_lu_seen, false);
+ dump_last_lu_seen(vty, "PS", subscr->last_lu_seen_ps, false);
if (!*subscr->imsi)
return;
@@ -159,6 +163,27 @@
}
}
+static void subscr_dump_summary_vty(struct vty *vty, struct hlr_subscriber *subscr)
+{
+ vty_out(vty, "%-5"PRIu64" %-12s %-16s", subscr->id,
+ *subscr->msisdn ? subscr->msisdn : "none",
+ *subscr->imsi ? subscr->imsi : "none");
+
+ if (*subscr->imei) {
+ char checksum = osmo_luhn(subscr->imei, 14);
+ if (checksum == -EINVAL)
+ vty_out(vty, " %-14s (INVALID LENGTH!)", subscr->imei);
+ else
+ vty_out(vty, " %-14s%c", subscr->imei, checksum);
+ } else {
+ vty_out(vty," ------------- ");
+ }
+ vty_out(vty, " %-2s%-2s ", subscr->nam_cs ? "CS" : "", subscr->nam_ps ? "PS" : "");
+ if (subscr->last_lu_seen)
+ dump_last_lu_seen(vty, "CS", subscr->last_lu_seen, true);
+ vty_out_newline(vty);
+}
+
static int get_subscr_by_argv(struct vty *vty, const char *type, const char *id, struct hlr_subscriber *subscr)
{
char imei_buf[GSM23003_IMEI_NUM_DIGITS_NO_CHK+1];
@@ -186,11 +211,48 @@
return rc;
}
+static int get_subscrs(struct vty *vty, const char *filter_type, const char *filter)
+{
+ int rc = -1;
+ int count = 0;
+ const char *err;
+ bool show_ls = (filter_type && strcmp(filter_type, "last_lu_seen") == 0);
+
+ vty_out(vty, "ID MSISDN IMSI IMEI NAM");
+ if (show_ls)
+ vty_out(vty, " LAST SEEN");
+ vty_out_newline(vty);
+ vty_out(vty, "----- ------------ ---------------- ---------------- -----");
+ if (show_ls)
+ vty_out(vty, " ------------");
+ vty_out_newline(vty);
+ rc = db_subscrs_get_print(vty, g_hlr->dbc, filter_type, filter, subscr_dump_summary_vty, &count, &err);
+ if (count > 40) {
+ vty_out(vty, "----- ------------ ---------------- ---------------- -----");
+ if (show_ls)
+ vty_out(vty, " ------------");
+ vty_out_newline(vty);
+ vty_out(vty, "ID MSISDN IMSI IMEI NAM");
+ if (show_ls)
+ vty_out(vty, " LAST SEEN");
+ vty_out_newline(vty);
+ }
+ if (count > 0)
+ vty_out(vty, " Subscribers Shown: %d%s", count, VTY_NEWLINE);
+ if (rc)
+ vty_out(vty, "%% %s%s", err, VTY_NEWLINE);
+ return rc;
+}
+
+
#define SUBSCR_CMD "subscriber "
#define SUBSCR_CMD_HELP "Subscriber management commands\n"
#define SUBSCR_SHOW_HELP "Show subscriber information\n"
+#define SUBSCRS_SHOW_HELP "Show all subscribers (with filter possibility)\n"
#define SUBSCR_ID "(imsi|msisdn|id|imei) IDENT"
+#define SUBSCR_FILTER "(imsi|msisdn) FILTER"
+
#define SUBSCR_ID_HELP \
"Identify subscriber by IMSI\n" \
"Identify subscriber by MSISDN (phone number)\n" \
@@ -225,6 +287,48 @@
"show " SUBSCR_CMD SUBSCR_ID,
SHOW_STR SUBSCR_SHOW_HELP SUBSCR_ID_HELP);
+DEFUN(subscriber_show_all,
+ subscriber_show_all_cmd,
+ "show subscribers all",
+ SHOW_STR SUBSCRS_SHOW_HELP "Show summary of all subscribers\n")
+{
+ if (get_subscrs(vty, NULL, NULL))
+ return CMD_WARNING;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(subscriber_show_filtered,
+ subscriber_show_filtered_cmd,
+ "show subscribers filter " SUBSCR_FILTER,
+ SHOW_STR SUBSCRS_SHOW_HELP "Show summary of subscribers with filter\n"
+ "Filter by IMSI\n" "Filter by MSISDN\n" "String to match in msisdn or imsi\n")
+{
+ const char *filter_type = argv[0];
+ const char *filter = argv[1];
+
+ if (get_subscrs(vty, filter_type, filter))
+ return CMD_WARNING;
+
+ return CMD_SUCCESS;
+}
+
+ALIAS(subscriber_show_filtered, subscriber_show_filtered_cmd2,
+ "show subscribers filter (cs|ps) (on|off)",
+ SHOW_STR SUBSCR_SHOW_HELP "Show summary of all subscribers\n"
+ "Show Subscribers with NAM CS In/active\n" "Show Subscribers with NAM PS In/active\n");
+
+DEFUN(subscriber_show_order_last_seen, subscriber_show_order_last_seen_cmd,
+ "show subscribers last seen",
+ SHOW_STR SUBSCR_SHOW_HELP "Show Subscribers Ordered by Last Seen Time\n"
+ "Show Subscribers Ordered by Last Seen Time\n")
+{
+ if (get_subscrs(vty, "last_lu_seen", NULL))
+ return CMD_WARNING;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(subscriber_create,
subscriber_create_cmd,
SUBSCR_CMD "imsi IDENT create",
@@ -679,6 +783,10 @@
void hlr_vty_subscriber_init(void)
{
install_element_ve(&subscriber_show_cmd);
+ install_element_ve(&subscriber_show_all_cmd);
+ install_element_ve(&subscriber_show_filtered_cmd);
+ install_element_ve(&subscriber_show_filtered_cmd2);
+ install_element_ve(&subscriber_show_order_last_seen_cmd);
install_element_ve(&show_subscriber_cmd);
install_element(ENABLE_NODE, &subscriber_create_cmd);
install_element(ENABLE_NODE, &subscriber_delete_cmd);
--
To view, visit https://gerrit.osmocom.org/c/osmo-hlr/+/22311
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-Change-Id: I7f0573381a6d0d13841ac6d42d50f0e8389decf4
Gerrit-Change-Number: 22311
Gerrit-PatchSet: 1
Gerrit-Owner: keith <keith at rhizomatica.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210119/f911e310/attachment.htm>