[GPRS] SGSN: Include rate counters in MM Context
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index df1ee47..59bf5c0 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -25,6 +25,20 @@
GPRS_ALGO_GEA2,
};
+enum grs_mm_ctr {
+ GMM_CTR_PKTS_SIG_IN,
+ GMM_CTR_PKTS_SIG_OUT,
+ GMM_CTR_PKTS_UDATA_IN,
+ GMM_CTR_PKTS_UDATA_OUT,
+ GMM_CTR_BYTES_UDATA_IN,
+ GMM_CTR_BYTES_UDATA_OUT,
+ GMM_CTR_PDP_CTX_ACT,
+ GMM_CTR_SUSPEND,
+ GMM_CTR_PAGING_PS,
+ GMM_CTR_PAGING_CS,
+ GMM_CTR_RA_UPDATE,
+};
+
#define MS_RADIO_ACCESS_CAPA
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
@@ -73,6 +87,7 @@
uint32_t tlli;
uint16_t nsei;
uint16_t bvci;
+ struct rate_ctr_group *ctrg;
struct timer_list timer;
unsigned int T;
};
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 391a0b1..f2e5362 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -36,6 +36,7 @@
#include <osmocore/gsm_utils.h>
#include <osmocore/signal.h>
#include <osmocore/talloc.h>
+#include <osmocore/rate_ctr.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
@@ -136,8 +137,12 @@
/* Our implementation, should be kept in SGSN */
/* Send a message through the underlying layer */
-static int gsm48_gmm_sendmsg(struct msgb *msg, int command)
+static int gsm48_gmm_sendmsg(struct msgb *msg, int command,
+ const struct sgsn_mm_ctx *mm)
{
+ if (mm)
+ rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]);
+
/* caller needs to provide TLLI, BVCI and NSEI */
return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command);
}
@@ -214,7 +219,7 @@
gsm48_construct_ra(aa->ra_id.digits, &ra_id);
/* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Chapter 9.4.5: Attach reject */
@@ -232,7 +237,7 @@
gh->msg_type = GSM48_MT_GMM_ATTACH_REJ;
gh->data[0] = gmm_cause;
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Chapter 9.4.6.2 Detach accept */
@@ -248,7 +253,7 @@
gh->msg_type = GSM48_MT_GMM_DETACH_ACK;
gh->data[0] = force_stby;
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Transmit Chapter 9.4.12 Identity Request */
@@ -267,7 +272,7 @@
/* 10.5.5.9 ID type 2 + identity type and 10.5.5.7 'force to standby' IE */
gh->data[0] = id_type & 0xf;
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Check if we can already authorize a subscriber */
@@ -494,7 +499,7 @@
gsm48_construct_ra(rua->ra_id.digits, &ra_id);
/* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Chapter 9.4.17: Routing area update reject */
@@ -514,7 +519,7 @@
gh->data[1] = 0; /* ? */
/* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, NULL);
}
/* Chapter 9.4.14: Routing area update request */
@@ -525,6 +530,8 @@
struct gprs_ra_id old_ra_id;
uint8_t upd_type;
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_RA_UPDATE]);
+
/* Update Type 10.5.5.18 */
upd_type = *cur++ & 0x0f;
@@ -683,7 +690,7 @@
pdp->lib->pco_neg.l, pdp->lib->pco_neg.v);
/* Optional: Packet Flow Identifier */
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, pdp->mm);
}
/* Section 9.5.3: Activate PDP Context reject */
@@ -695,7 +702,7 @@
struct gsm48_hdr *gh;
uint8_t transaction_id = tid ^ 0x8; /* flip */
- DEBUGP(DMM, "<- ACTIVATE PDP CONTEXT ACK\n");
+ DEBUGP(DMM, "<- ACTIVATE PDP CONTEXT REJ\n");
mmctx2msgid(msg, mm);
@@ -707,7 +714,7 @@
if (pco_len && pco_v)
msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, pco_len, pco_v);
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, mm);
}
/* Section 9.5.9: Deactivate PDP Context Accept */
@@ -727,7 +734,7 @@
gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
gh->msg_type = GSM48_MT_GSM_DEACT_PDP_ACK;
- return gsm48_gmm_sendmsg(msg, 0);
+ return gsm48_gmm_sendmsg(msg, 0, mmctx);
}
/* Section 9.5.1: Activate PDP Context Request */
@@ -745,6 +752,9 @@
DEBUGP(DMM, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
act_req->req_llc_sapi, act_req->req_nsapi);
+
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PDP_CTX_ACT]);
+
req_qos_len = act_req->data[0];
req_qos = act_req->data + 1; /* 10.5.6.5 */
req_pdpa_len = act_req->data[1 + req_qos_len];
@@ -894,8 +904,10 @@
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
- if (mmctx)
+ if (mmctx) {
msgid2mmctx(mmctx, msg);
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
+ }
/* MMCTX can be NULL */
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 4e5fb01..892c1b0 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -25,6 +25,7 @@
#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
#include <osmocore/timer.h>
+#include <osmocore/rate_ctr.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/debug.h>
#include <openbsc/gprs_sgsn.h>
@@ -36,6 +37,27 @@
LLIST_HEAD(sgsn_apn_ctxts);
LLIST_HEAD(sgsn_pdp_ctxts);
+static const struct rate_ctr_desc mmctx_ctr_description[] = {
+ { "sign.packets.in", "Signalling Messages ( In)" },
+ { "sign.packets.out", "Signalling Messages (Out)" },
+ { "udata.packets.in", "User Data Messages ( In)" },
+ { "udata.packets.out", "User Data Messages (Out)" },
+ { "udata.bytes.in", "User Data Bytes ( In)" },
+ { "udata.bytes.out", "User Data Bytes (Out)" },
+ { "pdp_ctx_act", "PDP Context Activations " },
+ { "suspend", "SUSPEND Count " },
+ { "paging.ps", "Paging Packet Switched " },
+ { "paging.cs", "Paging Circuit Switched " },
+ { "ra_update", "Routing Area Update " },
+};
+
+static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
+ .group_name_prefix = "sgsn.mmctx",
+ .group_description = "SGSN MM Context Statistics",
+ .num_ctr = ARRAY_SIZE(mmctx_ctr_description),
+ .ctr_desc = mmctx_ctr_description,
+};
+
static int ra_id_equals(const struct gprs_ra_id *id1,
const struct gprs_ra_id *id2)
{
@@ -93,6 +115,7 @@
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
ctx->tlli = tlli;
ctx->mm_state = GMM_DEREGISTERED;
+ ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli);
llist_add(&ctx->list, &sgsn_mm_ctxts);
diff --git a/openbsc/src/gprs/osmo_sgsn.cfg b/openbsc/src/gprs/osmo_sgsn.cfg
index f39e853..f9a340a 100644
--- a/openbsc/src/gprs/osmo_sgsn.cfg
+++ b/openbsc/src/gprs/osmo_sgsn.cfg
@@ -1,9 +1,18 @@
!
-! OpenBSC configuration saved from vty
-! !
+! Osmocom SGSN (0.9.0.384-d9a55-dirty) configuration saved from vty
+!!
!
line vty
no login
!
sgsn
nsip local port 23000
+ns
+ timer tns-block 3
+ timer tns-block-retries 3
+ timer tns-reset 3
+ timer tns-reset-retries 3
+ timer tns-test 30
+ timer tns-alive 3
+ timer tns-alive-retries 10
+bssgp
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index 5584824..212f0e6 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -171,6 +171,7 @@
pfx, pdp->mm->imsi, pdp->sapi, pdp->nsapi, VTY_NEWLINE);
vty_out(vty, "%s APN: %s\n", pfx, pdp->lib->apn_use.v);
/* FIXME: statistics */
+ //vty_out_rate_ctr_group(vty, " ", pdp->ctrg);
}
static void vty_dump_mmctx(struct vty *vty, const char *pfx,
@@ -186,6 +187,8 @@
mm->ra.mcc, mm->ra.mnc, mm->ra.lac, mm->ra.rac,
mm->cell_id, VTY_NEWLINE);
+ vty_out_rate_ctr_group(vty, " ", mm->ctrg);
+
if (pdp) {
struct sgsn_pdp_ctx *pdp;