aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/l1sap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/l1sap.c')
-rw-r--r--src/common/l1sap.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index f4f32466..dfc81a47 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -119,6 +119,72 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
return 1;
}
+static int check_acc_delay(struct ph_rach_ind_param *rach_ind,
+ struct gsm_bts_role_bts *btsb, uint8_t *acc_delay)
+{
+ *acc_delay = rach_ind->acc_delay;
+ return *acc_delay <= btsb->max_ta;
+}
+
+/* special case where handover RACH is detected */
+static int l1sap_handover_rach(struct gsm_bts_trx *trx,
+ struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind)
+{
+ struct gsm_lchan *lchan;
+ uint8_t chan_nr;
+ uint8_t tn, ss;
+
+ chan_nr = rach_ind->chan_nr;
+ tn = L1SAP_CHAN2TS(chan_nr);
+ ss = l1sap_chan2ss(chan_nr);
+ lchan = &trx->ts[tn].lchan[ss];
+
+ handover_rach(lchan, rach_ind->ra, rach_ind->acc_delay);
+
+ /* must return 0, so in case of msg at l1sap, it will be freed */
+ return 0;
+}
+
+/* RACH received from bts model */
+static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx,
+ struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind)
+{
+ struct gsm_bts *bts = trx->bts;
+ struct gsm_bts_role_bts *btsb = bts->role;
+ struct lapdm_channel *lc;
+ uint8_t acc_delay;
+
+ DEBUGP(DL1P, "Rx PH-RA.ind");
+
+ lc = &trx->ts[0].lchan[4].lapdm_ch;
+
+ /* check for under/overflow / sign */
+ if (!check_acc_delay(rach_ind, btsb, &acc_delay)) {
+ LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n",
+ acc_delay, btsb->max_ta);
+ return 0;
+ }
+
+ /* check for handover rach */
+ if (trx != bts->c0 && rach_ind->chan_nr != 0x88)
+ return l1sap_handover_rach(trx, l1sap, rach_ind);
+
+ /* check for packet access */
+ if (trx == bts->c0
+ && L1SAP_IS_PACKET_RACH(rach_ind->ra)) {
+ LOGP(DL1P, LOGL_INFO, "RACH for packet access\n");
+ pcu_tx_rach_ind(bts, rach_ind->acc_delay << 2,
+ rach_ind->ra, rach_ind->fn);
+ return 0;
+ }
+
+ LOGP(DL1P, LOGL_INFO, "RACH for RR access (toa=%d, ra=%d)\n",
+ rach_ind->acc_delay, rach_ind->ra);
+ lapdm_phsap_up(&l1sap->oph, &lc->lapdm_dcch);
+
+ return 0;
+}
+
/* any L1 prim received from bts model */
int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
{
@@ -129,6 +195,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION):
rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data);
break;
+ case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION):
+ rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind);
+ break;
default:
LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n",
l1sap->oph.primitive, l1sap->oph.operation);