[layer23] Added simple network monitor. Use "monitor network 1" to enable.
This commit is contained in:
parent
f9d7d13a33
commit
6aa923f003
|
@ -196,4 +196,6 @@ extern const char *plmn_a_state_names[];
|
||||||
extern const char *plmn_m_state_names[];
|
extern const char *plmn_m_state_names[];
|
||||||
extern const char *cs_state_names[];
|
extern const char *cs_state_names[];
|
||||||
|
|
||||||
|
char *gsm_print_rxlev(uint8_t rxlev);
|
||||||
|
|
||||||
#endif /* _GSM322_H */
|
#endif /* _GSM322_H */
|
||||||
|
|
|
@ -152,6 +152,10 @@ struct gsm48_rrlayer {
|
||||||
/* BA range */
|
/* BA range */
|
||||||
uint8_t ba_ranges;
|
uint8_t ba_ranges;
|
||||||
uint32_t ba_range[16];
|
uint32_t ba_range[16];
|
||||||
|
|
||||||
|
/* monitor */
|
||||||
|
uint8_t monitor;
|
||||||
|
struct timer_list t_monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *get_rr_name(int value);
|
const char *get_rr_name(int value);
|
||||||
|
@ -168,5 +172,7 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg);
|
||||||
int gsm48_rr_los(struct osmocom_ms *ms);
|
int gsm48_rr_los(struct osmocom_ms *ms);
|
||||||
int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn);
|
int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn);
|
||||||
extern const char *gsm48_rr_state_names[];
|
extern const char *gsm48_rr_state_names[];
|
||||||
|
int gsm48_rr_start_monitor(struct osmocom_ms *ms);
|
||||||
|
int gsm48_rr_stop_monitor(struct osmocom_ms *ms);
|
||||||
|
|
||||||
#endif /* _GSM48_RR_H */
|
#endif /* _GSM48_RR_H */
|
||||||
|
|
|
@ -24,6 +24,13 @@ struct osmol2_entity {
|
||||||
osmol2_cb_t msg_handler;
|
osmol2_cb_t msg_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* RX measurement statistics */
|
||||||
|
struct rx_meas_stat {
|
||||||
|
uint32_t frames;
|
||||||
|
uint32_t berr;
|
||||||
|
uint32_t rxlev;
|
||||||
|
};
|
||||||
|
|
||||||
/* One Mobilestation for osmocom */
|
/* One Mobilestation for osmocom */
|
||||||
struct osmocom_ms {
|
struct osmocom_ms {
|
||||||
struct llist_head entity;
|
struct llist_head entity;
|
||||||
|
@ -39,6 +46,8 @@ struct osmocom_ms {
|
||||||
|
|
||||||
struct osmol2_entity l2_entity;
|
struct osmol2_entity l2_entity;
|
||||||
|
|
||||||
|
struct rx_meas_stat meas;
|
||||||
|
|
||||||
struct gsm48_rrlayer rrlayer;
|
struct gsm48_rrlayer rrlayer;
|
||||||
struct gsm322_plmn plmn;
|
struct gsm322_plmn plmn;
|
||||||
struct gsm322_cellsel cellsel;
|
struct gsm322_cellsel cellsel;
|
||||||
|
|
|
@ -219,7 +219,7 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg)
|
||||||
* support
|
* support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *gsm_print_rxlev(uint8_t rxlev)
|
char *gsm_print_rxlev(uint8_t rxlev)
|
||||||
{
|
{
|
||||||
static char string[5];
|
static char string[5];
|
||||||
if (rxlev == 0)
|
if (rxlev == 0)
|
||||||
|
|
|
@ -59,7 +59,10 @@
|
||||||
#include <osmocom/logging.h>
|
#include <osmocom/logging.h>
|
||||||
#include <osmocom/networks.h>
|
#include <osmocom/networks.h>
|
||||||
#include <osmocom/l1ctl.h>
|
#include <osmocom/l1ctl.h>
|
||||||
|
#include <osmocom/vty.h>
|
||||||
|
|
||||||
|
static void start_rr_t_monitor(struct gsm48_rrlayer *rr, int sec, int micro);
|
||||||
|
static void stop_rr_t_monitor(struct gsm48_rrlayer *rr);
|
||||||
static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg);
|
static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg);
|
||||||
static int gsm48_rr_dl_est(struct osmocom_ms *ms);
|
static int gsm48_rr_dl_est(struct osmocom_ms *ms);
|
||||||
|
|
||||||
|
@ -388,10 +391,68 @@ int gsm48_rsl_dequeue(struct osmocom_ms *ms)
|
||||||
return work;
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gsm48_rr_start_monitor(struct osmocom_ms *ms)
|
||||||
|
{
|
||||||
|
ms->rrlayer.monitor = 1;
|
||||||
|
memset(&ms->meas, 0, sizeof(&ms->meas));
|
||||||
|
start_rr_t_monitor(&ms->rrlayer, 1, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gsm48_rr_stop_monitor(struct osmocom_ms *ms)
|
||||||
|
{
|
||||||
|
ms->rrlayer.monitor = 0;
|
||||||
|
memset(&ms->meas, 0, sizeof(&ms->meas));
|
||||||
|
stop_rr_t_monitor(&ms->rrlayer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* timers handling
|
* timers handling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* special timer to monitor measurements */
|
||||||
|
static void timeout_rr_monitor(void *arg)
|
||||||
|
{
|
||||||
|
struct gsm48_rrlayer *rr = arg;
|
||||||
|
struct gsm322_cellsel *cs = &rr->ms->cellsel;
|
||||||
|
struct rx_meas_stat *meas = &rr->ms->meas;
|
||||||
|
struct gsm_settings *set = &rr->ms->settings;
|
||||||
|
int rxlev, berr;
|
||||||
|
uint8_t ch_type, ch_subch, ch_ts;
|
||||||
|
char text[256];
|
||||||
|
|
||||||
|
if (!cs->selected) {
|
||||||
|
sprintf(text, "MON: no cell selected");
|
||||||
|
} else if (!meas->frames) {
|
||||||
|
sprintf(text, "MON: no cell info");
|
||||||
|
} else {
|
||||||
|
rxlev = meas->rxlev / meas->frames;
|
||||||
|
berr = meas->berr / meas->frames;
|
||||||
|
sprintf(text, "MON: arfcn=%d lev=%s ber=%2d LAI=%s %s %04x "
|
||||||
|
"ID=%04x", cs->sel_arfcn, gsm_print_rxlev(rxlev),
|
||||||
|
berr, gsm_print_mcc(cs->sel_mcc),
|
||||||
|
gsm_print_mnc(cs->sel_mnc), cs->sel_lac, cs->sel_id);
|
||||||
|
if (rr->state == GSM48_RR_ST_DEDICATED) {
|
||||||
|
rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type,
|
||||||
|
&ch_subch, &ch_ts);
|
||||||
|
sprintf(text + strlen(text), " TA=%d pwr=%d TS=%d",
|
||||||
|
rr->ind_ta - set->alter_delay,
|
||||||
|
(set->alter_tx_power) ? set->alter_tx_power_value
|
||||||
|
: rr->ind_tx_power, ch_ts);
|
||||||
|
if (ch_type == RSL_CHAN_SDCCH8_ACCH
|
||||||
|
|| ch_type == RSL_CHAN_SDCCH4_ACCH)
|
||||||
|
sprintf(text + strlen(text), "/%d", ch_subch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vty_notify(rr->ms, "%s\n", text);
|
||||||
|
|
||||||
|
memset(meas, 0, sizeof(*meas));
|
||||||
|
start_rr_t_monitor(rr, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* special timer to ensure that UA is sent before disconnecting channel */
|
/* special timer to ensure that UA is sent before disconnecting channel */
|
||||||
static void timeout_rr_t_rel_wait(void *arg)
|
static void timeout_rr_t_rel_wait(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -453,6 +514,13 @@ static void timeout_rr_t3126(void *arg)
|
||||||
new_rr_state(rr, GSM48_RR_ST_IDLE);
|
new_rr_state(rr, GSM48_RR_ST_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void start_rr_t_monitor(struct gsm48_rrlayer *rr, int sec, int micro)
|
||||||
|
{
|
||||||
|
rr->t_monitor.cb = timeout_rr_monitor;
|
||||||
|
rr->t_monitor.data = rr;
|
||||||
|
bsc_schedule_timer(&rr->t_monitor, sec, micro);
|
||||||
|
}
|
||||||
|
|
||||||
static void start_rr_t_rel_wait(struct gsm48_rrlayer *rr, int sec, int micro)
|
static void start_rr_t_rel_wait(struct gsm48_rrlayer *rr, int sec, int micro)
|
||||||
{
|
{
|
||||||
LOGP(DRR, LOGL_INFO, "starting T_rel_wait with %d seconds\n", sec);
|
LOGP(DRR, LOGL_INFO, "starting T_rel_wait with %d seconds\n", sec);
|
||||||
|
@ -485,6 +553,14 @@ static void start_rr_t3126(struct gsm48_rrlayer *rr, int sec, int micro)
|
||||||
bsc_schedule_timer(&rr->t3126, sec, micro);
|
bsc_schedule_timer(&rr->t3126, sec, micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stop_rr_t_monitor(struct gsm48_rrlayer *rr)
|
||||||
|
{
|
||||||
|
if (bsc_timer_pending(&rr->t_monitor)) {
|
||||||
|
LOGP(DRR, LOGL_INFO, "stopping pending timer T_monitor\n");
|
||||||
|
bsc_del_timer(&rr->t_monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void stop_rr_t_rel_wait(struct gsm48_rrlayer *rr)
|
static void stop_rr_t_rel_wait(struct gsm48_rrlayer *rr)
|
||||||
{
|
{
|
||||||
if (bsc_timer_pending(&rr->t_rel_wait)) {
|
if (bsc_timer_pending(&rr->t_rel_wait)) {
|
||||||
|
@ -3073,7 +3149,7 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
|
||||||
|
|
||||||
/* setting (new) timing advance */
|
/* setting (new) timing advance */
|
||||||
rr->ind_ta = rr->cd_now.ta;
|
rr->ind_ta = rr->cd_now.ta;
|
||||||
LOGP(DRR, LOGL_INFO, "setting indicated ta %d (actual ta %d)\n",
|
LOGP(DRR, LOGL_INFO, "setting indicated TA %d (actual TA %d)\n",
|
||||||
rr->ind_ta, rr->ind_ta - set->alter_delay);
|
rr->ind_ta, rr->ind_ta - set->alter_delay);
|
||||||
l1ctl_tx_ph_param_req(ms, rr->ind_ta - set->alter_delay,
|
l1ctl_tx_ph_param_req(ms, rr->ind_ta - set->alter_delay,
|
||||||
(set->alter_tx_power) ? set->alter_tx_power_value
|
(set->alter_tx_power) ? set->alter_tx_power_value
|
||||||
|
@ -4156,6 +4232,7 @@ int gsm48_rr_exit(struct osmocom_ms *ms)
|
||||||
rr->rr_est_msg = NULL;
|
rr->rr_est_msg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop_rr_t_monitor(rr);
|
||||||
stop_rr_t_rel_wait(rr);
|
stop_rr_t_rel_wait(rr);
|
||||||
stop_rr_t3110(rr);
|
stop_rr_t3110(rr);
|
||||||
stop_rr_t3122(rr);
|
stop_rr_t3122(rr);
|
||||||
|
|
|
@ -154,6 +154,7 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
|
||||||
struct l1ctl_info_dl *dl, dl_cpy;
|
struct l1ctl_info_dl *dl, dl_cpy;
|
||||||
struct l1ctl_data_ind *ccch;
|
struct l1ctl_data_ind *ccch;
|
||||||
struct lapdm_entity *le;
|
struct lapdm_entity *le;
|
||||||
|
struct rx_meas_stat *meas = &ms->meas;
|
||||||
uint8_t chan_type, chan_ts, chan_ss;
|
uint8_t chan_type, chan_ts, chan_ss;
|
||||||
uint8_t gsmtap_chan_type;
|
uint8_t gsmtap_chan_type;
|
||||||
struct gsm_time tm;
|
struct gsm_time tm;
|
||||||
|
@ -175,7 +176,12 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
|
||||||
chan_nr2string(dl->chan_nr), tm.t1, tm.t2, tm.t3,
|
chan_nr2string(dl->chan_nr), tm.t1, tm.t2, tm.t3,
|
||||||
hexdump(ccch->data, sizeof(ccch->data)));
|
hexdump(ccch->data, sizeof(ccch->data)));
|
||||||
|
|
||||||
|
meas->frames++;
|
||||||
|
meas->berr += dl->num_biterr;
|
||||||
|
meas->rxlev += dl->rx_level;
|
||||||
|
|
||||||
if (dl->num_biterr) {
|
if (dl->num_biterr) {
|
||||||
|
printf("dropping frame with %u bit errors\n", dl->num_biterr);
|
||||||
LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n",
|
LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n",
|
||||||
dl->num_biterr);
|
dl->num_biterr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -280,6 +286,8 @@ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn,
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
memset(&ms->meas, 0, sizeof(ms->meas));
|
||||||
|
|
||||||
req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req));
|
req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req));
|
||||||
req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn));
|
req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn));
|
||||||
req->timeout = htons(timeout);
|
req->timeout = htons(timeout);
|
||||||
|
@ -371,6 +379,8 @@ int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
|
||||||
printf("Tx Dedic.Mode Est Req (arfcn=%u, chan_nr=0x%02x)\n",
|
printf("Tx Dedic.Mode Est Req (arfcn=%u, chan_nr=0x%02x)\n",
|
||||||
band_arfcn, chan_nr);
|
band_arfcn, chan_nr);
|
||||||
|
|
||||||
|
memset(&ms->meas, 0, sizeof(ms->meas));
|
||||||
|
|
||||||
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
||||||
ul->chan_nr = chan_nr;
|
ul->chan_nr = chan_nr;
|
||||||
ul->link_id = 0;
|
ul->link_id = 0;
|
||||||
|
@ -398,6 +408,8 @@ int tx_ph_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
|
||||||
printf("Tx Dedic.Mode Est Req (maio=%u, hsn=%u, "
|
printf("Tx Dedic.Mode Est Req (maio=%u, hsn=%u, "
|
||||||
"chan_nr=0x%02x)\n", maio, hsn, chan_nr);
|
"chan_nr=0x%02x)\n", maio, hsn, chan_nr);
|
||||||
|
|
||||||
|
memset(&ms->meas, 0, sizeof(ms->meas));
|
||||||
|
|
||||||
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
||||||
ul->chan_nr = chan_nr;
|
ul->chan_nr = chan_nr;
|
||||||
ul->link_id = 0;
|
ul->link_id = 0;
|
||||||
|
@ -426,6 +438,8 @@ int tx_ph_dm_rel_req(struct osmocom_ms *ms)
|
||||||
|
|
||||||
printf("Tx Dedic.Mode Rel Req\n");
|
printf("Tx Dedic.Mode Rel Req\n");
|
||||||
|
|
||||||
|
memset(&ms->meas, 0, sizeof(ms->meas));
|
||||||
|
|
||||||
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
|
||||||
|
|
||||||
return osmo_send_l1(ms, msg);
|
return osmo_send_l1(ms, msg);
|
||||||
|
|
|
@ -308,6 +308,35 @@ DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
|
||||||
|
"Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
|
||||||
|
{
|
||||||
|
struct osmocom_ms *ms;
|
||||||
|
|
||||||
|
ms = get_ms(argv[0], vty);
|
||||||
|
if (!ms)
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
gsm48_rr_start_monitor(ms);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
|
||||||
|
NO_STR "Monitor...\nDeactivate monitor of network information\n"
|
||||||
|
"Name of MS (see \"show ms\")")
|
||||||
|
{
|
||||||
|
struct osmocom_ms *ms;
|
||||||
|
|
||||||
|
ms = get_ms(argv[0], vty);
|
||||||
|
if (!ms)
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
gsm48_rr_stop_monitor(ms);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN(insert_test, insert_test_cmd, "insert testcard MS_NAME [mcc] [mnc]",
|
DEFUN(insert_test, insert_test_cmd, "insert testcard MS_NAME [mcc] [mnc]",
|
||||||
"Insert ...\nInsert test card\nName of MS (see \"show ms\")\n"
|
"Insert ...\nInsert test card\nName of MS (see \"show ms\")\n"
|
||||||
"Mobile Country Code\nMobile Network Code")
|
"Mobile Country Code\nMobile Network Code")
|
||||||
|
@ -1015,6 +1044,8 @@ int ms_vty_init(void)
|
||||||
install_element_ve(&show_ba_cmd);
|
install_element_ve(&show_ba_cmd);
|
||||||
install_element_ve(&show_forb_la_cmd);
|
install_element_ve(&show_forb_la_cmd);
|
||||||
install_element_ve(&show_forb_plmn_cmd);
|
install_element_ve(&show_forb_plmn_cmd);
|
||||||
|
install_element_ve(&monitor_network_cmd);
|
||||||
|
install_element_ve(&no_monitor_network_cmd);
|
||||||
|
|
||||||
install_element(ENABLE_NODE, &insert_test_cmd);
|
install_element(ENABLE_NODE, &insert_test_cmd);
|
||||||
install_element(ENABLE_NODE, &remove_sim_cmd);
|
install_element(ENABLE_NODE, &remove_sim_cmd);
|
||||||
|
|
Loading…
Reference in New Issue