summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-12-15 18:42:40 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2015-12-25 09:33:08 +0100
commit98a0c0bc0eb5ac029c65a1e8de337f25cbdc220c (patch)
treed606f0b47574aafded38be0031465db2675023fa
parent3ba8e6da0de37c302c87b55a8b2f0961e6c1e807 (diff)
mobile: Keep track of cell channel description during dedicated mode
The initial cell channel decription is received via SI1. During a call this description may change due to handover, assignment, frequency redefinition. Whenever it changes, the last received cell channel description is used to handle messages that do not include this information element. Example of one call with handover inbetween. The assignments do not include a cell channel description: IMMEDIATE ASSIGNMENT: Use cell channel description from SI1. ASSIGNMENT COMMAND: Re-use cell channel description from SI1. HANDOVER COMMAND: Use new cell channel description from HANDOVER COMMAND. ASSIGNMENT COMMAND: Re-use cell channel description from HANDOVER COMMAND.
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h1
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c67
2 files changed, 45 insertions, 23 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
index 14b7dc66..1638f14d 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
@@ -106,6 +106,7 @@ struct gsm48_rr_cd {
uint8_t freq_list_lv[131]; /* len + 130 octets */
uint8_t freq_seq_lv[10]; /* len + 9 octets */
uint8_t cell_desc_lv[17]; /* len + 16 octets */
+ char cell_desc_origin[64]; /* description of IE origin */
uint8_t start; /* start time available */
struct gsm_time start_tm; /* start time */
uint8_t mode; /* mode of channel */
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index b5e717e4..067f96c0 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -2566,6 +2566,12 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
/* mobile allocation */
memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
ia->mob_alloc_len + 1);
+ /* get cell channel description of current cell */
+ rr->cd_now.cell_desc_lv[0] = 16;
+ memcpy(rr->cd_now.cell_desc_lv + 1, s->si1_msg + 3, 16);
+ sprintf(rr->cd_now.cell_desc_origin, "SI1 of cell %s",
+ gsm_print_arfcn(cs->sel_arfcn));
+ /* ignore RACH confirm and other assignments */
rr->wait_assign = 2;
/* reset scheduler */
LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
@@ -2701,9 +2707,16 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
memcpy(&rr->cd_now, &cd1, sizeof(rr->cd_now));
/* timing advance */
rr->cd_now.ind_ta = ia->timing_advance1;
+proceed_est:
/* mobile allocation */
memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
ia->mob_alloc_len + 1);
+ /* get cell channel description of current cell */
+ rr->cd_now.cell_desc_lv[0] = 16;
+ memcpy(rr->cd_now.cell_desc_lv + 1, s->si1_msg + 3, 16);
+ sprintf(rr->cd_now.cell_desc_origin, "SI1 of cell %s",
+ gsm_print_arfcn(cs->sel_arfcn));
+ /* ignore RACH confirm and other assignments */
rr->wait_assign = 2;
/* reset scheduler */
LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
@@ -2717,15 +2730,8 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
memcpy(&rr->cd_now, &cd2, sizeof(rr->cd_now));
/* timing advance */
rr->cd_now.ind_ta = ia->timing_advance2;
- /* mobile allocation */
- memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
- ia->mob_alloc_len + 1);
- rr->wait_assign = 2;
- /* reset scheduler */
- LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
- return gsm48_rr_dl_est(ms);
+ goto proceed_est;
}
LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
@@ -3184,22 +3190,28 @@ static int gsm48_rr_render_ma(struct osmocom_ms *ms, struct gsm48_rr_cd *cd,
/* decode mobile allocation */
if (cd->mob_alloc_lv[0]) {
- struct gsm_sysinfo_freq *freq = s->freq;
+ struct gsm_sysinfo_freq freq;
+
+ memset(&freq, 0, sizeof(freq));
LOGP(DRR, LOGL_INFO, "decoding mobile allocation\n");
- if (cd->cell_desc_lv[0]) {
- LOGP(DRR, LOGL_INFO, "using cell channel descr.\n");
- if (cd->cell_desc_lv[0] != 16) {
- LOGP(DRR, LOGL_ERROR, "cell channel descr. "
- "has invalid lenght\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
- gsm48_decode_freq_list(freq, cd->cell_desc_lv + 1, 16,
- 0xce, FREQ_TYPE_SERV);
+ if (!cd->cell_desc_lv[0]) {
+ LOGP(DRR, LOGL_ERROR, "Software error: we have no "
+ "cell channel description.\n");
+ return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
+ }
+ LOGP(DRR, LOGL_INFO, "using cell channel descr from %s.\n",
+ cd->cell_desc_origin);
+ if (cd->cell_desc_lv[0] != 16) {
+ LOGP(DRR, LOGL_ERROR, "cell channel descr. "
+ "has invalid lenght\n");
+ return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
}
+ gsm48_decode_freq_list(&freq, cd->cell_desc_lv + 1, 16,
+ 0xce, FREQ_TYPE_SERV);
- gsm48_decode_mobile_alloc(freq, cd->mob_alloc_lv + 1,
+ gsm48_decode_mobile_alloc(&freq, cd->mob_alloc_lv + 1,
cd->mob_alloc_lv[0], ma, ma_len, 0);
if (*ma_len < 1) {
LOGP(DRR, LOGL_NOTICE, "mobile allocation with no "
@@ -3633,6 +3645,7 @@ static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_INFO, " using cell channel description)\n");
cd.cell_desc_lv[0] = 16;
memcpy(cd.cell_desc_lv + 1, v, 17);
+ sprintf(cd.cell_desc_origin, "last FREQUENCY REDIFINITION");
}
/* render channel "after time" */
@@ -3998,14 +4011,18 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
}
cdb->cell_desc_lv[0] = len;
memcpy(cdb->cell_desc_lv + 1, v, len);
- cda->cell_desc_lv[0] = len;
- memcpy(cda->cell_desc_lv + 1, v, len);
+ sprintf(cdb->cell_desc_origin, "last ASSIGNMENT COMMAND");
+ memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
+ sizeof(cda->cell_desc_lv));
+ strcpy(cda->cell_desc_origin, cdb->cell_desc_origin);
} else {
/* keep old */
memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
sizeof(cdb->cell_desc_lv));
+ strcpy(cdb->cell_desc_origin, rr->cd_now.cell_desc_origin);
memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
sizeof(cda->cell_desc_lv));
+ strcpy(cda->cell_desc_origin, rr->cd_now.cell_desc_origin);
}
/* channel mode */
@@ -4435,14 +4452,18 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
}
cdb->cell_desc_lv[0] = len;
memcpy(cdb->cell_desc_lv + 1, v, len);
- cda->cell_desc_lv[0] = len;
- memcpy(cda->cell_desc_lv + 1, v, len);
+ sprintf(cdb->cell_desc_origin, "last ASSIGNMENT COMMAND");
+ memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
+ sizeof(cda->cell_desc_lv));
+ strcpy(cda->cell_desc_origin, cdb->cell_desc_origin);
} else {
/* keep old */
memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
sizeof(cdb->cell_desc_lv));
+ strcpy(cdb->cell_desc_origin, rr->cd_now.cell_desc_origin);
memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
sizeof(cda->cell_desc_lv));
+ strcpy(cda->cell_desc_origin, rr->cd_now.cell_desc_origin);
}
/* channel mode */