aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-06-12 09:12:04 +0200
committerHarald Welte <laforge@gnumonks.org>2015-09-22 16:41:28 +0200
commitb9a917a13880f9d6274409b9d3c9b56de484125f (patch)
treee419c598bafc3bc821409699f05213718931d642
parent6527dffc94686672add10fe6b66f898c436ea34c (diff)
TRX: Handover access burst support
-rw-r--r--src/osmo-bts-trx/l1_if.c6
-rw-r--r--src/osmo-bts-trx/l1_if.h4
-rw-r--r--src/osmo-bts-trx/scheduler.c47
-rw-r--r--src/osmo-bts-trx/scheduler.h3
-rw-r--r--src/osmo-bts-trx/trx_if.c10
-rw-r--r--src/osmo-bts-trx/trx_if.h2
6 files changed, 62 insertions, 10 deletions
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index a09fa19..986c988 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -501,7 +501,8 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
lchan->tch.amr_mr.mode[1].mode,
lchan->tch.amr_mr.mode[2].mode,
lchan->tch.amr_mr.mode[3].mode,
- amr_get_initial_mode(lchan));
+ amr_get_initial_mode(lchan),
+ (lchan->ho.active == 1));
/* init lapdm */
lchan_init_lapdm(lchan);
/* set lchan active */
@@ -520,7 +521,8 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
lchan->tch.amr_mr.mode[1].mode,
lchan->tch.amr_mr.mode[2].mode,
lchan->tch.amr_mr.mode[3].mode,
- amr_get_initial_mode(lchan));
+ amr_get_initial_mode(lchan),
+ 0);
break;
}
if ((chan_nr & 0x80)) {
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index 9e4a3f4..5b4dce3 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -100,6 +100,9 @@ struct trx_chan_state {
float toa_sum; /* sum of TOA values */
int toa_num; /* number of TOA value */
} meas;
+
+ /* handover */
+ uint8_t ho_rach_detect; /* if rach detection is on */
};
struct trx_config {
@@ -157,6 +160,7 @@ struct trx_l1h {
/* Channel states for all channels on all timeslots */
struct trx_chan_state chan_states[8][_TRX_CHAN_MAX];
struct llist_head dl_prims[8]; /* Queue primitves for TX */
+ uint8_t ho_rach_detect[8][8];
};
struct trx_l1h *l1if_open(struct gsm_bts_trx *trx);
diff --git a/src/osmo-bts-trx/scheduler.c b/src/osmo-bts-trx/scheduler.c
index bcde7f3..13e14e8 100644
--- a/src/osmo-bts-trx/scheduler.c
+++ b/src/osmo-bts-trx/scheduler.c
@@ -1173,17 +1173,20 @@ static int rx_rach_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
float toa)
{
+ uint8_t chan_nr;
struct osmo_phsap_prim l1sap;
uint8_t ra;
int rc;
- LOGP(DL1C, LOGL_NOTICE, "Received %s fn=%u toa=%.2f\n",
+ chan_nr = trx_chan_desc[chan].chan_nr | tn;
+
+ LOGP(DL1C, LOGL_NOTICE, "Received Access Burst on %s fn=%u toa=%.2f\n",
trx_chan_desc[chan].name, fn, toa);
/* decode */
rc = rach_decode(&ra, bits + 8 + 41, l1h->trx->bts->bsic);
if (rc) {
- LOGP(DL1C, LOGL_NOTICE, "Received bad rach frame at fn=%u "
+ LOGP(DL1C, LOGL_NOTICE, "Received bad AB frame at fn=%u "
"(%u/51)\n", fn, fn % 51);
return 0;
}
@@ -1193,6 +1196,7 @@ static int rx_rach_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
memset(&l1sap, 0, sizeof(l1sap));
osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION,
NULL);
+ l1sap.u.rach_ind.chan_nr = chan_nr;
l1sap.u.rach_ind.ra = ra;
#ifdef TA_TEST
#warning TIMING ADVANCE TEST-HACK IS ENABLED!!!
@@ -1222,6 +1226,10 @@ static int rx_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
uint8_t l2[23], l2_len;
int rc;
+ /* handle rach, if handover rach detection is turned on */
+ if (chan_state->ho_rach_detect == 1)
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+
LOGP(DL1C, LOGL_DEBUG, "Data received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
@@ -1382,6 +1390,10 @@ static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
int rc, amr = 0;
float ber;
+ /* handle rach, if handover rach detection is turned on */
+ if (chan_state->ho_rach_detect == 1)
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+
LOGP(DL1C, LOGL_DEBUG, "TCH/F received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
@@ -1522,6 +1534,10 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
int rc, amr = 0;
float ber;
+ /* handle rach, if handover rach detection is turned on */
+ if (chan_state->ho_rach_detect == 1)
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+
LOGP(DL1C, LOGL_DEBUG, "TCH/H received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
@@ -2487,9 +2503,10 @@ int trx_sched_set_lchan(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t link_id,
/* setting all logical channels given attributes to active/inactive */
int trx_sched_set_mode(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
- uint8_t codec2, uint8_t codec3, uint8_t initial_id)
+ uint8_t codec2, uint8_t codec3, uint8_t initial_id, uint8_t handover)
{
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
+ uint8_t ss = l1sap_chan2ss(chan_nr);
int i;
int rc = -EINVAL;
struct trx_chan_state *chan_state;
@@ -2499,11 +2516,13 @@ int trx_sched_set_mode(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t rsl_cmode,
if (trx_chan_desc[i].chan_nr == (chan_nr & 0xf8)
&& trx_chan_desc[i].link_id == 0x00) {
chan_state = &l1h->chan_states[tn][i];
- LOGP(DL1C, LOGL_NOTICE, "Set mode %u, %u on "
- "%s of trx=%d ts=%d\n", rsl_cmode, tch_mode,
- trx_chan_desc[i].name, l1h->trx->nr, tn);
+ LOGP(DL1C, LOGL_NOTICE, "Set mode %u, %u, handover %u "
+ "on %s of trx=%d ts=%d\n", rsl_cmode, tch_mode,
+ handover, trx_chan_desc[i].name, l1h->trx->nr,
+ tn);
chan_state->rsl_cmode = rsl_cmode;
chan_state->tch_mode = tch_mode;
+ chan_state->ho_rach_detect = handover;
if (rsl_cmode == RSL_CMOD_SPD_SPEECH
&& tch_mode == GSM48_CMODE_SPEECH_AMR) {
chan_state->codecs = codecs;
@@ -2522,6 +2541,19 @@ int trx_sched_set_mode(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t rsl_cmode,
}
}
+ /* command rach detection
+ * always enable handover, even if state is still set (due to loss
+ * of transceiver link).
+ * disable handover, if state is still set, since we might not know
+ * the actual state of transceiver (due to loss of link) */
+ if (handover) {
+ l1h->ho_rach_detect[tn][ss] = 1;
+ trx_if_cmd_handover(l1h, tn, ss);
+ } else if (l1h->ho_rach_detect[tn][ss]) {
+ l1h->ho_rach_detect[tn][ss] = 0;
+ trx_if_cmd_nohandover(l1h, tn, ss);
+ }
+
return rc;
}
@@ -2721,7 +2753,8 @@ int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t current_fn,
}
func(l1h, tn, fn, chan, bid, bits, rssi, toa);
- } else if (chan != TRXC_RACH) {
+ } else if (chan != TRXC_RACH
+ && !l1h->chan_states[tn][chan].ho_rach_detect) {
sbit_t spare[148];
memset(spare, 0, 148);
diff --git a/src/osmo-bts-trx/scheduler.h b/src/osmo-bts-trx/scheduler.h
index f2873a1..acc2ceb 100644
--- a/src/osmo-bts-trx/scheduler.h
+++ b/src/osmo-bts-trx/scheduler.h
@@ -29,7 +29,8 @@ int trx_sched_set_lchan(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t link_id,
/* setting all logical channels given attributes to active/inactive */
int trx_sched_set_mode(struct trx_l1h *l1h, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
- uint8_t codec2, uint8_t codec3, uint8_t initial_codec);
+ uint8_t codec2, uint8_t codec3, uint8_t initial_codec,
+ uint8_t handover);
/* setting cipher on logical channels */
int trx_sched_set_cipher(struct trx_l1h *l1h, uint8_t chan_nr, int downlink,
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index 746e95b..e798ca5 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -294,6 +294,16 @@ int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn)
return trx_ctrl_cmd(l1h, 1, "TXTUNE", "%d", freq10 * 100);
}
+int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss)
+{
+ return trx_ctrl_cmd(l1h, 1, "HANDOVER", "%d %d", tn, ss);
+}
+
+int trx_if_cmd_nohandover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss)
+{
+ return trx_ctrl_cmd(l1h, 1, "NOHANDOVER", "%d %d", tn, ss);
+}
+
/* get response from ctrl socket */
static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what)
{
diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h
index f041c93..ac0ee42 100644
--- a/src/osmo-bts-trx/trx_if.h
+++ b/src/osmo-bts-trx/trx_if.h
@@ -24,6 +24,8 @@ int trx_if_cmd_setmaxdly(struct trx_l1h *l1h, int dly);
int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type);
int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn);
int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn);
+int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss);
+int trx_if_cmd_nohandover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss);
int trx_if_data(struct trx_l1h *l1h, uint8_t tn, uint32_t fn, uint8_t pwr,
const ubit_t *bits);
int trx_if_open(struct trx_l1h *l1h);