Change in ...osmo-msc[master]: libmsc/msc_vty.c: refactor 'show subscr / conn / trans' commands

Harald Welte gerrit-no-reply at lists.osmocom.org
Mon Jun 3 07:18:41 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/osmo-msc/+/14069 )

Change subject: libmsc/msc_vty.c: refactor 'show subscr / conn / trans' commands
......................................................................

libmsc/msc_vty.c: refactor 'show subscr / conn / trans' commands

The current way of printing subscriber, connection, and transaction
info is ugly (sorry) and has several problems:

  - the terminal width should be large enough to fit quite long lines,
    otherwise the output is unreadable and looks misaligned;

  - some fields (such as subscriber name) can be larger than it's
    expected, so either they're getting truncated, or again, the
    output is misaligned and unreadable;

  - adding new info fields would require one to think about the
    alignment and would make the output even more cumbersome.

Here is an example output of 'show connection' command:

  _Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
  IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678      1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
  IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535     UTRAN-Iu-4294967295         COMMUNICATING 2=cm_service,trans_sms
  IMSI-262073993158656:MSISDN-123456:TMSI-0x493026BA     1               GERAN-A-1 MSC_A_ST_COMMUNICATING 1=1 (silent_call)

Another 'show subscriber' command mixes the information about
subscriber, its connections and transactions without any alignment,
what also decreases the readability.

This change introduces a hierarchical approach, based on the old
'field per line' formatting. First of all, the VTY commands were
extended with optional flags:

  show connection [trans]
  show subscriber cache [(conn|trans|conn+trans)]
  show subscriber TYPE ID [(conn|trans|conn+trans)]

so it can be decided, whether to print child connections and/or
transaction, or not. For example:

  show connection trans

would print all connections and their child transactions with
hierarchical alignment:

  Connection #00:
    Subscriber: IMSI-262073993158656:MSISDN-123456:TMSI-0x76760B75
    RAN connection: GERAN-A-1
    RAN connection state: MSC_A_ST_COMMUNICATING
    LAC / cell ID: 1 / 0
    Use count total: 1
    Use count: 1 (silent_call)
    Transaction #00:
      Unique (global) identifier: 0x00000000
      GSM 04.07 identifier (MT): 0
      Type: silent-call

another example is:

  show subscriber cache conn+trans

which would print all known subscribers,
their active connections and transactions:

  Subscriber #00:
    MSISDN: 123456
    LAC / cell ID: 1 / 0
    RAN type: GERAN-A
    IMSI: 262073993158656
    TMSI: 76760B75
    ...
    Connection:
      RAN connection: GERAN-A-1
      RAN connection state: MSC_A_ST_COMMUNICATING
      ...
      Transaction #00:
        Unique (global) identifier: 0x00000000
	GSM 04.07 identifier (MT): 0
	Type: silent-call
      Transaction #01:
        Unique (global) identifier: 0x00000001
	GSM 04.07 identifier (MO): 0
	Type: SMS
      Transaction #02:
        Unique (global) identifier: 0x00000002
	GSM 04.07 identifier (MT): 0
	Type: SMS

Please note that we don't print redundant info in child nodes
(i.e. connection and transaction info), such as subscriber name
in connection info, nor connection name in transaction info - it
is clear from the hierarchical formatting.

Change-Id: I5e58b56204c3f3d019e8d4c3c96cefdbb4af4d47
---
M src/libmsc/msc_vty.c
1 file changed, 291 insertions(+), 170 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 0c07bc2..5b0cfc4 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -661,58 +661,6 @@
 	return CMD_SUCCESS;
 }
 
-/*
-_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
-IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678  1     GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
-IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295     COMMUNICATING         2=cm_service,trans_sms
-IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. -     EUTRAN-SGs              RELEASING             0=none
-IMSI-123456789012378:HONR-12345432101              2     MSC-901-700-423:9876    REMOTE_MSC_A          1=inter_msc
-*/
-static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
-{
-	struct msc_a *msc_a = msub_msc_a(msub);
-	struct vlr_subscr *vsub = msub_vsub(msub);
-	char buf[128];
-
-	if (!(*idx))
-		vty_out(vty,
-			"_Subscriber_______________________________________ _LAC_ _RAN___________________"
-			" _MSC-A_state_________ _MSC-A_use_%s",
-			VTY_NEWLINE);
-	(*idx)++;
-
-	vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
-		vlr_subscr_short_name(msub_vsub(msub), 50),
-		vsub ? vsub->cgi.lai.lac : 0,
-		msub_ran_conn_name(msub),
-		osmo_fsm_inst_state_name(msc_a->c.fi),
-		osmo_use_count_total(&msc_a->use_count),
-		osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
-		VTY_NEWLINE);
-}
-
-DEFUN(show_msc_conn, show_msc_conn_cmd,
-	"show connection", SHOW_STR "Subscriber Connections\n")
-{
-	struct msub *msub;
-	int idx = 0;
-	llist_for_each_entry(msub, &msub_list, entry) {
-		vty_dump_one_conn(vty, msub, &idx);
-	}
-	return CMD_SUCCESS;
-}
-
-static void vty_trans_hdr(struct vty *vty)
-{
-	if (llist_empty(&gsmnet->trans_list))
-		return;
-
-	vty_out(vty,
-		"_Subscriber_______________________________________ _RAN___________________"
-		" _P__ TI CallRef_ _state_%s",
-		VTY_NEWLINE);
-}
-
 static const char *get_trans_proto_str(const struct gsm_trans *trans)
 {
 	static char buf[256];
@@ -725,146 +673,311 @@
 			 trans->cc.T308_second);
 		break;
 	case TRANS_SMS:
-		snprintf(buf, sizeof(buf), "%s %s",
+		snprintf(buf, sizeof(buf), "CP:%s RP:%s",
 			gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
 			gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
 		break;
 	default:
-		buf[0] = '\0';
-		break;
+		return NULL;
 	}
 
 	return buf;
 }
 
-static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
+/* Prefix a given format string with a given amount of spaces */
+#define MSC_VTY_DUMP(vty, offset, fmt, args...) \
+	vty_out(vty, "%*s" fmt, offset, "", ##args)
+
+#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \
+	MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \
+		     name, 30 - (int)strlen(name), "", \
+		     flag ? "true" : "false", \
+		     VTY_NEWLINE)
+
+enum msc_vty_dump_flags {
+	MSC_VTY_DUMP_F_SUBSCR		= (1 << 0),
+	MSC_VTY_DUMP_F_CONNECTION	= (1 << 1),
+	MSC_VTY_DUMP_F_TRANSACTION	= (1 << 2),
+};
+
+static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans,
+			       int offset, uint8_t dump_flags)
 {
-	vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
-		vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
-		msub_ran_conn_name(trans->msc_a->c.msub),
-		trans_type_name(trans->type),
-		trans->transaction_id,
-		trans->callref,
-		get_trans_proto_str(trans),
-		VTY_NEWLINE);
+	const char *proto_str;
+
+	if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
+		MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
+			     vlr_subscr_name(msc_a_vsub(trans->msc_a)),
+			     VTY_NEWLINE);
+	}
+
+	if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
+		MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
+			     trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub)
+					  : "(not established)",
+			     VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s",
+		     trans->callref, VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s",
+		     (trans->transaction_id & 0x08) ? "MO" : "MT",
+		     trans->transaction_id,
+		     VTY_NEWLINE);
+
+	MSC_VTY_DUMP(vty, offset, "Type: %s%s",
+		     trans_type_name(trans->type),
+		     VTY_NEWLINE);
+
+	if ((proto_str = get_trans_proto_str(trans))) {
+		MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s",
+			     proto_str, VTY_NEWLINE);
+	}
+}
+
+static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
+			      int offset, uint8_t dump_flags)
+{
+	struct vlr_subscr *vsub = msub_vsub(msub);
+	struct msc_a *msc_a = msub_msc_a(msub);
+	char buf[128];
+
+	if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
+		dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+		MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
+			     vlr_subscr_name(vsub),
+			     VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
+		     msub_ran_conn_name(msub),
+		     VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s",
+		     osmo_fsm_inst_state_name(msc_a->c.fi),
+		     VTY_NEWLINE);
+
+	if (vsub) {
+		MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
+			     vsub->cgi.lai.lac, vsub->cgi.cell_identity,
+			     VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
+		     osmo_use_count_total(&msc_a->use_count),
+		     VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
+		     osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
+		     VTY_NEWLINE);
+
+	/* Transactions of this connection */
+	if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
+		struct gsm_trans *trans;
+		unsigned int i = 0;
+
+		/* Both subscriber and connection info is already printed */
+		dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION;
+		dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+
+		llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+			if (trans->msc_a != msc_a)
+				continue;
+			MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
+				     i++, VTY_NEWLINE);
+			vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
+		}
+	}
+}
+
+static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
+				int offset, uint8_t dump_flags)
+{
+	char buf[128];
+
+	if (strlen(vsub->name)) {
+		MSC_VTY_DUMP(vty, offset, "Name: '%s'%s",
+			     vsub->name, VTY_NEWLINE);
+	}
+	if (strlen(vsub->msisdn)) {
+		MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s",
+			     vsub->msisdn, VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
+		     vsub->cgi.lai.lac, vsub->cgi.cell_identity,
+		     VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "RAN type: %s%s",
+		     osmo_rat_type_name(vsub->cs.attached_via_ran),
+		     VTY_NEWLINE);
+
+	MSC_VTY_DUMP(vty, offset, "IMSI: %s%s",
+		     vsub->imsi, VTY_NEWLINE);
+	if (vsub->tmsi != GSM_RESERVED_TMSI) {
+		MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s",
+			     vsub->tmsi, VTY_NEWLINE);
+	}
+	if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
+		MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s",
+			     vsub->tmsi_new, VTY_NEWLINE);
+	}
+	if (vsub->imei[0] != '\0') {
+		MSC_VTY_DUMP(vty, offset, "IMEI: %s%s",
+			     vsub->imei, VTY_NEWLINE);
+	}
+	if (vsub->imeisv[0] != '\0') {
+		MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s",
+			     vsub->imeisv, VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE);
+	MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached",
+			  vsub->imsi_detached_flag);
+	MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact",
+			  vsub->conf_by_radio_contact_ind);
+	MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR",
+			  vsub->sub_dataconf_by_hlr_ind);
+	MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR",
+			  vsub->loc_conf_in_hlr_ind);
+	MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant",
+			  vsub->dormant_ind);
+	MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location",
+			  vsub->cancel_loc_rx);
+	MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable",
+			  vsub->ms_not_reachable_flag);
+	MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed",
+			  vsub->la_allowed);
+
+	if (vsub->last_tuple) {
+		struct vlr_auth_tuple *t = vsub->last_tuple;
+		MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s",
+			     t->use_count, VTY_NEWLINE);
+		MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s",
+			     t->key_seq, VTY_NEWLINE);
+		MSC_VTY_DUMP(vty, offset + 2, "RAND  : %s%s",
+			     osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
+			     VTY_NEWLINE);
+		MSC_VTY_DUMP(vty, offset + 2, "SRES  : %s%s",
+			     osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
+			     VTY_NEWLINE);
+		MSC_VTY_DUMP(vty, offset + 2, "Kc    : %s%s",
+			     osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
+			     VTY_NEWLINE);
+	}
+
+	MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s",
+		     vsub->cs.is_paging ? "is" : "not",
+		     llist_count(&vsub->cs.requests),
+		     VTY_NEWLINE);
+
+	/* SGs related */
+	MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s",
+		     osmo_fsm_inst_state_name(vsub->sgs_fsm),
+		     VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s",
+		     strlen(vsub->sgs.mme_name) ?
+		             vsub->sgs.mme_name : "(none)",
+		     VTY_NEWLINE);
+
+	MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
+		     osmo_use_count_total(&vsub->use_count),
+		     VTY_NEWLINE);
+	MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
+		     osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count),
+		     VTY_NEWLINE);
+
+	/* Connection(s) and/or transactions of this subscriber */
+	if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
+		struct msub *msub = msub_for_vsub(vsub);
+		if (!msub)
+			return;
+
+		/* Subscriber info is already printed */
+		dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+
+		MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE);
+		vty_dump_one_conn(vty, msub, offset + 2, dump_flags);
+	} else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
+		struct gsm_trans *trans;
+		unsigned int i = 0;
+
+		/* Subscriber info is already printed */
+		dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+		/* Do not print connection info, but mention it */
+		dump_flags |= MSC_VTY_DUMP_F_CONNECTION;
+
+		llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+			if (trans->vsub != vsub)
+				continue;
+			MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
+				     i++, VTY_NEWLINE);
+			vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
+		}
+	}
 }
 
 DEFUN(show_msc_transaction, show_msc_transaction_cmd,
-	"show transaction", SHOW_STR "Transactions\n")
+	"show transaction",
+	SHOW_STR "Transactions\n")
 {
 	struct gsm_trans *trans;
+	uint8_t flags = 0x00;
+	unsigned int i = 0;
 
-	vty_trans_hdr(vty);
-	llist_for_each_entry(trans, &gsmnet->trans_list, entry)
-		vty_dump_one_trans(vty, trans);
+	flags |= MSC_VTY_DUMP_F_CONNECTION;
+	flags |= MSC_VTY_DUMP_F_SUBSCR;
+
+	llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+		vty_out(vty, "  Transaction #%02u: %s", i++, VTY_NEWLINE);
+		vty_dump_one_trans(vty, trans, 4, flags);
+	}
 
 	return CMD_SUCCESS;
 }
 
-static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
+DEFUN(show_msc_conn, show_msc_conn_cmd,
+	"show connection [trans]",
+	SHOW_STR "Subscriber Connections\n"
+	"Show child transactions of each connection\n")
 {
-	struct gsm_trans *trans;
-	char buf[128];
+	uint8_t flags = 0x00;
+	unsigned int i = 0;
+	struct msub *msub;
 
-	if (strlen(vsub->name))
-		vty_out(vty, "    Name: '%s'%s", vsub->name, VTY_NEWLINE);
-	if (strlen(vsub->msisdn))
-		vty_out(vty, "    Extension: %s%s", vsub->msisdn,
-			VTY_NEWLINE);
-	vty_out(vty, "    LAC: %d/0x%x%s",
-		vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
-	vty_out(vty, "    RAN: %s%s",
-		osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
-	vty_out(vty, "    IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
-	if (vsub->tmsi != GSM_RESERVED_TMSI)
-		vty_out(vty, "    TMSI: %08X%s", vsub->tmsi,
-			VTY_NEWLINE);
-	if (vsub->tmsi_new != GSM_RESERVED_TMSI)
-		vty_out(vty, "    new TMSI: %08X%s", vsub->tmsi_new,
-			VTY_NEWLINE);
-	if (vsub->imei[0] != '\0')
-		vty_out(vty, "    IMEI: %s%s", vsub->imei, VTY_NEWLINE);
-	if (vsub->imeisv[0] != '\0')
-		vty_out(vty, "    IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
+	if (argc > 0)
+		flags |= MSC_VTY_DUMP_F_TRANSACTION;
+	flags |= MSC_VTY_DUMP_F_SUBSCR;
 
-	vty_out(vty, "    Flags: %s", VTY_NEWLINE);
-	vty_out(vty, "     IMSI detached:             %s%s",
-		vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     Conf. by radio contact:    %s%s",
-		vsub->conf_by_radio_contact_ind ? "true" : "false",
-		VTY_NEWLINE);
-	vty_out(vty, "     Subscr. data conf. by HLR: %s%s",
-		vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     Location conf. in HLR:     %s%s",
-		vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     Subscriber dormant:        %s%s",
-		vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     Received cancel locataion: %s%s",
-		vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     MS not reachable:          %s%s",
-		vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
-	vty_out(vty, "     LA allowed:                %s%s",
-		vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
-
-	if (vsub->last_tuple) {
-		struct vlr_auth_tuple *t = vsub->last_tuple;
-		vty_out(vty, "    A3A8 last tuple (used %d times):%s",
-			t->use_count, VTY_NEWLINE);
-		vty_out(vty, "     seq # : %d%s",
-			t->key_seq, VTY_NEWLINE);
-		vty_out(vty, "     RAND  : %s%s",
-			osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
-			VTY_NEWLINE);
-		vty_out(vty, "     SRES  : %s%s",
-			osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
-			VTY_NEWLINE);
-		vty_out(vty, "     Kc    : %s%s",
-			osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
-			VTY_NEWLINE);
+	llist_for_each_entry(msub, &msub_list, entry) {
+		vty_out(vty, "  Connection #%02u: %s", i++, VTY_NEWLINE);
+		vty_dump_one_conn(vty, msub, 4, flags);
 	}
 
-	vty_out(vty, "    Paging: %s paging for %d requests%s",
-		vsub->cs.is_paging ? "is" : "not",
-		llist_count(&vsub->cs.requests),
-		VTY_NEWLINE);
-
-	/* SGs related */
-	vty_out(vty, "    SGs-state: %s%s",
-		osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
-	if (strlen(vsub->sgs.mme_name))
-		vty_out(vty, "    SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
-	else
-		vty_out(vty, "    SGs-MME: (none)%s", VTY_NEWLINE);
-
-	vty_out(vty, "    Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE);
-
-	/* Connection */
-	if (vsub->msc_conn_ref) {
-		struct msub *msub = msub_for_vsub(vsub);
-		int idx = 0;
-		if (msub) {
-			vty_dump_one_conn(vty, msub, &idx);
-		}
-	}
-
-	/* Transactions */
-	vty_trans_hdr(vty);
-	llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
-		if (trans->vsub != vsub)
-			continue;
-		vty_dump_one_trans(vty, trans);
-	}
+	return CMD_SUCCESS;
 }
 
+#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]"
+#define SUBSCR_FLAGS_HELP \
+	"Show child connections\n" \
+	"Show child transactions\n" \
+	"Show child connections and transactions\n"
+
 /* Subscriber */
-DEFUN(show_subscr_cache,
-      show_subscr_cache_cmd,
-      "show subscriber cache",
+DEFUN(show_subscr_cache, show_subscr_cache_cmd,
+	"show subscriber cache " SUBSCR_FLAGS,
 	SHOW_STR "Show information about subscribers\n"
-	"Display contents of subscriber cache\n")
+	"Display contents of subscriber cache\n"
+	SUBSCR_FLAGS_HELP)
 {
 	struct vlr_subscr *vsub;
-	int count = 0;
+	unsigned int count = 0;
+	uint8_t flags = 0x00;
+	unsigned int i = 0;
+
+	if (argc && strcmp(argv[0], "conn") == 0)
+		flags |= MSC_VTY_DUMP_F_CONNECTION;
+	else if (argc && strcmp(argv[0], "trans") == 0)
+		flags |= MSC_VTY_DUMP_F_TRANSACTION;
+	else if (argc && strcmp(argv[0], "conn+trans") == 0)
+		flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
 
 	llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
 		if (++count > 100) {
@@ -872,8 +985,8 @@
 				" stopping here.%s", count-1, VTY_NEWLINE);
 			break;
 		}
-		vty_out(vty, "  Subscriber:%s", VTY_NEWLINE);
-		subscr_dump_full_vty(vty, vsub);
+		vty_out(vty, "  Subscriber #%02u: %s", i++, VTY_NEWLINE);
+		vty_dump_one_subscr(vty, vsub, 4, flags);
 	}
 
 	return CMD_SUCCESS;
@@ -982,14 +1095,14 @@
 	"Legacy alias for 'imsi'\n"					\
 	"Identifier for the subscriber\n"
 
-DEFUN(show_subscr,
-      show_subscr_cmd,
-      "show subscriber " SUBSCR_TYPES " ID",
-	SHOW_STR SUBSCR_HELP)
+DEFUN(show_subscr, show_subscr_cmd,
+	"show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS,
+	SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP)
 {
-	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
-						       argv[1]);
+	struct vlr_subscr *vsub;
+	uint8_t flags = 0x00;
 
+	vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
 	if (!vsub) {
 		vty_out(vty, "%% No subscriber found for %s %s%s",
 			argv[0], argv[1], VTY_NEWLINE);
@@ -1001,7 +1114,15 @@
 	 * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
 	vlr_subscr_put(vsub, VSUB_USE_VTY);
 
-	subscr_dump_full_vty(vty, vsub);
+	if (argc > 2 && strcmp(argv[2], "conn") == 0)
+		flags |= MSC_VTY_DUMP_F_CONNECTION;
+	else if (argc > 2 && strcmp(argv[2], "trans") == 0)
+		flags |= MSC_VTY_DUMP_F_TRANSACTION;
+	else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0)
+		flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
+
+	vty_out(vty, "  Subscriber: %s", VTY_NEWLINE);
+	vty_dump_one_subscr(vty, vsub, 4, flags);
 
 	return CMD_SUCCESS;
 }

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-msc/+/14069
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: I5e58b56204c3f3d019e8d4c3c96cefdbb4af4d47
Gerrit-Change-Number: 14069
Gerrit-PatchSet: 5
Gerrit-Owner: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190603/4eaf9e39/attachment.html>


More information about the gerrit-log mailing list