[05/33] Add RACH message to PH-/MPH-/TCH-SAP interface
diff mbox

Message ID 1409176492-13269-6-git-send-email-laforge@gnumonks.org
State Superseded
Headers show

Commit Message

Harald Welte Aug. 27, 2014, 9:54 p.m. UTC
From: Andreas Eversberg <jolly@eversberg.eu>

This part moves RACH message primitives from osmo-bts-sysmo to common
part.
---
 src/common/l1sap.c         | 69 +++++++++++++++++++++++++++++++++
 src/osmo-bts-sysmo/l1_if.c | 97 +++++++++++++++-------------------------------
 2 files changed, 101 insertions(+), 65 deletions(-)

Patch
diff mbox

diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index f4f3246..dfc81a4 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);
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 542e3ce..c28e467 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -1015,91 +1015,58 @@  static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
 	return rc;
 }
 
-static int check_acc_delay(GsmL1_PhRaInd_t *ra_ind, struct gsm_bts_role_bts *btsb,
-				uint8_t *acc_delay)
-{
-	if (ra_ind->measParam.i16BurstTiming < 0)
-		*acc_delay = 0;
-	else
-		*acc_delay = ra_ind->measParam.i16BurstTiming >> 2;
-	return *acc_delay <= btsb->max_ta;
-}
-
-static int handle_handover(struct gsm_lchan *lchan, struct gsm_bts_role_bts *btsb,
-				GsmL1_PhRaInd_t *ra_ind)
-{
-	uint8_t acc_delay;
-	if (!check_acc_delay(ra_ind, btsb, &acc_delay)) {
-		LOGP(DHO, LOGL_INFO, "%s ignoring RACH request %u > max_ta(%u)\n",
-			gsm_lchan_name(lchan), acc_delay, btsb->max_ta);
-		return 0;
-	}
-
-	handover_rach(lchan, ra_ind->msgUnitParam.u8Buffer[0], acc_delay);
-	return 0;
-}
-
-static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind)
+static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind,
+			    struct msgb *l1p_msg)
 {
 	struct gsm_bts_trx *trx = fl1->priv;
 	struct gsm_bts *bts = trx->bts;
 	struct gsm_bts_role_bts *btsb = bts->role;
 	struct gsm_lchan *lchan;
-	struct osmo_phsap_prim pp;
-	struct lapdm_channel *lc;
-	uint8_t acc_delay;
+	struct osmo_phsap_prim *l1sap;
+	uint32_t fn;
+	uint8_t ra, acc_delay = 0;
+	int rc;
 
 	/* increment number of busy RACH slots, if required */
 	if (trx == bts->c0 &&
 	    ra_ind->measParam.fRssi >= btsb->load.rach.busy_thresh)
 		btsb->load.rach.busy++;
 
-	if (ra_ind->measParam.fLinkQuality < fl1->min_qual_rach)
+	if (ra_ind->measParam.fLinkQuality < fl1->min_qual_rach) {
+		msgb_free(l1p_msg);
 		return 0;
+	}
 
-	/*
-	 * Check if this is a handover
-	 */
-	lchan = l1if_hLayer_to_lchan(trx, ra_ind->hLayer2);
-	if (lchan && lchan->ho.active == HANDOVER_ENABLED)
-		return handle_handover(lchan, btsb, ra_ind);
+	if (ra_ind->measParam.i16BurstTiming > 0)
+		acc_delay = ra_ind->measParam.i16BurstTiming >> 2;
 
-	/* increment number of RACH slots with valid RACH burst */
-	if (trx == bts->c0)
+	/* increment number of RACH slots with valid non-handover RACH burst */
+	lchan = l1if_hLayer_to_lchan(trx, ra_ind->hLayer2);
+	if (trx == bts->c0 && !(lchan && lchan->ho.active == HANDOVER_ENABLED))
 		btsb->load.rach.access++;
 
-	DEBUGP(DL1C, "Rx PH-RA.ind");
 	dump_meas_res(LOGL_DEBUG, &ra_ind->measParam);
 
-	lc = get_lapdm_chan_by_hl2(fl1->priv, ra_ind->hLayer2);
-	if (!lc) {
-		LOGP(DL1C, LOGL_ERROR, "unable to resolve LAPD channel by hLayer2\n");
-		return -ENODEV;
-	}
-
-	/* check for under/overflow / sign */
-	if (!check_acc_delay(ra_ind, btsb, &acc_delay)) {
-		LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n",
-		     acc_delay, btsb->max_ta);
+	if (ra_ind->msgUnitParam.u8Size != 1) {
+		LOGP(DL1C, LOGL_ERROR, "PH-RACH-INDICATION has %d bits\n",
+			ra_ind->sapi);
+		msgb_free(l1p_msg);
 		return 0;
 	}
 
-	/* check for packet access */
-	if (trx == bts->c0
-	 && (ra_ind->msgUnitParam.u8Buffer[0] & 0xf0) == 0x70) {
-		LOGP(DL1C, LOGL_INFO, "RACH for packet access\n");
-		return pcu_tx_rach_ind(bts, ra_ind->measParam.i16BurstTiming,
-			ra_ind->msgUnitParam.u8Buffer[0], ra_ind->u32Fn);
-	}
-
-	osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RACH,
-			PRIM_OP_INDICATION, NULL);
-
-	pp.u.rach_ind.ra = ra_ind->msgUnitParam.u8Buffer[0];
-	pp.u.rach_ind.fn = ra_ind->u32Fn;
-	pp.u.rach_ind.acc_delay = acc_delay;
-
-	return lapdm_phsap_up(&pp.oph, &lc->lapdm_dcch);
+	fn = ra_ind->u32Fn;
+	ra = ra_ind->msgUnitParam.u8Buffer[0];
+	rc = msgb_trim(l1p_msg, sizeof(*l1sap));
+	if (rc < 0)
+		MSGB_ABORT(l1p_msg, "No room for primitive data\n");
+	l1sap = msgb_l1sap_prim(l1p_msg);
+	osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION,
+		l1p_msg);
+	l1sap->u.rach_ind.ra = ra;
+	l1sap->u.rach_ind.acc_delay = acc_delay;
+	l1sap->u.rach_ind.fn = fn;
+
+	return l1sap_up(trx, l1sap);
 }
 
 /* handle any random indication from the L1 */
@@ -1123,7 +1090,7 @@  static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg)
 		rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg);
 		break;
 	case GsmL1_PrimId_PhRaInd:
-		rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd);
+		return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg);
 		break;
 	default:
 		break;