keep some internal statistics inside OpenBSC
the statistics will give us some idea about the network load and performance.
This commit is contained in:
parent
a992a36d5f
commit
24ff6ee0a3
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue