summaryrefslogtreecommitdiffstats
path: root/src/host
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-12-15 18:42:40 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2016-09-25 08:11:44 +0200
commit87059041aad05cc1c6470f4c366bdbad989f4f8c (patch)
tree9e8f3cbfe50d33250a5ea2e610e7a95fd2b23dd2 /src/host
parent51e1ead52d7be6eb6e2d22417075f5536b4bd39a (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.
Diffstat (limited to 'src/host')
-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 */