keep some internal statistics inside OpenBSC

the statistics will give us some idea about the network load and
performance.
This commit is contained in:
Harald Welte 2009-12-22 00:41:05 +01:00
parent a992a36d5f
commit 24ff6ee0a3
8 changed files with 128 additions and 1 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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,

View File

@ -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 */

View File

@ -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 */
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);