diff options
Diffstat (limited to 'src/host')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/osmocom_data.h | 5 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/settings.h | 3 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/support.h | 1 | ||||
-rw-r--r-- | src/host/layer23/src/common/l1ctl.c | 54 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm322.c | 36 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_rr.c | 43 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/settings.c | 1 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/support.c | 1 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 16 |
9 files changed, 109 insertions, 51 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index a20b177f..bc0c7d87 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -40,6 +40,10 @@ struct rx_meas_stat { uint32_t snr; uint32_t berr; uint32_t rxlev; + + /* counters loss criterion */ + int16_t dsc, ds_fail; + int16_t s, rl_fail; }; /* One Mobilestation for osmocom */ @@ -76,6 +80,7 @@ enum osmobb_meas_sig { S_L1CTL_PM_DONE, S_L1CTL_CCCH_MODE_CONF, S_L1CTL_TCH_MODE_CONF, + S_L1CTL_LOSS_IND, }; struct osmobb_fbsb_res { diff --git a/src/host/layer23/include/osmocom/bb/mobile/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h index 4c66f348..24379514 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/settings.h +++ b/src/host/layer23/include/osmocom/bb/mobile/settings.h @@ -64,6 +64,9 @@ struct gsm_settings { uint8_t half_v3; uint8_t ch_cap; /* channel capability */ int8_t min_rxlev_db; /* min DB to access */ + + /* radio */ + uint16_t dsc_max; }; int gsm_settings_init(struct osmocom_ms *ms); diff --git a/src/host/layer23/include/osmocom/bb/mobile/support.h b/src/host/layer23/include/osmocom/bb/mobile/support.h index b609b7da..cbe6e19b 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/support.h +++ b/src/host/layer23/include/osmocom/bb/mobile/support.h @@ -76,6 +76,7 @@ struct gsm_support { int8_t min_rxlev_db; uint8_t scan_to; uint8_t sync_to; + uint16_t dsc_max; /* maximum dl signal failure counter */ /* codecs */ uint8_t full_v1; diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index be84bf95..0b25008e 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -160,7 +160,51 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg) meas->berr += dl->num_biterr; meas->rxlev += dl->rx_level; - if (dl->num_biterr) { + /* counting loss criteria */ + if (!(dl->link_id & 0x40)) { + switch (chan_type) { + case RSL_CHAN_PCH_AGCH: + if (!meas->ds_fail) + break; + if (dl->fire_crc >= 2) + meas->dsc -= 4; + else + meas->dsc += 1; + if (meas->dsc > meas->ds_fail) + meas->dsc = meas->ds_fail; + if (meas->dsc < meas->ds_fail) + printf("LOSS counter for CCCH %d\n", meas->dsc); + if (meas->dsc > 0) + break; + meas->ds_fail = 0; + dispatch_signal(SS_L1CTL, S_L1CTL_LOSS_IND, ms); + break; + } + } else { + switch (chan_type) { + case RSL_CHAN_Bm_ACCHs: + case RSL_CHAN_Lm_ACCHs: + case RSL_CHAN_SDCCH4_ACCH: + case RSL_CHAN_SDCCH8_ACCH: + if (!meas->rl_fail) + break; + if (dl->fire_crc >= 2) + meas->s -= 1; + else + meas->s += 2; + if (meas->s > meas->rl_fail) + meas->s = meas->rl_fail; + if (meas->s < meas->rl_fail) + printf("LOSS counter for ACCH %d\n", meas->s); + if (meas->s > 0) + break; + meas->rl_fail = 0; + dispatch_signal(SS_L1CTL, S_L1CTL_LOSS_IND, ms); + break; + } + } + + if (dl->fire_crc >= 2) { printf("Dropping frame with %u bit errors\n", dl->num_biterr); LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n", dl->num_biterr); @@ -266,8 +310,6 @@ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, if (!msg) return -1; - memset(&ms->meas, 0, sizeof(ms->meas)); - req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req)); req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn)); req->timeout = htons(timeout); @@ -399,8 +441,6 @@ int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (arfcn=%u, " "chan_nr=0x%02x)\n", band_arfcn, chan_nr); - memset(&ms->meas, 0, sizeof(ms->meas)); - ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul)); ul->chan_nr = chan_nr; ul->link_id = 0; @@ -430,8 +470,6 @@ int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (maio=%u, hsn=%u, " "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->chan_nr = chan_nr; ul->link_id = 0; @@ -522,8 +560,6 @@ int l1ctl_tx_dm_rel_req(struct osmocom_ms *ms) LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Rel Req\n"); - memset(&ms->meas, 0, sizeof(ms->meas)); - ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul)); return osmo_send_l1(ms, msg); diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c index 92287275..807c6624 100644 --- a/src/host/layer23/src/mobile/gsm322.c +++ b/src/host/layer23/src/mobile/gsm322.c @@ -236,6 +236,7 @@ static int gsm322_sync_to_cell(struct gsm322_cellsel *cs) { struct osmocom_ms *ms = cs->ms; struct gsm48_sysinfo *s = cs->si; + struct rx_meas_stat *meas = &ms->meas; cs->ccch_state = GSM322_CCCH_ST_INIT; if (s && s->si3) { @@ -257,6 +258,8 @@ static int gsm322_sync_to_cell(struct gsm322_cellsel *cs) cs->ccch_mode = CCCH_MODE_NONE; } + meas->frames = meas->snr = meas->berr = meas->rxlev = 0; + l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); return l1ctl_tx_fbsb_req(ms, cs->arfcn, L1CTL_FBSB_F_FB01SB, 100, 0, @@ -443,30 +446,6 @@ void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro) bsc_schedule_timer(&cs->timer, sec, micro); } -/* start loss timer */ -void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro) -{ - /* update timer */ - cs->timer.cb = gsm322_cs_loss; - cs->timer.data = cs; - if (bsc_timer_pending(&cs->timer)) { - struct timeval current_time; - unsigned long long currentTime; - - gettimeofday(¤t_time, NULL); - currentTime = current_time.tv_sec * 1000000LL - + current_time.tv_usec; - currentTime += sec * 1000000LL + micro; - cs->timer.timeout.tv_sec = currentTime / 1000000LL; - cs->timer.timeout.tv_usec = currentTime % 1000000LL; - - return; - } - - LOGP(DCS, LOGL_DEBUG, "Starting loss CS timer with %d seconds.\n", sec); - bsc_schedule_timer(&cs->timer, sec, micro); -} - /* stop cell selection timer */ static void stop_cs_timer(struct gsm322_cellsel *cs) { @@ -2465,6 +2444,10 @@ static int gsm322_l1_signal(unsigned int subsys, unsigned int signal, || cs->state == GSM322_HPLMN_SEARCH) start_cs_timer(cs, ms->support.scan_to, 0); // TODO: timer depends on BCCH config + + /* set downlink signalling failure criterion */ + ms->meas.ds_fail = ms->meas.dsc = ms->settings.dsc_max; + LOGP(DRR, LOGL_INFO, "using DSC of %d\n", ms->meas.dsc); } break; case S_L1CTL_FBSB_ERR: @@ -2488,6 +2471,11 @@ static int gsm322_l1_signal(unsigned int subsys, unsigned int signal, else gsm322_cs_timeout(cs); break; + case S_L1CTL_LOSS_IND: + ms = signal_data; + cs = &ms->cellsel; + gsm322_cs_loss(cs); + break; case S_L1CTL_RESET: ms = signal_data; if (ms->mmlayer.power_off_idle) { diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 53cb3b34..86630c3c 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -413,6 +413,7 @@ static void new_rr_state(struct gsm48_rrlayer *rr, int state) /* release dedicated mode, if any */ l1ctl_tx_dm_rel_req(rr->ms); + rr->ms->meas.rl_fail = 0; rr->dm_est = 0; l1ctl_tx_reset_req(rr->ms, L1CTL_RES_T_FULL); /* free establish message, if any */ @@ -644,7 +645,7 @@ static void timeout_rr_meas(void *arg) if (rr->dm_est) gsm48_rr_tx_meas_rep(rr->ms); - memset(meas, 0, sizeof(*meas)); + meas->frames = meas->snr = meas->berr = meas->rxlev = 0; start_rr_t_meas(rr, 1, 0); } @@ -2266,6 +2267,7 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg) /* NOTE: pseudo length is not in this structure, so we skip */ struct gsm48_system_information_type_6 *si = msgb_l3(msg) + 1; struct gsm48_sysinfo *s = ms->cellsel.si; + struct rx_meas_stat *meas = &ms->meas; int payload_len = msgb_l3len(msg) - sizeof(*si) - 1; if (!s) { @@ -2303,6 +2305,8 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg) "lac 0x%04x SACCH-timeout %d)\n", gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac, s->sacch_radio_link_timeout); + meas->rl_fail = meas->s = s->sacch_radio_link_timeout; + LOGP(DRR, LOGL_INFO, "using (new) SACCH timeout %d\n", meas->rl_fail); s->si6 = 1; return gsm48_new_sysinfo(ms, si->system_information); @@ -3148,6 +3152,7 @@ static int gsm48_rr_activate_channel(struct osmocom_ms *ms, struct gsm48_sysinfo *s = ms->cellsel.si; struct rx_meas_stat *meas = &ms->meas; uint8_t ch_type, ch_subch, ch_ts; + uint8_t timeout = 64; /* setting (new) timing advance */ LOGP(DRR, LOGL_INFO, "setting indicated TA %d (actual TA %d)\n", @@ -3155,13 +3160,29 @@ static int gsm48_rr_activate_channel(struct osmocom_ms *ms, l1ctl_tx_param_req(ms, cd->ind_ta - set->alter_delay, (set->alter_tx_power) ? set->alter_tx_power_value : cd->ind_tx_power); + + /* reset measurement and link timeout */ + meas->ds_fail = 0; + if (s) { + if (s->sacch_radio_link_timeout) { + timeout = s->sacch_radio_link_timeout; + LOGP(DRR, LOGL_INFO, "using last SACCH timeout %d\n", + timeout); + } else if (s->bcch_radio_link_timeout) { + timeout = s->bcch_radio_link_timeout; + LOGP(DRR, LOGL_INFO, "using last BCCH timeout %d\n", + timeout); + } + } + meas->rl_fail = meas->s = timeout; + /* setting initial (invalid) measurement report, resetting SI5* */ if (s) { memset(s->si5_msg, 0, sizeof(s->si5_msg)); memset(s->si5b_msg, 0, sizeof(s->si5b_msg)); memset(s->si5t_msg, 0, sizeof(s->si5t_msg)); - memset(meas, 0, sizeof(*meas)); } + meas->frames = meas->snr = meas->berr = meas->rxlev = 0; rr->meas.nc_num = 0; stop_rr_t_meas(rr); start_rr_t_meas(rr, 1, 0); @@ -4533,6 +4554,7 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg) LOGP(DRR, LOGL_INFO, "suspension coplete, leaving dedicated " "mode\n"); l1ctl_tx_dm_rel_req(ms); + ms->meas.rl_fail = 0; rr->dm_est = 0; l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED); @@ -4891,7 +4913,6 @@ static int gsm48_rr_rx_acch(struct osmocom_ms *ms, struct msgb *msg) /* unit data from layer 2 to RR layer */ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm48_rrlayer *rr = &ms->rrlayer; struct gsm322_cellsel *cs = &ms->cellsel; struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); struct tlv_parsed tv; @@ -4911,21 +4932,6 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) && cs->ccch_state != GSM322_CCCH_ST_DATA) return -EINVAL; - /* when camping, start/reset loss timer */ - if (cs->state == GSM322_C3_CAMPED_NORMALLY - || cs->state == GSM322_C7_CAMPED_ANY_CELL) { - struct gsm48_sysinfo *s = &ms->cellsel.sel_si; -#ifdef TODO - set radio link timeout on layer 1 - it is the number of subsequent BCCH blocks. (about 1/4 seconds) -#else - /* use maximu loss timer, if to value is not available yet */ - start_loss_timer(cs, ((rr->state == GSM48_RR_ST_DEDICATED) - ? ((s->sacch_radio_link_timeout) ? : 64) - : s->bcch_radio_link_timeout) / 4, 0); -#endif - } - /* temporary moved here until confirm is fixed */ if (cs->ccch_state != GSM322_CCCH_ST_DATA) { LOGP(DCS, LOGL_INFO, "Channel provides data.\n"); @@ -5062,6 +5068,7 @@ static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg) /* deactivate channel */ l1ctl_tx_dm_rel_req(ms); + ms->meas.rl_fail = 0; rr->dm_est = 0; l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED); diff --git a/src/host/layer23/src/mobile/settings.c b/src/host/layer23/src/mobile/settings.c index cbef280b..37e0dd84 100644 --- a/src/host/layer23/src/mobile/settings.c +++ b/src/host/layer23/src/mobile/settings.c @@ -63,6 +63,7 @@ int gsm_settings_init(struct osmocom_ms *ms) set->half_v3 = sup->half_v3; set->ch_cap = sup->ch_cap; set->min_rxlev_db = sup->min_rxlev_db; + set->dsc_max = sup->dsc_max; if (sup->half_v1 || sup->half_v3) set->half = 1; diff --git a/src/host/layer23/src/mobile/support.c b/src/host/layer23/src/mobile/support.c index beadc783..34952dc2 100644 --- a/src/host/layer23/src/mobile/support.c +++ b/src/host/layer23/src/mobile/support.c @@ -101,6 +101,7 @@ void gsm_support_init(struct osmocom_ms *ms) sup->min_rxlev_db = -100; // TODO sup->sync_to = 6; /* how long to wait sync (0.9 s) */ sup->scan_to = 4; /* how long to wait for all sysinfos (>=4 s) */ + sup->dsc_max = 90; /* the specs defines 90 */ /* codec */ sup->full_v1 = 1; diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index af994b42..e3d34fe0 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -916,6 +916,7 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms) SUP_WRITE(half_v1, "half-speech-v1"); SUP_WRITE(half_v3, "half-speech-v3"); vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE); + vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE); vty_out(vty, " exit%s", VTY_NEWLINE); vty_out(vty, " test-sim%s", VTY_NEWLINE); vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE); @@ -1528,6 +1529,20 @@ DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>", return CMD_SUCCESS; } +DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>", + "Set the maximum DSC value. Standard is 90. Increase to make mobile " + "more reliable against bad RX signal. This increase the propability " + "of missing a paging requests\n" + "DSC initial and maximum value (standard is 90)") +{ + struct osmocom_ms *ms = vty->index; + struct gsm_settings *set = &ms->settings; + + set->dsc_max = atoi(argv[0]); + + return CMD_SUCCESS; +} + /* per testsim config */ DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim", "Configure test SIM emulation") @@ -1867,6 +1882,7 @@ int ms_vty_init(void) install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd); install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd); install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd); + install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd); install_node(&testsim_node, config_write_dummy); install_default(TESTSIM_NODE); install_element(TESTSIM_NODE, &ournode_exit_cmd); |