diff options
author | Kirill Zakharenko <earwin@gmail.com> | 2020-05-01 18:49:56 +0300 |
---|---|---|
committer | Kirill Zakharenko <earwin@gmail.com> | 2020-05-01 18:49:56 +0300 |
commit | f51f0bcef9e4d66c5bf4a4563762cf3b38861c1c (patch) | |
tree | a83b9be3ac029e1e3d8fd78755d693eca2fa37d6 /src | |
parent | d7a64773bbd0f8bc98a55311a6b44108ac3b74d5 (diff) | |
parent | 74632859941d51a4f645d844cbb58709a8473443 (diff) |
Merge master into fairwaves/production
Diffstat (limited to 'src')
-rw-r--r-- | src/libfilter/bsc_msg_acc.c | 2 | ||||
-rw-r--r-- | src/osmo-bsc/abis_nm.c | 97 | ||||
-rw-r--r-- | src/osmo-bsc/abis_nm_vty.c | 2 | ||||
-rw-r--r-- | src/osmo-bsc/abis_om2000.c | 41 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_vty.c | 207 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_data.c | 4 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_bssap.c | 26 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_main.c | 26 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_vty.c | 4 | ||||
-rw-r--r-- | src/osmo-bsc/rest_octets.c | 9 | ||||
-rw-r--r-- | src/osmo-bsc/system_information.c | 11 | ||||
-rw-r--r-- | src/utils/meas_json.c | 14 | ||||
-rw-r--r-- | src/utils/meas_vis.c | 30 |
13 files changed, 365 insertions, 108 deletions
diff --git a/src/libfilter/bsc_msg_acc.c b/src/libfilter/bsc_msg_acc.c index de6c4d933..8853dbb5c 100644 --- a/src/libfilter/bsc_msg_acc.c +++ b/src/libfilter/bsc_msg_acc.c @@ -96,7 +96,7 @@ struct bsc_msg_acc_lst *bsc_msg_acc_lst_get(void *ctx, struct llist_head *head, lst = talloc_zero(ctx, struct bsc_msg_acc_lst); if (!lst) { - LOGP(DNAT, LOGL_ERROR, "Failed to allocate access list\n"); + LOGP(DFILTER, LOGL_ERROR, "Failed to allocate access list\n"); return NULL; } diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c index 7ca4e7983..32e9a8faf 100644 --- a/src/osmo-bsc/abis_nm.c +++ b/src/osmo-bsc/abis_nm.c @@ -353,37 +353,92 @@ static inline void handle_manufact_report(struct gsm_bts *bts, const uint8_t *p_ }; } -static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) +/* Parse into newly allocated struct abis_nm_fail_evt_rep, caller must free it. */ +struct nm_fail_rep_signal_data *abis_nm_fail_evt_rep_parse(struct msgb *mb, struct gsm_bts *bts) { struct abis_om_hdr *oh = msgb_l2(mb); struct abis_om_fom_hdr *foh = msgb_l3(mb); - struct e1inp_sign_link *sign_link = mb->dst; - struct tlv_parsed tp; - int rc = 0; + struct nm_fail_rep_signal_data *sd; const uint8_t *p_val = NULL; char *p_text = NULL; const char *e_type = NULL, *severity = NULL; - abis_nm_tlv_parse(&tp, sign_link->trx->bts, foh->data, - oh->length-sizeof(*foh)); + sd = talloc_zero(tall_bsc_ctx, struct nm_fail_rep_signal_data); + OSMO_ASSERT(sd); + + if (abis_nm_tlv_parse(&sd->tp, bts, foh->data, oh->length-sizeof(*foh)) < 0) + goto fail; - if (TLVP_PRESENT(&tp, NM_ATT_ADD_TEXT)) { - const uint8_t *val = TLVP_VAL(&tp, NM_ATT_ADD_TEXT); - p_text = talloc_strndup(tall_bsc_ctx, (const char *) val, - TLVP_LEN(&tp, NM_ATT_ADD_TEXT)); + if (TLVP_PRESENT(&sd->tp, NM_ATT_ADD_TEXT)) { + const uint8_t *val = TLVP_VAL(&sd->tp, NM_ATT_ADD_TEXT); + p_text = talloc_strndup(sd, (const char *) val, TLVP_LEN(&sd->tp, NM_ATT_ADD_TEXT)); } - if (TLVP_PRESENT(&tp, NM_ATT_EVENT_TYPE)) - e_type = abis_nm_event_type_name(*TLVP_VAL(&tp, - NM_ATT_EVENT_TYPE)); + if (TLVP_PRESENT(&sd->tp, NM_ATT_EVENT_TYPE)) + e_type = abis_nm_event_type_name(*TLVP_VAL(&sd->tp, NM_ATT_EVENT_TYPE)); + + if (TLVP_PRESENT(&sd->tp, NM_ATT_SEVERITY)) + severity = abis_nm_severity_name(*TLVP_VAL(&sd->tp, NM_ATT_SEVERITY)); + + if (TLVP_PRESENT(&sd->tp, NM_ATT_PROB_CAUSE)) + p_val = TLVP_VAL(&sd->tp, NM_ATT_PROB_CAUSE); + + sd->bts = bts; + sd->msg = mb; + if (e_type) + sd->parsed.event_type = e_type; + else + sd->parsed.event_type = talloc_strdup(sd, "<none>"); + if (severity) + sd->parsed.severity = severity; + else + sd->parsed.severity = talloc_strdup(sd, "<none>"); + if (p_text) + sd->parsed.additional_text = p_text; + else + sd->parsed.additional_text = talloc_strdup(sd, "<none>"); + sd->parsed.probable_cause = p_val; - if (TLVP_PRESENT(&tp, NM_ATT_SEVERITY)) - severity = abis_nm_severity_name(*TLVP_VAL(&tp, - NM_ATT_SEVERITY)); + return sd; +fail: + talloc_free(sd); + return NULL; +} - if (TLVP_PRESENT(&tp, NM_ATT_PROB_CAUSE)) { - p_val = TLVP_VAL(&tp, NM_ATT_PROB_CAUSE); +static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) +{ + struct abis_om_fom_hdr *foh = msgb_l3(mb); + struct nm_fail_rep_signal_data *sd; + int rc = 0; + const uint8_t *p_val; + const char *e_type, *severity, *p_text; + struct bts_oml_fail_rep *entry; + + /* Store copy in bts->oml_fail_rep */ + entry = talloc_zero(bts, struct bts_oml_fail_rep); + OSMO_ASSERT(entry); + entry->time = time(NULL); + entry->mb = msgb_copy_c(entry, mb, "OML failure report"); + llist_add(&entry->list, &bts->oml_fail_rep); + + /* Limit list size */ + if (llist_count(&bts->oml_fail_rep) > 50) { + struct bts_oml_fail_rep *old = llist_last_entry(&bts->oml_fail_rep, struct bts_oml_fail_rep, list); + llist_del(&old->list); + talloc_free(old); + } + + sd = abis_nm_fail_evt_rep_parse(mb, bts); + if (!sd) { + LOGPFOH(DNM, LOGL_ERROR, foh, "BTS%u: failed to parse Failure Event Report\n", bts->nr); + return -EINVAL; + } + e_type = sd->parsed.event_type; + severity = sd->parsed.severity; + p_text = sd->parsed.additional_text; + p_val = sd->parsed.probable_cause; + if (p_val) { switch (p_val[0]) { case NM_PCAUSE_T_MANUF: handle_manufact_report(bts, p_val, e_type, severity, @@ -398,9 +453,8 @@ static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) rc = -EINVAL; } - if (p_text) - talloc_free(p_text); - + osmo_signal_dispatch(SS_NM, S_NM_FAIL_REP, sd); + talloc_free(sd); return rc; } @@ -419,7 +473,6 @@ static int abis_nm_rcvmsg_report(struct msgb *mb, struct gsm_bts *bts) break; case NM_MT_FAILURE_EVENT_REP: rx_fail_evt_rep(mb, bts); - osmo_signal_dispatch(SS_NM, S_NM_FAIL_REP, mb); break; case NM_MT_TEST_REP: DEBUGPFOH(DNM, foh, "Test Report\n"); diff --git a/src/osmo-bsc/abis_nm_vty.c b/src/osmo-bsc/abis_nm_vty.c index b1c6d56d2..fe467fad1 100644 --- a/src/osmo-bsc/abis_nm_vty.c +++ b/src/osmo-bsc/abis_nm_vty.c @@ -165,7 +165,7 @@ DEFUN(oml_chg_adm_state, oml_chg_adm_state_cmd, } DEFUN(oml_opstart, oml_opstart_cmd, - "opstart", "Send an OPSTART message to the object") + "opstart", "Send an OPSTART message to the object\n") { struct oml_node_state *oms = vty->index; diff --git a/src/osmo-bsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c index 14c373b17..f8efa3990 100644 --- a/src/osmo-bsc/abis_om2000.c +++ b/src/osmo-bsc/abis_om2000.c @@ -202,6 +202,26 @@ enum abis_om2k_msgtype { OM2K_MSGT_NEGOT_REQ_ACK = 0x0104, OM2K_MSGT_NEGOT_REQ_NACK = 0x0105, OM2K_MSGT_NEGOT_REQ = 0x0106, + + OM2K_MSGT_BTS_INITIATED_REQ_ACK = 0x0108, + OM2K_MSGT_BTS_INITIATED_REQ_NACK = 0x0109, + OM2K_MSGT_BTS_INITIATED_REQ = 0x010a, + + OM2K_MSGT_RADIO_CHAN_REL_CMD = 0x010c, + OM2K_MSGT_RADIO_CHAN_REL_COMPL = 0x010e, + OM2K_MSGT_RADIO_CHAN_REL_REJ = 0x010f, + + OM2K_MSGT_FEATURE_CTRL_CMD = 0x0118, + OM2K_MSGT_FEATURE_CTRL_COMPL = 0x011a, + OM2K_MSGT_FEATURE_CTRL_REJ = 0x011b, + + OM2K_MSGT_MCTR_CONFIG_REQ = 0x012c, + OM2K_MSGT_MCTR_CONFIG_REQ_ACK = 0x012e, + OM2K_MSGT_MCTR_CONFIG_REQ_REJ = 0x012f, + + OM2K_MSGT_MCTR_CONFIG_RES_ACK = 0x0130, + OM2K_MSGT_MCTR_CONFIG_RES_NACK = 0x0131, + OM2K_MSGT_MCTR_CONFIG_RES = 0x0132, }; enum abis_om2k_dei { @@ -272,6 +292,13 @@ enum abis_om2k_dei { OM2K_DEI_FS_OFFSET = 0x98, OM2K_DEI_EXT_COND_MAP_2_EXT = 0x9c, OM2K_DEI_TSS_MO_STATE = 0x9d, + OM2K_DEI_CONFIG_TYPE = 0x9e, + OM2K_DEI_JITTER_SIZE = 0x9f, + OM2K_DEI_PACKING_ALGO = 0xa0, + OM2K_DEI_TRXC_LIST = 0xa8, + OM2K_DEI_MAX_ALLOWED_POWER = 0xa9, + OM2K_DEI_MAX_ALLOWED_NUM_TRXCS = 0xaa, + OM2K_DEI_MCTR_FEAT_STATUS_BMAP = 0xab, }; const struct tlv_definition om2k_att_tlvdef = { @@ -521,6 +548,12 @@ static const struct value_string om2k_msgcode_vals[] = { { 0x0118, "Feature Control Command" }, { 0x011a, "Feature Control Complete" }, { 0x011b, "Feature Control Reject" }, + { 0x012c, "MCTR Configuration Request" }, + { 0x012e, "MCTR Configuration Request Accept" }, + { 0x012f, "MCTR Configuration Request Reject" }, + { 0x0130, "MCTR Configuration Result ACK" }, + { 0x0131, "MCTR Configuration Result NACK" }, + { 0x0132, "MCTR Configuration Result" }, { 0, NULL } }; @@ -653,6 +686,13 @@ static const struct value_string om2k_attr_vals[] = { { 0x9b, "Master TX Chain Delay" }, { 0x9c, "External Condition Class 2 Extension" }, { 0x9d, "TSs MO State" }, + { 0x9e, "Configuration Type" }, + { 0x9f, "Jitter Size" }, + { 0xa0, "Packing Algorithm" }, + { 0xa8, "TRXC List" }, + { 0xa9, "Maximum Allowed Power" }, + { 0xaa, "Maximum Allowed Number of TRXCs" }, + { 0xab, "MCTR Feature Status Bitmap" }, { 0, NULL } }; @@ -663,6 +703,7 @@ const struct value_string om2k_mo_class_short_vals[] = { { 0x05, "IS" }, { 0x06, "CON" }, { 0x07, "DP" }, + { 0x08, "MCTR" }, { 0x0a, "CF" }, { 0x0b, "TX" }, { 0x0c, "RX" }, diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 1195d6580..f8bcee9a7 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -536,7 +536,7 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts) DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", SHOW_STR "Display information about a BTS\n" - "BTS number") + "BTS number\n") { struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr; @@ -559,6 +559,67 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", return CMD_SUCCESS; } +DEFUN(show_bts_fail_rep, show_bts_fail_rep_cmd, "show bts <0-255> fail-rep [reset]", + SHOW_STR "Display information about a BTS\n" + "BTS number\n" "OML failure reports\n" + "Clear the list of failure reports after showing them\n") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + struct bts_oml_fail_rep *entry; + struct gsm_bts *bts; + int bts_nr; + + bts_nr = atoi(argv[0]); + if (bts_nr >= net->num_bts) { + vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + bts = gsm_bts_num(net, bts_nr); + if (llist_empty(&bts->oml_fail_rep)) { + vty_out(vty, "No failure reports received.%s", VTY_NEWLINE); + return CMD_SUCCESS; + } + + llist_for_each_entry(entry, &bts->oml_fail_rep, list) { + struct nm_fail_rep_signal_data *sd; + char timestamp[20]; /* format like 2020-03-23 14:24:00 */ + enum abis_nm_pcause_type pcause; + enum abis_mm_event_causes cause; + + strftime(timestamp, sizeof(timestamp), "%F %T", localtime(&entry->time)); + sd = abis_nm_fail_evt_rep_parse(entry->mb, bts); + if (!sd) { + vty_out(vty, "[%s] (failed to parse report)%s", timestamp, VTY_NEWLINE); + continue; + } + pcause = sd->parsed.probable_cause[0]; + cause = osmo_load16be(sd->parsed.probable_cause + 1); + + vty_out(vty, "[%s] Type=%s, Severity=%s, ", timestamp, sd->parsed.event_type, sd->parsed.severity); + vty_out(vty, "Probable cause=%s: ", get_value_string(abis_nm_pcause_type_names, pcause)); + if (pcause == NM_PCAUSE_T_MANUF) + vty_out(vty, "%s, ", get_value_string(abis_mm_event_cause_names, cause)); + else + vty_out(vty, "%04X, ", cause); + vty_out(vty, "Additional text=%s%s", sd->parsed.additional_text, VTY_NEWLINE); + + talloc_free(sd); + } + + /* Optionally clear the list */ + if (argc > 1) { + while (!llist_empty(&bts->oml_fail_rep)) { + struct bts_oml_fail_rep *old = llist_last_entry(&bts->oml_fail_rep, struct bts_oml_fail_rep, + list); + llist_del(&old->list); + talloc_free(old); + } + } + + return CMD_SUCCESS; +} + DEFUN(show_rejected_bts, show_rejected_bts_cmd, "show rejected-bts", SHOW_STR "Display recently rejected BTS devices\n") { @@ -675,9 +736,6 @@ static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts) if (bts->gprs.mode == BTS_GPRS_NONE) return; - vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s", - bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE); - vty_out(vty, " gprs routing area %u%s", bts->gprs.rac, VTY_NEWLINE); vty_out(vty, " gprs network-control-order nc%u%s", @@ -711,6 +769,12 @@ static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts) vty_out(vty, " gprs nsvc %u remote ip %s%s", i, inet_ntoa(ia), VTY_NEWLINE); } + + /* EGPRS specific parameters */ + if (bts->gprs.mode == BTS_GPRS_EGPRS) { + if (bts->gprs.egprs_pkt_chan_request) + vty_out(vty, " gprs egprs-packet-channel-request%s", VTY_NEWLINE); + } } /* Write the model data if there is one */ @@ -1062,8 +1126,6 @@ static int config_write_net(struct vty *vty) ho_vty_write_net(vty, gsmnet); - osmo_tdef_vty_write(vty, gsmnet->T_defs, " "); - if (!gsmnet->dyn_ts_allow_tch_f) vty_out(vty, " dyn_ts_allow_tch_f 0%s", VTY_NEWLINE); if (gsmnet->tz.override != 0) { @@ -1094,6 +1156,9 @@ static int config_write_net(struct vty *vty) meas_scenario, VTY_NEWLINE); } + if (gsmnet->allow_unusable_timeslots) + vty_out(vty, " allow-unusable-timeslots%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -2498,7 +2563,7 @@ DEFUN(cfg_bts_ccch_load_ind_thresh, "ccch load-indication-threshold <0-100>", CCCH_STR "Percentage of CCCH load at which BTS sends RSL CCCH LOAD IND\n" - "CCCH Load Threshold in percent (Default: 10)") + "CCCH Load Threshold in percent (Default: 10)\n") { struct gsm_bts *bts = vty->index; bts->ccch_load_ind_thresh = atoi(argv[0]); @@ -2513,7 +2578,7 @@ DEFUN(cfg_bts_rach_nm_b_thresh, RACH_STR NM_STR "Set the NM Busy Threshold\n" "Set the NM Busy Threshold\n" - "NM Busy Threshold in dB") + "NM Busy Threshold in dB\n") { struct gsm_bts *bts = vty->index; bts->rach_b_thresh = atoi(argv[0]); @@ -2617,7 +2682,7 @@ DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd, "MS Options\n" "Maximum transmit power of the MS\n" "Maximum transmit power of the MS\n" - "Maximum transmit power of the MS in dBm") + "Maximum transmit power of the MS in dBm\n") { struct gsm_bts *bts = vty->index; @@ -2632,7 +2697,7 @@ DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd, "cell reselection hysteresis <0-14>", CELL_STR "Cell re-selection parameters\n" "Cell Re-Selection Hysteresis in dB\n" - "Cell Re-Selection Hysteresis in dB") + "Cell Re-Selection Hysteresis in dB\n") { struct gsm_bts *bts = vty->index; @@ -2646,7 +2711,7 @@ DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd, "Minimum RxLev needed for cell access\n" "Minimum RxLev needed for cell access\n" "Minimum RxLev needed for cell access\n" - "Minimum RxLev needed for cell access (better than -110dBm)") + "Minimum RxLev needed for cell access (better than -110dBm)\n") { struct gsm_bts *bts = vty->index; @@ -2687,7 +2752,7 @@ DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd, "temporary offset <0-60>", "Cell selection temporary negative offset\n" "Cell selection temporary negative offset\n" - "Cell selection temporary negative offset in dB") + "Cell selection temporary negative offset in dB\n") { struct gsm_bts *bts = vty->index; @@ -2701,7 +2766,7 @@ DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd, "temporary offset infinite", "Cell selection temporary negative offset\n" "Cell selection temporary negative offset\n" - "Sets cell selection temporary negative offset to infinity") + "Sets cell selection temporary negative offset to infinity\n") { struct gsm_bts *bts = vty->index; @@ -2731,7 +2796,7 @@ DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd, "Cell selection penalty time\n" "Set cell selection penalty time to reserved value 31, " "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 " - "and TEMPORARY_OFFSET is ignored)") + "and TEMPORARY_OFFSET is ignored)\n") { struct gsm_bts *bts = vty->index; @@ -2778,7 +2843,7 @@ DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd, GPRS_TEXT "GPRS Cell Settings\n" "GPRS BSSGP VC Identifier\n" - "GPRS BSSGP VC Identifier") + "GPRS BSSGP VC Identifier\n") { /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */ struct gsm_bts *bts = vty->index; @@ -2797,7 +2862,7 @@ DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd, "gprs nsei <0-65535>", GPRS_TEXT "GPRS NS Entity Identifier\n" - "GPRS NS Entity Identifier") + "GPRS NS Entity Identifier\n") { struct gsm_bts *bts = vty->index; @@ -2818,7 +2883,7 @@ DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd, "gprs nsvc <0-1> nsvci <0-65535>", GPRS_TEXT NSVC_TEXT "NS Virtual Connection Identifier\n" - "GPRS NS VC Identifier") + "GPRS NS VC Identifier\n") { struct gsm_bts *bts = vty->index; int idx = atoi(argv[0]); @@ -3064,29 +3129,65 @@ DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd, return CMD_SUCCESS; } -DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs, +DEFUN_DEPRECATED(cfg_bts_gprs_11bit_rach_support_for_egprs, cfg_bts_gprs_11bit_rach_support_for_egprs_cmd, "gprs 11bit_rach_support_for_egprs (0|1)", - GPRS_TEXT "11 bit RACH options\n" - "Disable 11 bit RACH for EGPRS\n" - "Enable 11 bit RACH for EGPRS") + GPRS_TEXT "EGPRS Packet Channel Request support\n" + "Disable EGPRS Packet Channel Request support\n" + "Enable EGPRS Packet Channel Request support\n") { struct gsm_bts *bts = vty->index; - bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]); + vty_out(vty, "%% 'gprs 11bit_rach_support_for_egprs' is now deprecated: " + "use '[no] gprs egprs-packet-channel-request' instead%s", VTY_NEWLINE); + + bts->gprs.egprs_pkt_chan_request = (argv[0][0] == '1'); - if (bts->gprs.supports_egprs_11bit_rach > 1) { - vty_out(vty, "Error in RACH type%s", VTY_NEWLINE); + if (bts->gprs.mode == BTS_GPRS_NONE && bts->gprs.egprs_pkt_chan_request) { + vty_out(vty, "%% (E)GPRS is not enabled (see 'gprs mode')%s", VTY_NEWLINE); return CMD_WARNING; } - if ((bts->gprs.mode == BTS_GPRS_NONE) && - (bts->gprs.supports_egprs_11bit_rach == 1)) { - vty_out(vty, "Error:gprs mode is none and 11bit rach is" - " enabled%s", VTY_NEWLINE); + if (bts->gprs.mode != BTS_GPRS_EGPRS) { + vty_out(vty, "%% EGPRS Packet Channel Request support requires " + "EGPRS mode to be enabled (see 'gprs mode')%s", VTY_NEWLINE); + /* Do not return here, keep the old behaviour. */ + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_gprs_egprs_pkt_chan_req, + cfg_bts_gprs_egprs_pkt_chan_req_cmd, + "gprs egprs-packet-channel-request", + GPRS_TEXT "EGPRS Packet Channel Request support") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gprs.mode != BTS_GPRS_EGPRS) { + vty_out(vty, "%% EGPRS Packet Channel Request support requires " + "EGPRS mode to be enabled (see 'gprs mode')%s", VTY_NEWLINE); return CMD_WARNING; } + bts->gprs.egprs_pkt_chan_request = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_gprs_egprs_pkt_chan_req, + cfg_bts_no_gprs_egprs_pkt_chan_req_cmd, + "no gprs egprs-packet-channel-request", + NO_STR GPRS_TEXT "EGPRS Packet Channel Request support") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gprs.mode != BTS_GPRS_EGPRS) { + vty_out(vty, "%% EGPRS Packet Channel Request support requires " + "EGPRS mode to be enabled (see 'gprs mode')%s", VTY_NEWLINE); + return CMD_WARNING; + } + + bts->gprs.egprs_pkt_chan_request = false; return CMD_SUCCESS; } @@ -3719,7 +3820,7 @@ DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd, #define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n" #define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n" -static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full) +static int get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full) { struct gsm_bts *bts = vty->index; struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half; @@ -3735,12 +3836,12 @@ static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int if (mode_prev > mode) { vty_out(vty, "Modes must be listed in order%s", VTY_NEWLINE); - return; + return -1; } if (mode_prev == mode) { vty_out(vty, "Modes must be unique %s", VTY_NEWLINE); - return; + return -2; } mode_prev = mode; } @@ -3765,6 +3866,7 @@ static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int mr->ms_mode[i].hysteresis = 0; mr->bts_mode[i].hysteresis = 0; } + return 0; } static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full) @@ -3880,7 +3982,8 @@ DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd, AMR_TEXT "Full Rate\n" AMR_MODE_TEXT AMR_TCHF_HELP_STR) { - get_amr_from_arg(vty, 1, argv, 1); + if (get_amr_from_arg(vty, 1, argv, 1)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3889,7 +3992,8 @@ DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd, AMR_TEXT "Full Rate\n" AMR_MODE_TEXT AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR) { - get_amr_from_arg(vty, 2, argv, 1); + if (get_amr_from_arg(vty, 2, argv, 1)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3898,7 +4002,8 @@ DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd, AMR_TEXT "Full Rate\n" AMR_MODE_TEXT AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR) { - get_amr_from_arg(vty, 3, argv, 1); + if (get_amr_from_arg(vty, 3, argv, 1)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3907,7 +4012,8 @@ DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd, AMR_TEXT "Full Rate\n" AMR_MODE_TEXT AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR) { - get_amr_from_arg(vty, 4, argv, 1); + if (get_amr_from_arg(vty, 4, argv, 1)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3978,7 +4084,8 @@ DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd, AMR_TEXT "Half Rate\n" AMR_MODE_TEXT AMR_TCHH_HELP_STR) { - get_amr_from_arg(vty, 1, argv, 0); + if (get_amr_from_arg(vty, 1, argv, 0)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3987,7 +4094,8 @@ DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd, AMR_TEXT "Half Rate\n" AMR_MODE_TEXT AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR) { - get_amr_from_arg(vty, 2, argv, 0); + if (get_amr_from_arg(vty, 2, argv, 0)) + return CMD_WARNING; return check_amr_config(vty); } @@ -3996,7 +4104,8 @@ DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd, AMR_TEXT "Half Rate\n" AMR_MODE_TEXT AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR) { - get_amr_from_arg(vty, 3, argv, 0); + if (get_amr_from_arg(vty, 3, argv, 0)) + return CMD_WARNING; return check_amr_config(vty); } @@ -4005,7 +4114,8 @@ DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd, AMR_TEXT "Half Rate\n" AMR_MODE_TEXT AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR) { - get_amr_from_arg(vty, 4, argv, 0); + if (get_amr_from_arg(vty, 4, argv, 0)) + return CMD_WARNING; return check_amr_config(vty); } @@ -4129,8 +4239,8 @@ DEFUN(cfg_bts_no_t3113_dynamic, cfg_bts_no_t3113_dynamic_cmd, DEFUN(cfg_trx, cfg_trx_cmd, "trx <0-255>", - TRX_TEXT - "Select a TRX to configure") + TRX_TEXT + "Select a TRX to configure\n") { int trx_nr = atoi(argv[0]); struct gsm_bts *bts = vty->index; @@ -5202,6 +5312,17 @@ DEFUN(cfg_net_timer, cfg_net_timer_cmd, return osmo_tdef_vty_set_cmd(vty, net->T_defs, argv); } +DEFUN(cfg_net_allow_unusable_timeslots, cfg_net_allow_unusable_timeslots_cmd, + "allow-unusable-timeslots", + "Don't refuse to start with mutually exclusive codec settings\n") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + net->allow_unusable_timeslots = true; + LOGP(DMSC, LOGL_ERROR, "Configuration contains 'allow-unusable-timeslots'. OsmoBSC will start up even if the" + " configuration has unusable codec settings!\n"); + return CMD_SUCCESS; +} + extern int bsc_vty_init_extra(void); int bsc_vty_init(struct gsm_network *network) @@ -5247,9 +5368,11 @@ int bsc_vty_init(struct gsm_network *network) install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd); install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd); install_element(GSMNET_NODE, &cfg_net_timer_cmd); + install_element(GSMNET_NODE, &cfg_net_allow_unusable_timeslots_cmd); install_element_ve(&bsc_show_net_cmd); install_element_ve(&show_bts_cmd); + install_element_ve(&show_bts_fail_rep_cmd); install_element_ve(&show_rejected_bts_cmd); install_element_ve(&show_trx_cmd); install_element_ve(&show_trx_con_cmd); @@ -5329,6 +5452,8 @@ int bsc_vty_init(struct gsm_network *network) install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd); install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd); install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd); + install_element(BTS_NODE, &cfg_bts_no_gprs_egprs_pkt_chan_req_cmd); + install_element(BTS_NODE, &cfg_bts_gprs_egprs_pkt_chan_req_cmd); install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd); install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd); install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd); diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c index 1f19b4ebc..02541c7f3 100644 --- a/src/osmo-bsc/gsm_data.c +++ b/src/osmo-bsc/gsm_data.c @@ -807,6 +807,9 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num) memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, sizeof(bts->gprs.cell.rlc_cfg)); + /* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */ + bts->gprs.cell.bvci = 2; + /* init statistics */ bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr); if (!bts->bts_ctrs) { @@ -878,6 +881,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num) INIT_LLIST_HEAD(&bts->abis_queue); INIT_LLIST_HEAD(&bts->loc_list); INIT_LLIST_HEAD(&bts->local_neighbors); + INIT_LLIST_HEAD(&bts->oml_fail_rep); /* Enable all codecs by default. These get reset to a more fine grained selection IF a * 'codec-support' config appears in the config file (see bsc_vty.c). */ diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 74faae1bc..1ba490faa 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -568,20 +568,24 @@ reject: static void bssmap_handle_ass_req_lcls(struct gsm_subscriber_connection *conn, const struct tlv_parsed *tp) { - const uint8_t *config, *control, *gcr, gcr_len = TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF); - - if (gcr_len > sizeof(conn->lcls.global_call_ref)) - LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too long\n", - gcr_len); - else { - gcr = TLVP_VAL_MINLEN(tp, GSM0808_IE_GLOBAL_CALL_REF, 13); - if (gcr) { + const uint8_t *config, *control, *gcr; + uint8_t gcr_len; + + /* TS 48.008 sec 3.2.2.115 Global Call Reference */ + if (TLVP_PRESENT(tp, GSM0808_IE_GLOBAL_CALL_REF)) { + gcr = TLVP_VAL(tp, GSM0808_IE_GLOBAL_CALL_REF); + gcr_len = TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF); + if (gcr_len > sizeof(conn->lcls.global_call_ref)) { + LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too long: %s\n", + gcr_len, osmo_hexdump_nospc(gcr, gcr_len)); + } else if (gcr_len < 13) { /* FIXME: document this magic value 13 */ + LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too short: %s\n", + gcr_len, osmo_hexdump_nospc(gcr, gcr_len)); + } else { LOGPFSM(conn->fi, "Setting GCR to %s\n", osmo_hexdump_nospc(gcr, gcr_len)); memcpy(&conn->lcls.global_call_ref, gcr, gcr_len); conn->lcls.global_call_ref_len = gcr_len; - } else - LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too short\n", - gcr_len); + } } config = TLVP_VAL_MINLEN(tp, GSM0808_IE_LCLS_CONFIG, 1); diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c index 6b1427903..ad5a3a9da 100644 --- a/src/osmo-bsc/osmo_bsc_main.c +++ b/src/osmo-bsc/osmo_bsc_main.c @@ -713,7 +713,7 @@ static const struct log_info_cat osmo_bsc_categories[] = { .name = "DNM", .description = "A-bis Network Management / O&M (NM/OML)", .color = "\033[1;36m", - .enabled = 1, .loglevel = LOGL_INFO, + .enabled = 1, .loglevel = LOGL_NOTICE, }, [DPAG] = { .name = "DPAG", @@ -748,11 +748,6 @@ static const struct log_info_cat osmo_bsc_categories[] = { .description = "Reference Counting", .enabled = 0, .loglevel = LOGL_NOTICE, }, - [DNAT] = { - .name = "DNAT", - .description = "GSM 08.08 NAT/Multiplexer", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, [DCTRL] = { .name = "DCTRL", .description = "Control interface", @@ -761,12 +756,12 @@ static const struct log_info_cat osmo_bsc_categories[] = { [DFILTER] = { .name = "DFILTER", .description = "BSC/NAT IMSI based filtering", - .enabled = 1, .loglevel = LOGL_DEBUG, + .enabled = 1, .loglevel = LOGL_NOTICE, }, [DPCU] = { .name = "DPCU", .description = "PCU Interface", - .enabled = 1, .loglevel = LOGL_DEBUG, + .enabled = 1, .loglevel = LOGL_NOTICE, }, [DLCLS] = { .name = "DLCLS", @@ -850,6 +845,7 @@ int main(int argc, char **argv) ctrl_vty_init(tall_bsc_ctx); logging_vty_add_deprecated_subsys(tall_bsc_ctx, "cc"); logging_vty_add_deprecated_subsys(tall_bsc_ctx, "mgcp"); + logging_vty_add_deprecated_subsys(tall_bsc_ctx, "nat"); /* Initialize SS7 */ OSMO_ASSERT(osmo_ss7_init() == 0); @@ -902,12 +898,20 @@ int main(int argc, char **argv) } rc = check_codec_pref(&bsc_gsmnet->bsc_data->mscs); - if (rc < 0) - LOGP(DMSC, LOGL_ERROR, "Configuration contains mutually exclusive codec settings -- check configuration!\n"); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "Configuration contains mutually exclusive codec settings -- check" + " configuration!\n"); + if (!bsc_gsmnet->allow_unusable_timeslots) { + LOGP(DMSC, LOGL_ERROR, "You should really fix that! However, you can prevent OsmoBSC from" + " stopping here by setting 'allow-unusable-timeslots' in the 'network'" + " section of the config.\n"); + exit(1); + } + } llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry) { if (osmo_bsc_msc_init(msc) != 0) { - LOGP(DNAT, LOGL_ERROR, "Failed to start up. Exiting.\n"); + LOGP(DMSC, LOGL_ERROR, "Failed to start up. Exiting.\n"); exit(1); } } diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c index e656d7079..c372b48ff 100644 --- a/src/osmo-bsc/osmo_bsc_vty.c +++ b/src/osmo-bsc/osmo_bsc_vty.c @@ -539,7 +539,7 @@ DEFUN(cfg_msc_acc_lst_name, cfg_msc_acc_lst_name_cmd, "access-list-name NAME", "Set the name of the access list to use.\n" - "The name of the to be used access list.") + "The name of the to be used access list.\n") { struct bsc_msc_data *msc = bsc_msc_data(vty); @@ -792,7 +792,7 @@ DEFUN(cfg_bsc_acc_lst_name, cfg_bsc_acc_lst_name_cmd, "access-list-name NAME", "Set the name of the access list to use.\n" - "The name of the to be used access list.") + "The name of the to be used access list.\n") { struct osmo_bsc_data *bsc = osmo_bsc_data(vty); diff --git a/src/osmo-bsc/rest_octets.c b/src/osmo-bsc/rest_octets.c index 1d2279bf9..2238b088d 100644 --- a/src/osmo-bsc/rest_octets.c +++ b/src/osmo-bsc/rest_octets.c @@ -822,13 +822,8 @@ static int append_gprs_cell_opt(struct bitvec *bv, /* EGPRS supported in the cell */ bitvec_set_bit(bv, 1); - /* 1bit EGPRS PACKET CHANNEL REQUEST */ - if (gco->supports_egprs_11bit_rach == 0) { - bitvec_set_bit(bv, - gco->ext_info.use_egprs_p_ch_req); - } else { - bitvec_set_bit(bv, 0); - } + /* 1bit EGPRS PACKET CHANNEL REQUEST (inverted logic) */ + bitvec_set_bit(bv, !gco->ext_info.use_egprs_p_ch_req); /* 4bit BEP PERIOD */ bitvec_set_uint(bv, gco->ext_info.bep_period, 4); diff --git a/src/osmo-bsc/system_information.c b/src/osmo-bsc/system_information.c index 6e5841966..d5be3f2d7 100644 --- a/src/osmo-bsc/system_information.c +++ b/src/osmo-bsc/system_information.c @@ -1151,11 +1151,10 @@ static struct gsm48_si13_info si13_default = { .bs_cv_max = 15, .ctrl_ack_type_use_block = true, .ext_info_present = 0, - .supports_egprs_11bit_rach = 0, .ext_info = { /* The values below are just guesses ! */ .egprs_supported = 0, - .use_egprs_p_ch_req = 1, + .use_egprs_p_ch_req = 0, .bep_period = 5, .pfc_supported = 0, .dtm_supported = 0, @@ -1197,8 +1196,12 @@ static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) /* Information about the other SIs */ si13_default.bcch_change_mark = bts->bcch_change_mark; - si13_default.cell_opts.supports_egprs_11bit_rach = - bts->gprs.supports_egprs_11bit_rach; + + /* Whether EGPRS capable MSs shall use EGPRS PACKET CHANNEL REQUEST */ + if (bts->gprs.egprs_pkt_chan_request) + si13_default.cell_opts.ext_info.use_egprs_p_ch_req = 1; + else + si13_default.cell_opts.ext_info.use_egprs_p_ch_req = 0; ret = rest_octets_si13(si13->rest_octets, &si13_default); if (ret < 0) diff --git a/src/utils/meas_json.c b/src/utils/meas_json.c index a3526de5d..6aa531a7f 100644 --- a/src/utils/meas_json.c +++ b/src/utils/meas_json.c @@ -34,6 +34,7 @@ #include <osmocom/core/socket.h> #include <osmocom/core/msgb.h> #include <osmocom/core/select.h> +#include <osmocom/core/application.h> #include <osmocom/gsm/gsm_utils.h> @@ -171,8 +172,21 @@ static int udp_fd_cb(struct osmo_fd *ofd, unsigned int what) return 0; } +/* default categories */ +static struct log_info_cat default_categories[] = { +}; + +static const struct log_info meas_json_log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + int main(int argc, char **argv) { + + void *tall_ctx = talloc_named_const(NULL, 0, "meas_json"); + osmo_init_logging2(tall_ctx, &meas_json_log_info); + int rc; struct osmo_fd udp_ofd; diff --git a/src/utils/meas_vis.c b/src/utils/meas_vis.c index cba08f5c3..01be98611 100644 --- a/src/utils/meas_vis.c +++ b/src/utils/meas_vis.c @@ -13,6 +13,8 @@ #include <osmocom/core/msgb.h> #include <osmocom/core/select.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/application.h> #include <osmocom/gsm/gsm_utils.h> @@ -203,7 +205,7 @@ void write_uni(struct ms_state *ms, struct ms_state_uni *msu, snprintf(msu->label, sizeof(msu->label), "</%d>%1d<!%d> %3d %2u %2d %4u", qual_col, lq->rx_qual, qual_col, pwr, ms->mr.ms_l1.ta, ms->mr.ms_timing_offset, - now - msu->last_update); + (unsigned int)(now - msu->last_update)); msu->cdk_label = newCDKLabel(g_st.cdkscreen, RIGHT, row, msu->_lbl, 1, FALSE, FALSE); } @@ -258,16 +260,33 @@ const struct value_string col_strs[] = { { 0, NULL } }; +/* default categories */ +static struct log_info_cat default_categories[] = { +}; + +static const struct log_info meas_vis_log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + int main(int argc, char **argv) { int rc; char *header[1]; char *title[1]; + struct log_target *stderr_target; + + void *tall_ctx = talloc_named_const(NULL, 0, "meas_vis"); + osmo_init_logging2(tall_ctx, &meas_vis_log_info); msgb_talloc_ctx_init(NULL, 0); - printf("sizeof(gsm_meas_rep)=%u\n", sizeof(struct gsm_meas_rep)); - printf("sizeof(meas_feed_meas)=%u\n", sizeof(struct meas_feed_meas)); + printf("sizeof(gsm_meas_rep)=%zu\n", sizeof(struct gsm_meas_rep)); + printf("sizeof(meas_feed_meas)=%zu\n", sizeof(struct meas_feed_meas)); + g_st.udp_ofd.cb = udp_fd_cb; + rc = osmo_sock_init_ofd(&g_st.udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 8888, OSMO_SOCK_F_BIND); + if (rc < 0) + exit(1); INIT_LLIST_HEAD(&g_st.ms_list); g_st.curses_win = initscr(); @@ -296,11 +315,6 @@ int main(int argc, char **argv) exit(0); #endif - g_st.udp_ofd.cb = udp_fd_cb; - rc = osmo_sock_init_ofd(&g_st.udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 8888, OSMO_SOCK_F_BIND); - if (rc < 0) - exit(1); - while (1) { osmo_select_main(0); update_sliders(); |