msc: add counters to track call attempts/active/success/failed

active_calls describe all calls in active state.
call.complete Call got terminated by disconnect requested either by MS or MSC.
call.incomplete Call got terminated by any other reason.
call.active Calls reached active state.
Change-Id: I49b93af2e6a0ba16c2fb00b7b83974e8a6a16df3
diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c
index e53b466..57e3599 100644
--- a/openbsc/src/libbsc/net_init.c
+++ b/openbsc/src/libbsc/net_init.c
@@ -86,6 +86,7 @@
 	/* init statistics */
 	net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0);
 	net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0);
+	net->active_calls = osmo_counter_alloc("msc.active_calls");
 
 	net->mncc_recv = mncc_recv;
 	net->ext_min = GSM_MIN_EXTEN;
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index aa3d78a9..be1b260 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1299,6 +1299,39 @@
 	return gsm48_conn_sendmsg(msg, conn, NULL);
 }
 
+/* FIXME: this count_statistics is a state machine behaviour. we should convert
+ * the complete call control into a state machine. Afterwards we can move this
+ * code into state transitions.
+ */
+static void count_statistics(struct gsm_trans *trans, int new_state)
+{
+	int old_state = trans->cc.state;
+	struct rate_ctr_group *msc = trans->net->msc_ctrs;
+
+	if (old_state == new_state)
+		return;
+
+	/* state incoming */
+	switch (new_state) {
+	case GSM_CSTATE_ACTIVE:
+		osmo_counter_inc(trans->net->active_calls);
+		rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_ACTIVE]);
+		break;
+	}
+
+	/* state outgoing */
+	switch (old_state) {
+	case GSM_CSTATE_ACTIVE:
+		osmo_counter_dec(trans->net->active_calls);
+		if (new_state == GSM_CSTATE_DISCONNECT_REQ ||
+				new_state == GSM_CSTATE_DISCONNECT_IND)
+			rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]);
+		else
+			rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]);
+		break;
+	}
+}
+
 /* Call Control */
 
 /* The entire call control code is written in accordance with Figure 7.10c
@@ -1315,6 +1348,7 @@
 		gsm48_cc_state_name(trans->cc.state),
 		gsm48_cc_state_name(state));
 
+	count_statistics(trans, state);
 	trans->cc.state = state;
 }