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