summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-12-15 18:32:32 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2014-02-26 12:16:56 +0100
commit3ecbc4e59b05dd3650a1f1e45b5f93407623da07 (patch)
treed1e6907bb3ab687cd002ea447ff13942a11b7689
parent9a30420933634345efa80da6187e7a730acf7024 (diff)
mobile: Use only sel_si for informations about the current cell
sel_si structure tracks content of SI5* and SI6 messages. The informations will change after handover, so they do not refer to the origin cell. The list of scanned cells is not affected. The sel_si structure will be overwritten with the selected cell after leaving dedicated mode.
-rw-r--r--src/host/layer23/src/common/sysinfo.c2
-rw-r--r--src/host/layer23/src/mobile/gsm322.c19
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c84
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c7
4 files changed, 68 insertions, 44 deletions
diff --git a/src/host/layer23/src/common/sysinfo.c b/src/host/layer23/src/common/sysinfo.c
index b42bd653..ad73c8db 100644
--- a/src/host/layer23/src/common/sysinfo.c
+++ b/src/host/layer23/src/common/sysinfo.c
@@ -200,7 +200,7 @@ int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
sprintf(buffer + 69, " %d", i + 63);
print(priv, "%s\n", buffer);
}
- print(priv, " 'S' = serv. cell 'n' = SI2 (neigh.) 'r' = SI5 (rep.) "
+ print(priv, " 'S' = serv. cell 'n' = SI2 (neigh.) 'r' = last SI5 (rep.) "
"'b' = SI2+SI5\n\n");
/* serving cell */
diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c
index 526e3537..4b1e1c38 100644
--- a/src/host/layer23/src/mobile/gsm322.c
+++ b/src/host/layer23/src/mobile/gsm322.c
@@ -504,8 +504,6 @@ static void gsm322_unselect_cell(struct gsm322_cellsel *cs)
LOGP(DCS, LOGL_INFO, "Unselecting serving cell.\n");
cs->selected = 0;
- if (cs->si)
- cs->si->si5 = 0; /* unset SI5* */
cs->si = NULL;
memset(&cs->sel_si, 0, sizeof(cs->sel_si));
cs->sel_mcc = cs->sel_mnc = cs->sel_lac = cs->sel_id = 0;
@@ -4849,8 +4847,12 @@ int gsm322_dump_sorted_plmn(struct osmocom_ms *ms)
int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
void (*print)(void *, const char *, ...), void *priv)
{
- int i;
struct gsm48_sysinfo *s;
+ char arfcn_str[9];
+ int i, arfci = -1;
+
+ if (cs->selected)
+ arfci = arfcn2index(cs->sel_arfcn);
print(priv, "ARFCN |MCC |MNC |LAC |cell ID|forb.LA|prio |"
"min-db |max-pwr|rx-lev\n");
@@ -4861,11 +4863,14 @@ int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
if (!s || !(cs->list[i].flags & flags))
continue;
if (i >= 1024)
- print(priv, "%4dPCS|", i-1024+512);
+ sprintf(arfcn_str, "%4dPCS|", i-1024+512);
else if (i >= 512 && i <= 885)
- print(priv, "%4dDCS|", i);
+ sprintf(arfcn_str, "%4dDCS|", i);
else
- print(priv, "%4d |", i);
+ sprintf(arfcn_str, "%4d |", i);
+ if (i == arfci)
+ arfcn_str[6] = '*';
+ print(priv, arfcn_str);
if (s->mcc) {
print(priv, "%s |%s%s |", gsm_print_mcc(s->mcc),
gsm_print_mnc(s->mnc),
@@ -4896,6 +4901,8 @@ int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
print(priv, "n/a |n/a |n/a\n");
}
print(priv, "\n");
+ if (arfci >= 0)
+ print(priv, "* = Selected cell\n");
return 0;
}
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 0191f95c..fdc67226 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -1306,7 +1306,7 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging,
struct gsm_settings *set = &ms->settings;
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct msgb *nmsg;
struct gsm48_rr_hdr *nrrh;
uint8_t chan_req_val, chan_req_mask;
@@ -1676,22 +1676,22 @@ fail:
tx_power = set->alter_tx_power_value;
LOGP(DRR, LOGL_INFO, "Use alternative tx-power %d (%d dBm)\n",
tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power));
+ ms_pwr_dbm(gsm_arfcn2band(cs->sel_arfcn), tx_power));
} else {
tx_power = s->ms_txpwr_max_cch;
/* power offset in case of DCS1800 */
- if (s->po && (cs->arfcn & 1023) >= 512
- && (cs->arfcn & 1023) <= 885) {
+ if (s->po && (cs->sel_arfcn & 1023) >= 512
+ && (cs->sel_arfcn & 1023) <= 885) {
LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
"%d (%d dBm) with offset %d dBm\n", tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power),
- s->po_value * 2);
+ ms_pwr_dbm(gsm_arfcn2band(cs->sel_arfcn),
+ tx_power), s->po_value * 2);
/* use reserved bits 7,8 for offset (+ X * 2dB) */
tx_power |= s->po_value << 6;
} else
LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
"%d (%d dBm)\n", tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn),
+ ms_pwr_dbm(gsm_arfcn2band(cs->sel_arfcn),
tx_power));
}
ncch->data[7] = tx_power;
@@ -1713,14 +1713,14 @@ fail:
/* generate list from SI5 and send to L1 to start SB measurement */
static int gsm48_new_si5(struct osmocom_ms *ms)
{
- struct gsm48_sysinfo *s = ms->cellsel.si;
struct gsm322_cellsel *cs = &ms->cellsel;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm48_rr_meas *rrmeas = &rr->meas;
int n = 0, i, refer_pcs;
rrmeas->nc_num = 0;
- refer_pcs = gsm_refer_pcs(cs->arfcn, s);
+ refer_pcs = gsm_refer_pcs(cs->sel_arfcn, s);
/* collect channels from freq list (1..1023,0) */
for (i = 1; i <= 1024; i++) {
@@ -1803,13 +1803,13 @@ int gsm48_rr_meas_ind(struct osmocom_ms *ms, uint16_t band_arfcn,
/* send sysinfo event to other layers */
static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type)
{
- struct gsm48_sysinfo *s = ms->cellsel.si;
+ struct gsm322_cellsel *cs = &ms->cellsel;
+ struct gsm48_sysinfo *s = &cs->sel_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
+ if ((type == GSM48_MT_RR_SYSINFO_5
|| type == GSM48_MT_RR_SYSINFO_5bis
|| type == GSM48_MT_RR_SYSINFO_5ter)
&& s->si5
@@ -1819,6 +1819,14 @@ static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type)
gsm48_new_si5(ms);
}
+ /* update stuff from SI 6 */
+ if (type == GSM48_MT_RR_SYSINFO_6 && s->si6) {
+ cs->sel_mcc = s->mcc;
+ cs->sel_mnc = s->mnc;
+ cs->sel_lac = s->lac;
+ cs->sel_id = s->cell_id;
+ }
+
/* send sysinfo event to other layers */
nmsg = gsm322_msgb_alloc(GSM322_EVENT_SYSINFO);
if (!nmsg)
@@ -2031,7 +2039,8 @@ static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg)
{
/* NOTE: pseudo length is not in this structure, so we skip */
struct gsm48_system_information_type_5 *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
+ /* Note: Only store SI5* / SI6 in temporary sel_si */
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
if (!s) {
@@ -2061,7 +2070,8 @@ static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg)
{
/* NOTE: pseudo length is not in this structure, so we skip */
struct gsm48_system_information_type_5bis *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
+ /* Note: Only store SI5* / SI6 in temporary sel_si */
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
if (!s) {
@@ -2092,7 +2102,8 @@ static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg)
{
/* NOTE: pseudo length is not in this structure, so we skip */
struct gsm48_system_information_type_5ter *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
+ /* Note: Only store SI5* / SI6 in temporary sel_si */
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
if (!s) {
@@ -2123,7 +2134,8 @@ 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;
+ /* Note: Only store SI5* / SI6 in temporary sel_si */
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
struct rx_meas_stat *meas = &ms->meas;
int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
@@ -2466,7 +2478,7 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm48_imm_ass *ia = msgb_l3(msg);
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
int ma_len = msgb_l3len(msg) - sizeof(*ia);
uint8_t ch_type, ch_subch, ch_ts;
struct gsm48_rr_cd cd;
@@ -2526,7 +2538,7 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
} else {
cd.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc, &cd.tsc, &cd.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cd.arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " (ta %d/%dm ra 0x%02x chan_nr 0x%02x "
"ARFCN %s TS %u SS %u TSC %u)\n",
@@ -2573,7 +2585,7 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
int ma_len = msgb_l3len(msg) - sizeof(*ia);
uint8_t ch_type, ch_subch, ch_ts;
@@ -2640,7 +2652,7 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
} else {
cd1.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc1, &cd1.tsc, &cd1.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cd1.arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " assignment 1 (ta %d/%dm ra 0x%02x "
"chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
@@ -2664,7 +2676,7 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
} else {
cd2.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc2, &cd2.tsc, &cd2.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cd2.arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " assignment 2 (ta %d/%dm ra 0x%02x "
"chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
@@ -2798,7 +2810,7 @@ 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_sysinfo *s = ms->cellsel.si;
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
struct rx_meas_stat *meas = &rr->ms->meas;
struct gsm48_rr_meas *rrmeas = &rr->meas;
struct msgb *nmsg;
@@ -3062,8 +3074,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;
+ struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
+ struct rx_meas_stat *meas = &ms->meas;
uint8_t ch_type, ch_subch, ch_ts;
uint8_t timeout = 64;
int ta = cd->ind_ta;
@@ -3159,12 +3171,12 @@ static int gsm48_rr_render_ma(struct osmocom_ms *ms, struct gsm48_rr_cd *cd,
uint16_t *ma, uint8_t *ma_len)
{
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm_settings *set = &ms->settings;
int i, pcs, index;
uint16_t arfcn;
- pcs = gsm_refer_pcs(cs->arfcn, s) ? ARFCN_PCS : 0;
+ pcs = gsm_refer_pcs(cs->sel_arfcn, s) ? ARFCN_PCS : 0;
/* no hopping (no MA), channel description is valid */
if (!cd->h) {
@@ -3564,7 +3576,7 @@ static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_frq_redef *fr = msgb_l3(msg);
int mob_al_len = msgb_l3len(msg) - sizeof(*fr);
uint8_t ch_type, ch_subch, ch_ts;
@@ -3601,7 +3613,7 @@ static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
} else {
cd.h = 0;
gsm48_decode_chan_h0(&fr->chan_desc, &cd.tsc, &cd.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cd.arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " (ARFCN %s TS %u SS %u TSC %u)\n",
gsm_print_arfcn(cd.arfcn), ch_ts, ch_subch, cd.tsc);
@@ -3674,7 +3686,7 @@ static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_chan_mode_modify *cm =
(struct gsm48_chan_mode_modify *)gh->data;
@@ -3706,7 +3718,7 @@ static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
} else {
cd->h = 0;
gsm48_decode_chan_h0(&cm->chan_desc, &cd->tsc, &cd->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cd->arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " (chan_nr 0x%02x ARFCN %s TS %u SS %u "
"TSC %u mode %u)\n", cm->chan_desc.chan_nr,
@@ -3782,7 +3794,7 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
@@ -3829,7 +3841,7 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
} else {
cdb->h = 0;
gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cdb->arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
"ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
@@ -3852,7 +3864,7 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
} else {
cda->h = 0;
gsm48_decode_chan_h0(&ac->chan_desc, &cda->tsc, &cda->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cda->arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
"SS %u TSC %u)\n", ac->chan_desc.chan_nr,
@@ -4202,7 +4214,7 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm48_rr_meas *rrmeas = &rr->meas;
struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
+ struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ho);
@@ -4285,7 +4297,7 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
} else {
cdb->h = 0;
gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cdb->arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
"ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
@@ -4308,7 +4320,7 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
} else {
cda->h = 0;
gsm48_decode_chan_h0(&ho->chan_desc, &cda->tsc, &cda->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
+ if (gsm_refer_pcs(cs->sel_arfcn, s))
cda->arfcn |= ARFCN_PCS;
LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
"SS %u TSC %u)\n", ho->chan_desc.chan_nr,
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index 6a93cec2..b1ee65b5 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -335,12 +335,14 @@ DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
"Given frequency is PCS band (1900) rather than DCS band.")
{
struct osmocom_ms *ms;
+ struct gsm322_cellsel *cs;
struct gsm48_sysinfo *s;
uint16_t arfcn = atoi(argv[1]);
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
+ cs = &ms->cellsel;
if (argc > 2) {
if (arfcn < 512 || arfcn > 810) {
@@ -351,7 +353,10 @@ DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
arfcn |= ARFCN_PCS;
}
- s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
+ if (cs->selected && cs->sel_arfcn == arfcn)
+ s = &cs->sel_si;
+ else
+ s = cs->list[arfcn2index(arfcn)].sysinfo;
if (!s) {
vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
argv[1], VTY_NEWLINE);