diff options
Diffstat (limited to 'src/common/l1sap.c')
-rw-r--r-- | src/common/l1sap.c | 69 |
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); |