summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-12-15 18:42:40 +0100
committerHarald Welte <laforge@gnumonks.org>2019-05-23 13:03:45 +0200
commit46f2bdb91601e5c5ac34061a3e185704be8c3efa (patch)
treee74bf9a534f1c25a77eae70ef7570e970670d05e /src/host/layer23/src
parent5981c25bc0372c73137ae04d3c26e8caab3a60fa (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. Change-Id: I4981b0a2a3f896a75e624d07c2d3628442f13ecf
Diffstat (limited to 'src/host/layer23/src')
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 6b41bdd2..74dac749 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -2563,6 +2563,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");
@@ -2698,9 +2704,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");
@@ -2714,15 +2727,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");
@@ -3185,22 +3191,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 "
@@ -3640,6 +3652,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" */
@@ -4005,14 +4018,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 */
@@ -4461,14 +4478,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 */