diff options
Diffstat (limited to 'src/host/layer23/src/mobile/gsm48_rr.c')
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_rr.c | 319 |
1 files changed, 239 insertions, 80 deletions
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 24360274..333b379b 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -79,12 +79,13 @@ #include <osmocom/bb/common/l1ctl.h> #include <osmocom/bb/mobile/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 void start_rr_t_meas(struct gsm48_rrlayer *rr, int sec, int micro); +static void stop_rr_t_meas(struct gsm48_rrlayer *rr); static void stop_rr_t_starting(struct gsm48_rrlayer *rr); static void stop_rr_t3124(struct gsm48_rrlayer *rr); 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_tx_meas_rep(struct osmocom_ms *ms); /* * support @@ -322,6 +323,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->dm_est = 0; l1ctl_tx_reset_req(rr->ms, L1CTL_RES_T_FULL); /* free establish message, if any */ rr->rr_est_req = 0; @@ -495,8 +497,6 @@ int gsm48_rsl_dequeue(struct osmocom_ms *ms) 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; } @@ -504,8 +504,6 @@ int gsm48_rr_start_monitor(struct osmocom_ms *ms) 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; } @@ -515,7 +513,7 @@ int gsm48_rr_stop_monitor(struct osmocom_ms *ms) */ /* special timer to monitor measurements */ -static void timeout_rr_monitor(void *arg) +static void timeout_rr_meas(void *arg) { struct gsm48_rrlayer *rr = arg; struct gsm322_cellsel *cs = &rr->ms->cellsel; @@ -526,7 +524,7 @@ static void timeout_rr_monitor(void *arg) char text[256]; if (!cs->selected) { - sprintf(text, "MON: no cell selected"); + return; } else if (!meas->frames) { sprintf(text, "MON: no cell info"); } else { @@ -550,10 +548,14 @@ static void timeout_rr_monitor(void *arg) sprintf(text + strlen(text), "/%d", ch_subch); } } - vty_notify(rr->ms, "%s\n", text); + LOGP(DRR, LOGL_INFO, "%s\n", text); + if (rr->monitor) + vty_notify(rr->ms, "%s\n", text); + if (rr->dm_est) + gsm48_rr_tx_meas_rep(rr->ms); memset(meas, 0, sizeof(*meas)); - start_rr_t_monitor(rr, 1, 0); + start_rr_t_meas(rr, 1, 0); } /* special timer to assign / handover when starting time is reached */ @@ -645,11 +647,11 @@ static void timeout_rr_t3126(void *arg) new_rr_state(rr, GSM48_RR_ST_IDLE); } -static void start_rr_t_monitor(struct gsm48_rrlayer *rr, int sec, int micro) +static void start_rr_t_meas(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); + rr->t_meas.cb = timeout_rr_meas; + rr->t_meas.data = rr; + bsc_schedule_timer(&rr->t_meas, sec, micro); } static void start_rr_t_rel_wait(struct gsm48_rrlayer *rr, int sec, int micro) @@ -706,11 +708,11 @@ static void start_rr_t3126(struct gsm48_rrlayer *rr, int sec, int micro) bsc_schedule_timer(&rr->t3126, sec, micro); } -static void stop_rr_t_monitor(struct gsm48_rrlayer *rr) +static void stop_rr_t_meas(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); + if (bsc_timer_pending(&rr->t_meas)) { + LOGP(DRR, LOGL_INFO, "stopping pending timer T_meas\n"); + bsc_del_timer(&rr->t_meas); } } @@ -1704,11 +1706,46 @@ static int gsm48_decode_si6_rest(struct gsm48_sysinfo *s, uint8_t *si, } /* send sysinfo event to other layers */ -static int gsm48_send_sysinfo(struct osmocom_ms *ms, uint8_t type) +static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type) { + struct gsm48_sysinfo *s = ms->cellsel.si; struct msgb *nmsg; struct gsm322_msg *em; + /* update list of measurements, if BA(SACCH) is complete and new */ + if (s + && (type == GSM48_MT_RR_SYSINFO_5 + || type == GSM48_MT_RR_SYSINFO_5bis + || type == GSM48_MT_RR_SYSINFO_5ter) + && s->si5 + && (!s->nb_ext_ind_si5 + || (s->si5bis && s->nb_ext_ind_si5 && !s->nb_ext_ind_si5bis) + || (s->si5bis && s->si5ter && s->nb_ext_ind_si5 + && s->nb_ext_ind_si5bis))) { + struct gsm48_rr_meas *rrmeas = &ms->rrlayer.meas; + int n = 0, i; + + LOGP(DRR, LOGL_NOTICE, "Complete set of SI5* for BA(%d)\n", + s->nb_ba_ind_si5); + rrmeas->nc_num = 0; + for (i = 1; i <= 1024; i++) { + if ((s->freq[i & 1023].mask & FREQ_TYPE_REP)) { + if (n == 32) { + LOGP(DRR, LOGL_NOTICE, "SI5* report " + "exceeds 32 BCCHs\n"); + break; + } + LOGP(DRR, LOGL_NOTICE, "SI5* report arfcn %d\n", + i & 1023); + rrmeas->nc_arfcn[n] = i & 1023; + rrmeas->nc_rxlev[n] = -128; + n++; + } + } + rrmeas->nc_num = n; + } + + /* send sysinfo event to other layers */ nmsg = gsm322_msgb_alloc(GSM322_EVENT_SYSINFO); if (!nmsg) return -ENOMEM; @@ -1762,7 +1799,7 @@ static int gsm48_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg) s->si1 = 1; - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 2" message (9.1.32) */ @@ -1797,13 +1834,13 @@ static int gsm48_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg) decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list, sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2); /* NCC Permitted */ - s->nb_ncc_permitted = si->ncc_permitted; + s->nb_ncc_permitted_si2 = si->ncc_permitted; /* RACH Control Parameter */ gsm48_decode_rach_ctl_neigh(s, &si->rach_control); s->si2 = 1; - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 2bis" message (9.1.33) */ @@ -1837,14 +1874,13 @@ static int gsm48_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg) s->nb_ba_ind_si2bis = (si->bcch_frequency_list[0] >> 5) & 1; decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list, - sizeof(si->bcch_frequency_list), 0x8e, - FREQ_TYPE_NCELL_2bis); + sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2bis); /* RACH Control Parameter */ gsm48_decode_rach_ctl_neigh(s, &si->rach_control); s->si2bis = 1; - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 2ter" message (9.1.34) */ @@ -1875,14 +1911,15 @@ static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg) /* Neighbor Cell Description 2 */ s->nb_multi_rep_si2ter = (si->ext_bcch_frequency_list[0] >> 6) & 3; + s->nb_ba_ind_si2ter = (si->ext_bcch_frequency_list[0] >> 5) & 1; decode_freq_list(&ms->support, s->freq, si->ext_bcch_frequency_list, sizeof(si->ext_bcch_frequency_list), 0x8e, - FREQ_TYPE_NCELL_2ter); + FREQ_TYPE_NCELL_2ter); s->si2ter = 1; - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 3" message (9.1.35) */ @@ -1939,7 +1976,7 @@ static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg) l1ctl_tx_ccch_mode_req(ms, cs->ccch_mode); } - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 4" message (9.1.36) */ @@ -2015,7 +2052,7 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg) s->si4 = 1; - return gsm48_send_sysinfo(ms, si->header.system_information); + return gsm48_new_sysinfo(ms, si->header.system_information); } /* receive "SYSTEM INFORMATION 5" message (9.1.37) */ @@ -2052,7 +2089,7 @@ static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg) s->si5 = 1; - return gsm48_send_sysinfo(ms, si->system_information); + return gsm48_new_sysinfo(ms, si->system_information); } /* receive "SYSTEM INFORMATION 5bis" message (9.1.38) */ @@ -2090,7 +2127,7 @@ static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg) s->si5bis = 1; - return gsm48_send_sysinfo(ms, si->system_information); + return gsm48_new_sysinfo(ms, si->system_information); } /* receive "SYSTEM INFORMATION 5ter" message (9.1.39) */ @@ -2121,12 +2158,14 @@ static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg) memcpy(s->si5t_msg, si, MIN(msgb_l3len(msg), sizeof(s->si5t_msg))); /* Neighbor Cell Description */ + s->nb_multi_rep_si5ter = (si->bcch_frequency_list[0] >> 6) & 3; + s->nb_ba_ind_si5ter = (si->bcch_frequency_list[0] >> 5) & 1; decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list, - sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_REP_5ter); + sizeof(si->bcch_frequency_list), 0x8e, FREQ_TYPE_REP_5ter); s->si5ter = 1; - return gsm48_send_sysinfo(ms, si->system_information); + return gsm48_new_sysinfo(ms, si->system_information); } /* receive "SYSTEM INFORMATION 6" message (9.1.39) */ @@ -2163,7 +2202,7 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg) /* Cell Options (SACCH) */ gsm48_decode_cellopt_sacch(s, &si->cell_options); /* NCC Permitted */ - s->nb_ncc_permitted = si->ncc_permitted; + s->nb_ncc_permitted_si6 = si->ncc_permitted; /* SI 6 Rest Octets */ if (payload_len >= 4) gsm48_decode_si6_rest(s, si->rest_octets, payload_len); @@ -2174,7 +2213,7 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg) s->si6 = 1; - return gsm48_send_sysinfo(ms, si->system_information); + return gsm48_new_sysinfo(ms, si->system_information); } /* @@ -2484,6 +2523,7 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg) #endif memset(&cd, 0, sizeof(cd)); + cd.ind_tx_power = rr->cd_now.ind_tx_power; if (ma_len < 0 /* mobile allocation IE must be included */ || ia->mob_alloc_len > ma_len) { /* short read of IE */ @@ -2579,7 +2619,9 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg) #endif memset(&cd1, 0, sizeof(cd1)); + cd1.ind_tx_power = rr->cd_now.ind_tx_power; memset(&cd2, 0, sizeof(cd2)); + cd2.ind_tx_power = rr->cd_now.ind_tx_power; if (ma_len < 0 /* mobile allocation IE must be included */ || ia->mob_alloc_len > ma_len) { /* short read of IE */ @@ -2780,14 +2822,91 @@ static int gsm48_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg) static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms) { struct gsm48_rrlayer *rr = &ms->rrlayer; - struct gsm48_rr_meas *meas = &rr->meas; + struct gsm48_sysinfo *s = ms->cellsel.si; + struct rx_meas_stat *meas = &rr->ms->meas; + struct gsm48_rr_meas *rrmeas = &rr->meas; struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_meas_res *mr; + uint8_t serv_rxlev_full = 0, serv_rxlev_sub = 0, serv_rxqual_full = 0, + serv_rxqual_sub = 0; + uint8_t ta, tx_power; + uint8_t rep_ba = 0, rep_valid = 0, meas_valid = 0, multi_rep = 0; + uint8_t n = 0, rxlev_nc[6], bsic_nc[6], bcch_f_nc[6]; + + /* just in case! */ + if (!s) + return -EINVAL; + + /* check if SI5* is completely received, check BA-IND */ + if (s->si5 + && (!s->nb_ext_ind_si5 + || (s->si5bis && s->nb_ext_ind_si5 && !s->nb_ext_ind_si5bis) + || (s->si5bis && s->si5ter && s->nb_ext_ind_si5 + && s->nb_ext_ind_si5bis))) { + rep_ba = s->nb_ba_ind_si5; + if ((s->si5bis && s->nb_ext_ind_si5 + && s->nb_ba_ind_si5bis != rep_ba) + || (s->si5bis && s->si5ter && s->nb_ext_ind_si5 + && s->nb_ext_ind_si5bis && s->nb_ba_ind_si5ter != rep_ba)) { + LOGP(DRR, LOGL_NOTICE, "BA-IND missmatch on SI5*"); + } else + rep_valid = 1; + } + + /* check for valid measurements, any frame must exist */ + if (meas->frames) { + meas_valid = 1; + serv_rxlev_full = serv_rxlev_sub = meas->rxlev / meas->frames; + serv_rxqual_full = serv_rxqual_sub = 0; // FIXME + } + + memset(&rxlev_nc, 0, sizeof(rxlev_nc)); + memset(&bsic_nc, 0, sizeof(bsic_nc)); + memset(&bcch_f_nc, 0, sizeof(bcch_f_nc)); + if (rep_valid) { + int8_t strongest, current; + uint8_t ncc; + int i, index; + + /* multiband reporting, if not: 0 = normal reporting */ + if (s->si5 && s->si5bis && s->si5ter && s->nb_ext_ind_si5 + && s->nb_ext_ind_si5bis) + multi_rep = s->nb_multi_rep_si5ter; + + /* get 6 strongest measurements */ + // FIXME: multiband report + strongest = 127; /* infinite */ + for (n = 0; n < 6; n++) { + current = -128; /* -infinite */ + index = 0; + for (i = 0; i < rrmeas->nc_num; i++) { + /* only check if NCC is permitted */ + ncc = rrmeas->nc_bsic[i] >> 3; + if ((s->nb_ncc_permitted_si6 & (1 << ncc)) + && rrmeas->nc_rxlev[i] > current + && rrmeas->nc_rxlev[i] < strongest) { + current = rrmeas->nc_rxlev[i]; + index = i; + } + } + if (current == -128) /* no more found */ + break; + rxlev_nc[n] = rrmeas->nc_rxlev[index] + 110; + bsic_nc[n] = rrmeas->nc_bsic[index]; + bcch_f_nc[n] = index; + } + } nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; + + /* use indicated tx-power and TA (not the altered ones) */ + tx_power = rr->cd_now.ind_tx_power; + // FIXME: degrade power to the max supported level + ta = rr->cd_now.ind_ta; + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); mr = (struct gsm48_meas_res *) msgb_put(nmsg, sizeof(*mr)); @@ -2795,51 +2914,68 @@ static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms) gh->msg_type = GSM48_MT_RR_MEAS_REP; /* measurement results */ - mr->rxlev_full = meas->rxlev_full; - mr->rxlev_sub = meas->rxlev_sub; - mr->rxqual_full = meas->rxqual_full; - mr->rxqual_sub = meas->rxqual_sub; - mr->dtx_used = meas->dtx; - mr->ba_used = meas->ba; - mr->meas_valid = meas->meas_valid; - if (meas->ncell_na) { + mr->rxlev_full = serv_rxlev_full; + mr->rxlev_sub = serv_rxlev_sub; + mr->rxqual_full = serv_rxqual_full; + mr->rxqual_sub = serv_rxqual_sub; + mr->dtx_used = 0; // FIXME: no DTX yet + mr->ba_used = rep_ba; + mr->meas_valid = !meas_valid; /* 0 = valid */ + if (rep_valid) { + mr->no_nc_n_hi = n >> 2; + mr->no_nc_n_lo = n & 3; + } else { /* no results for serving cells */ mr->no_nc_n_hi = 1; mr->no_nc_n_lo = 3; - } else { - mr->no_nc_n_hi = meas->count >> 2; - mr->no_nc_n_lo = meas->count & 3; - } - mr->rxlev_nc1 = meas->rxlev_nc[0]; - mr->rxlev_nc2_hi = meas->rxlev_nc[1] >> 1; - mr->rxlev_nc2_lo = meas->rxlev_nc[1] & 1; - mr->rxlev_nc3_hi = meas->rxlev_nc[2] >> 2; - mr->rxlev_nc3_lo = meas->rxlev_nc[2] & 3; - mr->rxlev_nc4_hi = meas->rxlev_nc[3] >> 3; - mr->rxlev_nc4_lo = meas->rxlev_nc[3] & 7; - mr->rxlev_nc5_hi = meas->rxlev_nc[4] >> 4; - mr->rxlev_nc5_lo = meas->rxlev_nc[4] & 15; - mr->rxlev_nc6_hi = meas->rxlev_nc[5] >> 5; - mr->rxlev_nc6_lo = meas->rxlev_nc[5] & 31; - mr->bsic_nc1_hi = meas->bsic_nc[0] >> 3; - mr->bsic_nc1_lo = meas->bsic_nc[0] & 7; - mr->bsic_nc2_hi = meas->bsic_nc[1] >> 4; - mr->bsic_nc2_lo = meas->bsic_nc[1] & 15; - mr->bsic_nc3_hi = meas->bsic_nc[2] >> 5; - mr->bsic_nc3_lo = meas->bsic_nc[2] & 31; - mr->bsic_nc4 = meas->bsic_nc[3]; - mr->bsic_nc5 = meas->bsic_nc[4]; - mr->bsic_nc6 = meas->bsic_nc[5]; - mr->bcch_f_nc1 = meas->bcch_f_nc[0]; - mr->bcch_f_nc2 = meas->bcch_f_nc[1]; - mr->bcch_f_nc3 = meas->bcch_f_nc[2]; - mr->bcch_f_nc4 = meas->bcch_f_nc[3]; - mr->bcch_f_nc5_hi = meas->bcch_f_nc[4] >> 1; - mr->bcch_f_nc5_lo = meas->bcch_f_nc[4] & 1; - mr->bcch_f_nc6_hi = meas->bcch_f_nc[5] >> 2; - mr->bcch_f_nc6_lo = meas->bcch_f_nc[5] & 3; - - return gsm48_send_rsl(ms, RSL_MT_UNIT_DATA_REQ, nmsg); + } + mr->rxlev_nc1 = rxlev_nc[0]; + mr->rxlev_nc2_hi = rxlev_nc[1] >> 1; + mr->rxlev_nc2_lo = rxlev_nc[1] & 1; + mr->rxlev_nc3_hi = rxlev_nc[2] >> 2; + mr->rxlev_nc3_lo = rxlev_nc[2] & 3; + mr->rxlev_nc4_hi = rxlev_nc[3] >> 3; + mr->rxlev_nc4_lo = rxlev_nc[3] & 7; + mr->rxlev_nc5_hi = rxlev_nc[4] >> 4; + mr->rxlev_nc5_lo = rxlev_nc[4] & 15; + mr->rxlev_nc6_hi = rxlev_nc[5] >> 5; + mr->rxlev_nc6_lo = rxlev_nc[5] & 31; + mr->bsic_nc1_hi = bsic_nc[0] >> 3; + mr->bsic_nc1_lo = bsic_nc[0] & 7; + mr->bsic_nc2_hi = bsic_nc[1] >> 4; + mr->bsic_nc2_lo = bsic_nc[1] & 15; + mr->bsic_nc3_hi = bsic_nc[2] >> 5; + mr->bsic_nc3_lo = bsic_nc[2] & 31; + mr->bsic_nc4 = bsic_nc[3]; + mr->bsic_nc5 = bsic_nc[4]; + mr->bsic_nc6 = bsic_nc[5]; + mr->bcch_f_nc1 = bcch_f_nc[0]; + mr->bcch_f_nc2 = bcch_f_nc[1]; + mr->bcch_f_nc3 = bcch_f_nc[2]; + mr->bcch_f_nc4 = bcch_f_nc[3]; + mr->bcch_f_nc5_hi = bcch_f_nc[4] >> 1; + mr->bcch_f_nc5_lo = bcch_f_nc[4] & 1; + mr->bcch_f_nc6_hi = bcch_f_nc[5] >> 2; + mr->bcch_f_nc6_lo = bcch_f_nc[5] & 3; + + LOGP(DRR, LOGL_INFO, "MEAS REP: pwr=%d TA=%d meas-invalid=%d " + "rxlev-full=%d rxlev-sub=%d rxqual-full=%d rxqual-sub=%d " + "dtx %d ba %d no-ncell-n %d\n", tx_power, ta, mr->meas_valid, + mr->rxlev_full - 110, mr->rxlev_sub - 110, + mr->rxqual_full, mr->rxqual_sub, mr->dtx_used, mr->ba_used, + (mr->no_nc_n_hi << 2) | mr->no_nc_n_lo); + + msgb_tv16_push(nmsg, RSL_IE_L3_INFO, + nmsg->tail - (uint8_t *)msgb_l3(nmsg)); + msgb_push(nmsg, 2 + 2); + nmsg->data[0] = RSL_IE_ACCESS_DELAY; + nmsg->data[1] = ta; + nmsg->data[2] = RSL_IE_MS_POWER; + nmsg->data[3] = tx_power; + rsl_rll_push_hdr(nmsg, RSL_MT_UNIT_DATA_REQ, rr->cd_now.chan_nr, + 0x40, 1); + + return rslms_recvmsg(nmsg, ms); } /* @@ -2917,6 +3053,8 @@ static int gsm48_rr_activate_channel(struct osmocom_ms *ms, struct gsm_subscriber *subscr = &ms->subscr; struct gsm48_rrlayer *rr = &ms->rrlayer; struct gsm_settings *set = &ms->settings; + struct gsm48_sysinfo *s = ms->cellsel.si; + struct rx_meas_stat *meas = &ms->meas; uint8_t ch_type, ch_subch, ch_ts; /* setting (new) timing advance */ @@ -2925,6 +3063,17 @@ 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); + /* 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)); + } + rr->meas.nc_num = 0; + stop_rr_t_meas(rr); + start_rr_t_meas(rr, 1, 0); + gsm48_rr_tx_meas_rep(ms); /* establish */ LOGP(DRR, LOGL_INFO, "establishing channel in dedicated mode\n"); @@ -2940,6 +3089,7 @@ static int gsm48_rr_activate_channel(struct osmocom_ms *ms, ma, ma_len, cd->chan_nr, cd->tsc); else l1ctl_tx_dm_est_req_h0(ms, cd->arfcn, cd->chan_nr, cd->tsc); + rr->dm_est = 1; if (rr->cipher_on) l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8); @@ -3556,7 +3706,9 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg) LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMMAND\n"); memset(cda, 0, sizeof(*cda)); + cda->ind_tx_power = rr->cd_now.ind_tx_power; memset(cdb, 0, sizeof(*cdb)); + cdb->ind_tx_power = rr->cd_now.ind_tx_power; if (payload_len < 0) { LOGP(DRR, LOGL_NOTICE, "Short read of ASSIGNMENT COMMAND " @@ -3909,7 +4061,9 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg) LOGP(DRR, LOGL_INFO, "HANDOVER COMMAND\n"); memset(cda, 0, sizeof(*cda)); + cda->ind_tx_power = rr->cd_now.ind_tx_power; memset(cdb, 0, sizeof(*cdb)); + cdb->ind_tx_power = rr->cd_now.ind_tx_power; if (payload_len < 0) { LOGP(DRR, LOGL_NOTICE, "Short read of HANDOVER COMMAND " @@ -4264,6 +4418,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); + rr->dm_est = 0; l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED); /* store current channel descriptions */ @@ -4791,6 +4946,7 @@ static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg) /* deactivate channel */ l1ctl_tx_dm_rel_req(ms); + rr->dm_est = 0; l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED); switch (rr->modify_state) { @@ -5041,6 +5197,8 @@ int gsm48_rr_init(struct osmocom_ms *ms) osmol2_register_handler(ms, &gsm48_rx_rsl); + start_rr_t_meas(rr, 1, 0); + return 0; } @@ -5062,7 +5220,7 @@ int gsm48_rr_exit(struct osmocom_ms *ms) rr->rr_est_msg = NULL; } - stop_rr_t_monitor(rr); + stop_rr_t_meas(rr); stop_rr_t_starting(rr); stop_rr_t_rel_wait(rr); stop_rr_t3110(rr); @@ -5092,6 +5250,7 @@ static void timeout_rr_t3124(void *arg) /* change radio to old channel */ tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr, rr->cd_now.tsc); + rr->dm_est = 1; /* re-establish old link */ nmsg = gsm48_l3_msgb_alloc(); @@ -5138,6 +5297,7 @@ static int gsm48_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *m start_rr_t3124(rr, GSM_T3124_675); else start_rr_t3124(rr, GSM_T3124_320); + } if (!rr->n_chan_req) { start_rr_t3126(rr, 5, 0); /* TODO improve! */ return 0; @@ -5151,4 +5311,3 @@ static int gsm48_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *m #endif - |