From b9a917a13880f9d6274409b9d3c9b56de484125f Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Wed, 12 Jun 2013 09:12:04 +0200 Subject: TRX: Handover access burst support --- src/osmo-bts-trx/l1_if.c | 6 ++++-- src/osmo-bts-trx/l1_if.h | 4 ++++ src/osmo-bts-trx/scheduler.c | 47 +++++++++++++++++++++++++++++++++++++------- src/osmo-bts-trx/scheduler.h | 3 ++- src/osmo-bts-trx/trx_if.c | 10 ++++++++++ src/osmo-bts-trx/trx_if.h | 2 ++ 6 files changed, 62 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c index a09fa199..986c9889 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 9e4a3f47..5b4dce3c 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 bcde7f30..13e14e8b 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 f2873a11..acc2cebe 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 746e95bb..e798ca53 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 f041c933..ac0ee42c 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); -- cgit v1.2.3