introduce cache of 6 last recently received measurement reports for each lchan

This commit is contained in:
Harald Welte 2009-12-15 21:36:05 +01:00
parent 0b12103965
commit d12b0fdf51
5 changed files with 47 additions and 21 deletions

View File

@ -194,6 +194,10 @@ struct gsm_lchan {
/* use count. how many users use this channel */
unsigned int use_count;
/* cache of last measurement reports on this lchan */
struct gsm_meas_rep meas_rep[6];
int meas_rep_idx;
struct {
u_int32_t bound_ip;
u_int16_t bound_port;
@ -564,4 +568,6 @@ const char *rrlp_mode_name(enum rrlp_mode mode);
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
#endif

View File

@ -998,14 +998,12 @@ static int rsl_rx_meas_res(struct msgb *msg)
{
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tp;
struct gsm_meas_rep mr;
struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
u_int8_t len;
const u_int8_t *val;
int rc;
memset(&mr, 0, sizeof(mr));
mr.lchan = msg->lchan;
memset(mr, 0, sizeof(*mr));
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
@ -1015,44 +1013,44 @@ static int rsl_rx_meas_res(struct msgb *msg)
return -EIO;
/* Mandatory Parts */
mr.nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
if (len >= 3) {
if (val[0] & 0x40)
mr.flags |= MEAS_REP_F_DL_DTX;
mr.ul.full.rx_lev = val[0] & 0x3f;
mr.ul.sub.rx_lev = val[1] & 0x3f;
mr.ul.full.rx_qual = val[2]>>3 & 0x7;
mr.ul.sub.rx_qual = val[2] & 0x7;
mr->flags |= MEAS_REP_F_DL_DTX;
mr->ul.full.rx_lev = val[0] & 0x3f;
mr->ul.sub.rx_lev = val[1] & 0x3f;
mr->ul.full.rx_qual = val[2]>>3 & 0x7;
mr->ul.sub.rx_qual = val[2] & 0x7;
}
mr.bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
/* Optional Parts */
if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
mr.ms_timing_offset =
mr->ms_timing_offset =
*TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
mr.flags |= MEAS_REP_F_MS_L1;
mr.ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
mr->flags |= MEAS_REP_F_MS_L1;
mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
if (val[0] & 0x04)
mr.flags |= MEAS_REP_F_FPC;
mr.ms_l1.ta = val[1];
mr->flags |= MEAS_REP_F_FPC;
mr->ms_l1.ta = val[1];
}
if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
rc = gsm48_parse_meas_rep(&mr, msg);
rc = gsm48_parse_meas_rep(mr, msg);
if (rc < 0)
return rc;
}
print_meas_rep(&mr);
print_meas_rep(mr);
dispatch_signal(SS_LCHAN, S_LCHAN_MEAS_REP, &mr);
dispatch_signal(SS_LCHAN, S_LCHAN_MEAS_REP, mr);
return 0;
}

View File

@ -235,6 +235,8 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
/* Free a logical channel */
void lchan_free(struct gsm_lchan *lchan)
{
int i;
lchan->type = GSM_LCHAN_NONE;
if (lchan->subscr) {
subscr_put(lchan->subscr);
@ -250,6 +252,13 @@ void lchan_free(struct gsm_lchan *lchan)
/* stop the timer */
bsc_del_timer(&lchan->release_timer);
/* clear cached measuement reports */
lchan->meas_rep_idx = 0;
for (i = 0; i < ARRAY_SIZE(lchan->meas_rep); i++) {
lchan->meas_rep[i].flags = 0;
lchan->meas_rep[i].nr = 0;
}
/* FIXME: ts_free() the timeslot, if we're the last logical
* channel using it */
}

View File

@ -1558,13 +1558,13 @@ static int gsm48_rx_rr_status(struct msgb *msg)
static int gsm48_rx_rr_meas_rep(struct msgb *msg)
{
static struct gsm_meas_rep meas_rep;
struct gsm_meas_rep *meas_rep = lchan_next_meas_rep(msg->lchan);
/* This shouldn't actually end up here, as RSL treats
* L3 Info of 08.58 MEASUREMENT REPORT different by calling
* directly into gsm48_parse_meas_rep */
DEBUGP(DMEAS, "DIRECT GSM48 MEASUREMENT REPORT ?!? ");
gsm48_parse_meas_rep(&meas_rep, msg);
gsm48_parse_meas_rep(meas_rep, msg);
return 0;
}

View File

@ -415,3 +415,16 @@ const char *rrlp_mode_name(enum rrlp_mode mode)
return "none";
return rrlp_mode_names[mode];
}
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
{
struct gsm_meas_rep *meas_rep;
meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
memset(meas_rep, 0, sizeof(*meas_rep));
meas_rep->lchan = lchan;
lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
% ARRAY_SIZE(lchan->meas_rep);
return meas_rep;
}