[PATCH] osmo-bts[master]: Add loopback support for PDTCH

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Fri Jun 23 16:47:30 UTC 2017


Review at  https://gerrit.osmocom.org/3032

Add loopback support for PDTCH

This add support for BTS-side lookback of PDTCH channels.

If lchan-loopback is enabled, We take the uplink frames as received in
PH-DATA.ind and put them into the dl_tch_queue for that lchan.  When we
receive PH-RTS.ind, we dequeue frames from that queue and transmit them
in downlink. If no frame is found in queue, we transmit an empty
(all-zero) frame of 23 bytes (CS-1).

Change-Id: Idd07a3f4a88c38398d3e844333c0104e2de23864
---
M src/common/l1sap.c
1 file changed, 88 insertions(+), 27 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/32/3032/1

diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index b9104b7..15e2509 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -50,6 +50,16 @@
 #include <osmo-bts/power_control.h>
 #include <osmo-bts/msg_utils.h>
 
+static char *dump_gsmtime(const struct gsm_time *tm)
+{
+	static char buf[64];
+
+	snprintf(buf, sizeof(buf), "%06u/%02u/%02u/%02u/%02u",
+		 tm->fn, tm->t1, tm->t2, tm->t3, tm->fn%52);
+	buf[sizeof(buf)-1] = '\0';
+	return buf;
+}
+
 struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx,
 				       unsigned int chan_nr)
 {
@@ -580,6 +590,39 @@
 	return rc;
 }
 
+/*! handling for PDTCH loopback mode, used for BER testing
+ *  \param[in] lchan logical channel on which we operate
+ *  \param[in] rts_ind PH-RTS.ind from PHY which we process
+ *  \param[out] msg Message buffer to which we write data
+ *
+ *  The function will fill \a msg, from which the caller can then
+ *  subsequently build a PH-DATA.req */
+static int lchan_pdtch_ph_rts_ind_loop(struct gsm_lchan *lchan,
+					const struct ph_data_param *rts_ind,
+					struct msgb *msg, const struct gsm_time *tm)
+{
+	struct msgb *loop_msg;
+	uint8_t *p;
+
+	/* de-queue response message (loopback) */
+	loop_msg = msgb_dequeue(&lchan->dl_tch_queue);
+	if (!loop_msg) {
+		LOGP(DL1P, LOGL_NOTICE, "%s %s: no looped PDTCH message, sending empty\n",
+		     gsm_lchan_name(lchan), dump_gsmtime(tm));
+		/* empty downlink message */
+		p = msgb_put(msg, GSM_MACBLOCK_LEN);
+		memset(p, 0, GSM_MACBLOCK_LEN);
+	} else {
+		LOGP(DL1P, LOGL_NOTICE, "%s %s: looped PDTCH message of %u bytes\n",
+		     gsm_lchan_name(lchan), dump_gsmtime(tm), msgb_l2len(loop_msg));
+		/* copy over data from queued response message */
+		p = msgb_put(msg, msgb_l2len(loop_msg));
+		memcpy(p, msgb_l2(loop_msg), msgb_l2len(loop_msg));
+		msgb_free(loop_msg);
+	}
+	return 0;
+}
+
 /* PH-RTS-IND prim received from bts model */
 static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
 	struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind)
@@ -603,21 +646,8 @@
 
 	gsm_fn2gsmtime(&g_time, fn);
 
-	DEBUGP(DL1P, "Rx PH-RTS.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n",
-		g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id);
-
-	if (ts_is_pdch(&trx->ts[tn])) {
-		if (L1SAP_IS_PTCCH(rts_ind->fn)) {
-			pcu_tx_rts_req(&trx->ts[tn], 1, fn, 1 /* ARFCN */,
-				L1SAP_FN2PTCCHBLOCK(fn));
-
-			return 0;
-		}
-		pcu_tx_rts_req(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
-			L1SAP_FN2MACBLOCK(fn));
-
-		return 0;
-	}
+	DEBUGP(DL1P, "Rx PH-RTS.ind %s chan_nr=%d link_id=%d\n",
+		dump_gsmtime(&g_time), chan_nr, link_id);
 
 	/* reuse PH-RTS.ind for PH-DATA.req */
 	if (!msg) {
@@ -630,7 +660,25 @@
 		msg);
 	msg->l2h = msg->l1h + sizeof(*l1sap);
 
-	if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
+	if (ts_is_pdch(&trx->ts[tn])) {
+		lchan = get_active_lchan_by_chan_nr(trx, chan_nr);
+		if (lchan && lchan->loopback) {
+			if (!L1SAP_IS_PTCCH(rts_ind->fn))
+				lchan_pdtch_ph_rts_ind_loop(lchan, rts_ind, msg, &g_time);
+			/* continue below like for SACCH/FACCH/... */
+		} else {
+			/* forward RTS.ind to PCU */
+			if (L1SAP_IS_PTCCH(rts_ind->fn)) {
+				pcu_tx_rts_req(&trx->ts[tn], 1, fn, 1 /* ARFCN */,
+						L1SAP_FN2PTCCHBLOCK(fn));
+			} else {
+				pcu_tx_rts_req(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
+						L1SAP_FN2MACBLOCK(fn));
+			}
+			/* return early, PCU takes care of rest */
+			return 0;
+		}
+	} else if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
 		p = msgb_put(msg, GSM_MACBLOCK_LEN);
 		/* get them from bts->si_buf[] */
 		si = bts_sysinfo_get(trx->bts, &g_time);
@@ -901,25 +949,38 @@
 		g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id);
 
 	if (ts_is_pdch(&trx->ts[tn])) {
+		lchan = get_lchan_by_chan_nr(trx, chan_nr);
+		if (!lchan)
+			LOGP(DL1P, LOGL_ERROR, "No lchan for chan_nr=%d\n", chan_nr);
+		if (lchan && lchan->loopback) {
+			/* we are in loopback mode (for BER testing)
+			 * mode and need to enqeue the frame to be
+			 * returned in downlink */
+			msgb_enqueue(&lchan->dl_tch_queue, msg);
+
+			/* Return 1 to signal that we're still using msg
+			 * and it should not be freed */
+			return 1;
+		}
+
+		/* don't send bad frames to PCU */
 		if (len == 0)
 			return -EINVAL;
 		if (L1SAP_IS_PTCCH(fn)) {
 			pcu_tx_data_ind(&trx->ts[tn], 1, fn,
-				0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn),
+					0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn),
 					data, len, rssi, data_ind->ber10k,
 					data_ind->ta_offs_qbits,
 					data_ind->lqual_cb);
-
-			return 0;
+		} else {
+			/* drop incomplete UL block */
+			if (pr_info != PRES_INFO_BOTH)
+				return 0;
+			/* PDTCH / PACCH frame handling */
+			pcu_tx_data_ind(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
+					L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k,
+					data_ind->ta_offs_qbits, data_ind->lqual_cb);
 		}
-		/* drop incomplete UL block */
-		if (pr_info != PRES_INFO_BOTH)
-			return 0;
-		/* PDTCH / PACCH frame handling */
-		pcu_tx_data_ind(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
-			L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k,
-				data_ind->ta_offs_qbits, data_ind->lqual_cb);
-
 		return 0;
 	}
 

-- 
To view, visit https://gerrit.osmocom.org/3032
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idd07a3f4a88c38398d3e844333c0104e2de23864
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list