aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-12-22 00:41:05 +0100
committerHarald Welte <laforge@netfilter.org>2009-12-22 00:41:05 +0100
commit24ff6ee0a343d46823771b9a86e867780eb2099b (patch)
tree2c8bd4dd014f9a851cbe1de9da39b4389ae6ccca
parenta992a36d5f9e7a2d1bb7948784c69ea2e342b7d3 (diff)
keep some internal statistics inside OpenBSC
the statistics will give us some idea about the network load and performance.
-rw-r--r--openbsc/include/openbsc/gsm_data.h45
-rw-r--r--openbsc/src/abis_rsl.c3
-rw-r--r--openbsc/src/gsm_04_08.c19
-rw-r--r--openbsc/src/gsm_04_08_utils.c2
-rw-r--r--openbsc/src/gsm_04_11.c9
-rw-r--r--openbsc/src/handover_logic.c8
-rw-r--r--openbsc/src/paging.c7
-rw-r--r--openbsc/src/vty_interface.c36
8 files changed, 128 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 9d2549ca..74e19383 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -457,6 +457,49 @@ struct gsm_bts {
struct llist_head trx_list;
};
+/* Some statistics of our network */
+struct gsmnet_stats {
+ struct {
+ unsigned long total;
+ unsigned long no_channel;
+ } chreq;
+ struct {
+ unsigned long attempted;
+ unsigned long no_channel; /* no channel available */
+ unsigned long timeout; /* T3103 timeout */
+ unsigned long completed; /* HO COMPL received */
+ unsigned long failed; /* HO FAIL received */
+ } handover;
+ struct {
+ unsigned long attach;
+ unsigned long normal;
+ unsigned long periodic;
+ unsigned long detach;
+ } loc_upd_type;
+ struct {
+ unsigned long reject;
+ unsigned long accept;
+ } loc_upd_resp;
+ struct {
+ unsigned long attempted;
+ unsigned long detached;
+ unsigned long completed;
+ unsigned long expired;
+ } paging;
+ struct {
+ unsigned long submitted; /* MO SMS submissions */
+ unsigned long no_receiver;
+ unsigned long delivered; /* MT SMS deliveries */
+ unsigned long rp_err_mem;
+ unsigned long rp_err_other;
+ } sms;
+ struct {
+ unsigned long dialled; /* total number of dialled calls */
+ unsigned long alerted; /* we alerted the other end */
+ unsigned long connected;/* how many calls were accepted */
+ } call;
+};
+
enum gsm_auth_policy {
GSM_AUTH_POLICY_CLOSED, /* only subscribers authorized in DB */
GSM_AUTH_POLICY_ACCEPT_ALL, /* accept everyone, even if not authorized in DB */
@@ -494,6 +537,8 @@ struct gsm_network {
unsigned int max_distance; /* TA values */
} handover;
+ struct gsmnet_stats stats;
+
/* layer 4 */
int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
struct llist_head upqueue;
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 72ae9dbb..ae1d6af5 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1261,11 +1261,14 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
+ bts->network->stats.chreq.total++;
+
/* check availability / allocate channel */
lchan = lchan_alloc(bts, lctype);
if (!lchan) {
DEBUGP(DRSL, "CHAN RQD: no resources for %s 0x%x\n",
gsm_lchan_name(lctype), rqd_ref->ra);
+ bts->network->stats.chreq.no_channel++;
/* FIXME: send some kind of reject ?!? */
return -ENOMEM;
}
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 156927f5..2b9dcc23 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -886,6 +886,7 @@ static int encode_more(struct msgb *msg)
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
{
+ struct gsm_bts *bts = lchan->ts->trx->bts;
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
@@ -897,6 +898,8 @@ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
gh->data[0] = cause;
DEBUGP(DMM, "-> LOCATION UPDATING REJECT on channel: %d\n", lchan->nr);
+
+ bts->network->stats.loc_upd_resp.reject++;
return gsm48_sendmsg(msg, NULL);
}
@@ -925,6 +928,8 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
+ bts->network->stats.loc_upd_resp.accept++;
+
return gsm48_sendmsg(msg, NULL);
}
@@ -1043,6 +1048,18 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
dispatch_signal(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len);
+ switch (lu->type) {
+ case GSM48_LUPD_NORMAL:
+ bts->network->stats.loc_upd_type.normal++;
+ break;
+ case GSM48_LUPD_IMSI_ATT:
+ bts->network->stats.loc_upd_type.attach++;
+ break;
+ case GSM48_LUPD_PERIODIC:
+ bts->network->stats.loc_upd_type.periodic++;
+ break;
+ }
+
/*
* Pseudo Spoof detection: Just drop a second/concurrent
* location updating request.
@@ -1369,6 +1386,8 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg)
DEBUGP(DMM, "IMSI DETACH INDICATION: mi_type=0x%02x MI(%s): ",
mi_type, mi_string);
+ bts->network->stats.loc_upd_type.detach++;
+
switch (mi_type) {
case GSM_MI_TYPE_TMSI:
subscr = subscr_get_by_tmsi(bts->network,
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index e96a1ca0..2cd571e2 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -488,6 +488,8 @@ int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr)
sig_data.bts = msg->lchan->ts->trx->bts;
sig_data.lchan = msg->lchan;
+ bts->network->stats.paging.completed++;
+
dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
/* Stop paging on the bts we received the paging response */
diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c
index 17a58311..579bb55d 100644
--- a/openbsc/src/gsm_04_11.c
+++ b/openbsc/src/gsm_04_11.c
@@ -517,6 +517,8 @@ static int gsm340_rx_tpdu(struct msgb *msg)
u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
int rc = 0;
+ bts->network->stats.sms.submitted++;
+
gsms = sms_alloc();
if (!gsms)
return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
@@ -605,6 +607,7 @@ static int gsm340_rx_tpdu(struct msgb *msg)
gsms->receiver = subscr_get_by_extension(bts->network, gsms->dest_addr);
if (!gsms->receiver) {
rc = 1; /* cause 1: unknown subscriber */
+ bts->network->stats.sms.no_receiver++;
goto out;
}
@@ -791,7 +794,9 @@ static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans,
* to store this in our database and wati for a SMMA message */
/* FIXME */
dispatch_signal(SS_SMS, S_SMS_MEM_EXCEEDED, trans->subscr);
- }
+ trans->lchan->ts->trx->bts->network->stats.sms.rp_err_mem++;
+ } else
+ trans->lchan->ts->trx->bts->network->stats.sms.rp_err_other++;
sms_free(sms);
trans->sms.sms = NULL;
@@ -1064,6 +1069,8 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
DEBUGP(DSMS, "TX: SMS DELIVER\n");
+ lchan->ts->trx->bts->network->stats.sms.delivered++;
+
return gsm411_rp_sendmsg(msg, trans, GSM411_MT_RP_DATA_MT, msg_ref);
/* FIXME: enter 'wait for RP-ACK' state, start TR1N */
}
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 94d3d0d1..393b0f2a 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -97,9 +97,12 @@ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts)
DEBUGP(DHO, "(old_lchan on BTS %u, new BTS %u)\n",
old_lchan->ts->trx->bts->nr, bts->nr);
+ bts->network->stats.handover.attempted++;
+
new_lchan = lchan_alloc(bts, old_lchan->type);
if (!new_lchan) {
LOGP(DHO, LOGL_NOTICE, "No free channel\n");
+ bts->network->stats.handover.no_channel++;
return -ENOSPC;
}
@@ -143,6 +146,7 @@ static void ho_T3103_cb(void *_ho)
struct bsc_handover *ho = _ho;
DEBUGP(DHO, "HO T3103 expired\n");
+ ho->new_lchan->ts->trx->bts->network->stats.handover.timeout++;
lchan_free(ho->new_lchan);
llist_del(&ho->list);
@@ -211,6 +215,8 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
return -ENODEV;
}
+ new_lchan->ts->trx->bts->network->stats.handover.completed++;
+
bsc_del_timer(&ho->T3103);
/* update lchan pointer of transaction */
@@ -238,6 +244,8 @@ static int ho_gsm48_ho_fail(struct gsm_lchan *old_lchan)
return -ENODEV;
}
+ old_lchan->ts->trx->bts->network->stats.handover.failed++;
+
bsc_del_timer(&ho->T3103);
llist_del(&ho->list);
put_lchan(ho->new_lchan);
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index b273419c..538e0a8e 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -212,6 +212,8 @@ static void paging_T3113_expired(void *data)
cbfn = req->cbfn;
paging_remove_request(&req->bts->paging, req);
+ req->bts->network->stats.paging.expired++;
+
dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
if (cbfn)
cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL,
@@ -254,6 +256,8 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
struct gsm_bts *bts = NULL;
int num_pages = 0;
+ network->stats.paging.attempted++;
+
/* start paging subscriber on all BTS within Location Area */
do {
int rc;
@@ -269,6 +273,9 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
return rc;
} while (1);
+ if (num_pages == 0)
+ network->stats.paging.detached++;
+
return num_pages;
}
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index b13dc5f5..fa9b45da 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -761,6 +761,41 @@ DEFUN(show_paging,
return CMD_SUCCESS;
}
+DEFUN(show_stats,
+ show_stats_cmd,
+ "show statistics",
+ SHOW_STR "Display network statistics\n")
+{
+ struct gsm_network *net = gsmnet;
+
+ vty_out(vty, "Channel Requests: %lu total, %lu no channel%s",
+ net->stats.chreq.total, net->stats.chreq.no_channel,
+ VTY_NEWLINE);
+ vty_out(vty, "Location Update: %lu attach, %lu normal, %lu periodic%s",
+ net->stats.loc_upd_type.attach, net->stats.loc_upd_type.normal,
+ net->stats.loc_upd_type.periodic, VTY_NEWLINE);
+ vty_out(vty, "IMSI Detach Indications: %lu%s\n",
+ net->stats.loc_upd_type.detach, VTY_NEWLINE);
+ vty_out(vty, "Location Update Response: %lu accept, %lu reject%s",
+ net->stats.loc_upd_resp.accept,
+ net->stats.loc_upd_resp.reject, VTY_NEWLINE);
+ vty_out(vty, "Paging: %lu attempted, %lu complete, %lu expired%s",
+ net->stats.paging.attempted, net->stats.paging.completed,
+ net->stats.paging.expired, VTY_NEWLINE);
+ vty_out(vty, "Handover: %lu attempted, %lu no_channel, %lu timeout, "
+ "%lu completed, %lu failed%s", net->stats.handover.attempted,
+ net->stats.handover.no_channel, net->stats.handover.timeout,
+ net->stats.handover.completed, net->stats.handover.failed,
+ VTY_NEWLINE);
+ vty_out(vty, "SMS MO: %lu submitted, %lu no receiver%s",
+ net->stats.sms.submitted, net->stats.sms.no_receiver,
+ VTY_NEWLINE);
+ vty_out(vty, "SMS MT: %lu delivered, %lu no memory, %lu other error%s",
+ net->stats.sms.delivered, net->stats.sms.rp_err_mem,
+ net->stats.sms.rp_err_other, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net,
cfg_net_cmd,
"network",
@@ -1435,6 +1470,7 @@ int bsc_vty_init(struct gsm_network *net)
install_element(VIEW_NODE, &show_e1ts_cmd);
install_element(VIEW_NODE, &show_paging_cmd);
+ install_element(VIEW_NODE, &show_stats_cmd);
install_element(CONFIG_NODE, &cfg_net_cmd);
install_node(&net_node, config_write_net);