[PATCH] osmocom-bb[master]: trxcon/scheduler: separate primitive management code

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
Thu Feb 22 15:33:32 UTC 2018


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

trxcon/scheduler: separate primitive management code

It's good to write, keep and make the source code as much modular
as possible. So, Tte primitive management code was separated to
the 'sched_prim.c' and going to be extended in the near future.

Change-Id: Ifec8c9e4f2c95c72b00772688bcb5dc9c11d6de7
---
M src/host/trxcon/Makefile.am
M src/host/trxcon/l1ctl.c
M src/host/trxcon/sched_lchan_common.c
M src/host/trxcon/sched_lchan_tchf.c
A src/host/trxcon/sched_prim.c
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
7 files changed, 214 insertions(+), 141 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/07/6807/1

diff --git a/src/host/trxcon/Makefile.am b/src/host/trxcon/Makefile.am
index 88ff2be..c9cc170 100644
--- a/src/host/trxcon/Makefile.am
+++ b/src/host/trxcon/Makefile.am
@@ -39,6 +39,7 @@
 	sched_lchan_sch.c \
 	sched_mframe.c \
 	sched_clck.c \
+	sched_prim.c \
 	sched_trx.c \
 	$(NULL)
 
diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index b72f5ea..a11e792 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -495,8 +495,7 @@
 		"(offset=%u ra=0x%02x)\n", req->offset, req->ra);
 
 	/* Init a new primitive */
-	rc = sched_trx_init_prim(l1l->trx, &prim, len,
-		chan_nr, link_id);
+	rc = sched_prim_init(l1l->trx, &prim, len, chan_nr, link_id);
 	if (rc)
 		goto exit;
 
@@ -506,7 +505,7 @@
 	 * FIXME: what if requested TS is not configured?
 	 * Or what if one (such as TCH) has no TRXC_RACH slots?
 	 */
-	rc = sched_trx_push_prim(l1l->trx, prim, chan_nr);
+	rc = sched_prim_push(l1l->trx, prim, chan_nr);
 	if (rc) {
 		talloc_free(prim);
 		goto exit;
@@ -619,13 +618,13 @@
 		"link_id=0x%02x)\n", chan_nr, link_id);
 
 	/* Init a new primitive */
-	rc = sched_trx_init_prim(l1l->trx, &prim, 23,
+	rc = sched_prim_init(l1l->trx, &prim, 23,
 		chan_nr, link_id);
 	if (rc)
 		goto exit;
 
 	/* Push this primitive to transmit queue */
-	rc = sched_trx_push_prim(l1l->trx, prim, chan_nr);
+	rc = sched_prim_push(l1l->trx, prim, chan_nr);
 	if (rc) {
 		talloc_free(prim);
 		goto exit;
@@ -657,13 +656,13 @@
 		"link_id=0x%02x)\n", chan_nr, link_id);
 
 	/* Init a new primitive */
-	rc = sched_trx_init_prim(l1l->trx, &prim, TRAFFIC_DATA_LEN,
+	rc = sched_prim_init(l1l->trx, &prim, TRAFFIC_DATA_LEN,
 		chan_nr, link_id);
 	if (rc)
 		goto exit;
 
 	/* Push this primitive to transmit queue */
-	rc = sched_trx_push_prim(l1l->trx, prim, chan_nr);
+	rc = sched_prim_push(l1l->trx, prim, chan_nr);
 	if (rc) {
 		talloc_free(prim);
 		goto exit;
diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c
index bf47541..9eccc3e 100644
--- a/src/host/trxcon/sched_lchan_common.c
+++ b/src/host/trxcon/sched_lchan_common.c
@@ -185,52 +185,3 @@
 		return 0;
 	}
 }
-
-#define CHAN_IS_TCH(chan) \
-	(chan == TRXC_TCHF || chan == TRXC_TCHH_0 || chan == TRXC_TCHH_1)
-
-#define PRIM_IS_TCH(prim) \
-	CHAN_IS_TCH(prim->chan) && prim->payload_len != GSM_MACBLOCK_LEN
-
-#define PRIM_IS_FACCH(prim) \
-	CHAN_IS_TCH(prim->chan) && prim->payload_len == GSM_MACBLOCK_LEN
-
-struct trx_ts_prim *sched_dequeue_tch_prim(struct llist_head *queue)
-{
-	struct trx_ts_prim *a, *b;
-
-	/* Obtain the first prim from TX queue */
-	a = llist_entry(queue->next, struct trx_ts_prim, list);
-
-	/* If this is the only one => do nothing... */
-	if (queue->next->next == queue)
-		return a;
-
-	/* Obtain the second prim from TX queue */
-	b = llist_entry(queue->next->next, struct trx_ts_prim, list);
-
-	/* Find and prioritize FACCH  */
-	if (PRIM_IS_FACCH(a) && PRIM_IS_TCH(b)) {
-		/**
-		 * Case 1: first is FACCH, second is TCH:
-		 * Prioritize FACCH, dropping TCH
-		 */
-		llist_del(&b->list);
-		talloc_free(b);
-		return a;
-	} else if (PRIM_IS_TCH(a) && PRIM_IS_FACCH(b)) {
-		/**
-		 * Case 2: first is TCH, second is FACCH:
-		 * Prioritize FACCH, dropping TCH
-		 */
-		llist_del(&a->list);
-		talloc_free(a);
-		return b;
-	} else {
-		/**
-		 * Otherwise: both are TCH or FACCH frames:
-		 * Nothing to prioritize, return the first one
-		 */
-		return a;
-	}
-}
diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c
index 7860007..da24b23 100644
--- a/src/host/trxcon/sched_lchan_tchf.c
+++ b/src/host/trxcon/sched_lchan_tchf.c
@@ -217,7 +217,7 @@
 	}
 
 	/* Get a message from TX queue */
-	prim = sched_dequeue_tch_prim(&ts->tx_prims);
+	prim = sched_prim_dequeue_tch(&ts->tx_prims);
 	l2 = (uint8_t *) prim->payload;
 
 	/* Determine payload length */
diff --git a/src/host/trxcon/sched_prim.c b/src/host/trxcon/sched_prim.c
new file mode 100644
index 0000000..1d1a940
--- /dev/null
+++ b/src/host/trxcon/sched_prim.c
@@ -0,0 +1,199 @@
+/*
+ * OsmocomBB <-> SDR connection bridge
+ * TDMA scheduler: primitive management
+ *
+ * (C) 2017 by Vadim Yanitskiy <axilirator at gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <talloc.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/linuxlist.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+#include "scheduler.h"
+#include "sched_trx.h"
+#include "trx_if.h"
+#include "logging.h"
+
+/**
+ * Initializes a new primitive by allocating memory
+ * and filling some meta-information (e.g. lchan type).
+ *
+ * @param  trx     TRX instance to be used as initial talloc context
+ * @param  prim    external prim pointer (will point to the allocated prim)
+ * @param  pl_len  prim payload length
+ * @param  chan_nr RSL channel description (used to set a proper chan)
+ * @param  link_id RSL link description (used to set a proper chan)
+ * @return         zero in case of success, otherwise a error number
+ */
+int sched_prim_init(struct trx_instance *trx,
+	struct trx_ts_prim **prim, size_t pl_len,
+	uint8_t chan_nr, uint8_t link_id)
+{
+	enum trx_lchan_type lchan_type;
+	struct trx_ts_prim *new_prim;
+	uint8_t len;
+
+	/* Determine lchan type */
+	lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id);
+	if (!lchan_type) {
+		LOGP(DSCH, LOGL_ERROR, "Couldn't determine lchan type "
+			"for chan_nr=%02x and link_id=%02x\n", chan_nr, link_id);
+		return -EINVAL;
+	}
+
+	/* How much memory do we need? */
+	len  = sizeof(struct trx_ts_prim); /* Primitive header */
+	len += pl_len; /* Requested payload size */
+
+	/* Allocate a new primitive */
+	new_prim = talloc_zero_size(trx, len);
+	if (new_prim == NULL) {
+		LOGP(DSCH, LOGL_ERROR, "Failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	/* Init primitive header */
+	new_prim->payload_len = pl_len;
+	new_prim->chan = lchan_type;
+
+	/* Set external pointer */
+	*prim = new_prim;
+
+	return 0;
+}
+
+/**
+ * Adds a primitive to the end of transmit queue of a particular
+ * timeslot, whose index is parsed from chan_nr.
+ *
+ * @param  trx     TRX instance
+ * @param  prim    to be enqueued primitive
+ * @param  chan_nr RSL channel description
+ * @return         zero in case of success, otherwise a error number
+ */
+int sched_prim_push(struct trx_instance *trx,
+	struct trx_ts_prim *prim, uint8_t chan_nr)
+{
+	struct trx_ts *ts;
+	uint8_t tn;
+
+	/* Determine TS index */
+	tn = chan_nr & 0x7;
+	if (tn > 7) {
+		LOGP(DSCH, LOGL_ERROR, "Incorrect TS index %u\n", tn);
+		return -EINVAL;
+	}
+
+	/* Check whether required timeslot is allocated and configured */
+	ts = trx->ts_list[tn];
+	if (ts == NULL || ts->mf_layout == NULL) {
+		LOGP(DSCH, LOGL_ERROR, "Timeslot %u isn't configured\n", tn);
+		return -EINVAL;
+	}
+
+	/**
+	 * Change talloc context of primitive
+	 * from trx to the parent ts
+	 */
+	talloc_steal(ts, prim);
+
+	/* Add primitive to TS transmit queue */
+	llist_add_tail(&prim->list, &ts->tx_prims);
+
+	return 0;
+}
+
+#define CHAN_IS_TCH(chan) \
+	(chan == TRXC_TCHF || chan == TRXC_TCHH_0 || chan == TRXC_TCHH_1)
+
+#define PRIM_IS_TCH(prim) \
+	CHAN_IS_TCH(prim->chan) && prim->payload_len != GSM_MACBLOCK_LEN
+
+#define PRIM_IS_FACCH(prim) \
+	CHAN_IS_TCH(prim->chan) && prim->payload_len == GSM_MACBLOCK_LEN
+
+/**
+ * Dequeues a TCH or FACCH frame, prioritizing the second.
+ * In case if a FACCH frame is found, a TCH frame is being
+ * dropped (i.e. replaced).
+ *
+ * @param  queue a transmit queue to take a prim from
+ * @return       a FACCH or TCH primitive
+ */
+struct trx_ts_prim *sched_prim_dequeue_tch(struct llist_head *queue)
+{
+	struct trx_ts_prim *a, *b;
+
+	/* Obtain the first prim from TX queue */
+	a = llist_entry(queue->next, struct trx_ts_prim, list);
+
+	/* If this is the only one => do nothing... */
+	if (queue->next->next == queue)
+		return a;
+
+	/* Obtain the second prim from TX queue */
+	b = llist_entry(queue->next->next, struct trx_ts_prim, list);
+
+	/* Find and prioritize FACCH  */
+	if (PRIM_IS_FACCH(a) && PRIM_IS_TCH(b)) {
+		/**
+		 * Case 1: first is FACCH, second is TCH:
+		 * Prioritize FACCH, dropping TCH
+		 */
+		llist_del(&b->list);
+		talloc_free(b);
+		return a;
+	} else if (PRIM_IS_TCH(a) && PRIM_IS_FACCH(b)) {
+		/**
+		 * Case 2: first is TCH, second is FACCH:
+		 * Prioritize FACCH, dropping TCH
+		 */
+		llist_del(&a->list);
+		talloc_free(a);
+		return b;
+	} else {
+		/**
+		 * Otherwise: both are TCH or FACCH frames:
+		 * Nothing to prioritize, return the first one
+		 */
+		return a;
+	}
+}
+
+/**
+ * Flushes a queue of primitives
+ *
+ * @param list list of prims going to be flushed
+ */
+void sched_prim_flush_queue(struct llist_head *list)
+{
+	struct trx_ts_prim *prim, *prim_next;
+
+	llist_for_each_entry_safe(prim, prim_next, list, list) {
+		llist_del(&prim->list);
+		talloc_free(prim);
+	}
+}
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 02da241..ec2f448 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -37,16 +37,6 @@
 #include "trx_if.h"
 #include "logging.h"
 
-static void prim_queue_flush(struct llist_head *list)
-{
-	struct trx_ts_prim *prim, *prim_next;
-
-	llist_for_each_entry_safe(prim, prim_next, list, list) {
-		llist_del(&prim->list);
-		talloc_free(prim);
-	}
-}
-
 static void sched_frame_clck_cb(struct trx_sched *sched)
 {
 	struct trx_instance *trx = (struct trx_instance *) sched->data;
@@ -202,7 +192,7 @@
 	LOGP(DSCH, LOGL_NOTICE, "Delete TDMA timeslot #%u\n", tn);
 
 	/* Flush queue primitives for TX */
-	prim_queue_flush(&ts->tx_prims);
+	sched_prim_flush_queue(&ts->tx_prims);
 
 	/* Remove ts from list and free memory */
 	trx->ts_list[tn] = NULL;
@@ -289,7 +279,7 @@
 	ts->mf_layout = NULL;
 
 	/* Flush queue primitives for TX */
-	prim_queue_flush(&ts->tx_prims);
+	sched_prim_flush_queue(&ts->tx_prims);
 
 	/* Free channel states */
 	talloc_free(ts->lchans);
@@ -426,75 +416,6 @@
 
 		lchan->active = 0;
 	}
-}
-
-int sched_trx_init_prim(struct trx_instance *trx,
-	struct trx_ts_prim **prim, size_t pl_len,
-	uint8_t chan_nr, uint8_t link_id)
-{
-	enum trx_lchan_type lchan_type;
-	struct trx_ts_prim *new_prim;
-	uint8_t len;
-
-	/* Determine lchan type */
-	lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id);
-	if (!lchan_type) {
-		LOGP(DSCH, LOGL_ERROR, "Couldn't determine lchan type "
-			"for chan_nr=%02x and link_id=%02x\n", chan_nr, link_id);
-		return -EINVAL;
-	}
-
-	/* How much memory do we need? */
-	len  = sizeof(struct trx_ts_prim); /* Primitive header */
-	len += pl_len; /* Requested payload size */
-
-	/* Allocate a new primitive */
-	new_prim = talloc_zero_size(trx, len);
-	if (new_prim == NULL) {
-		LOGP(DSCH, LOGL_ERROR, "Failed to allocate memory\n");
-		return -ENOMEM;
-	}
-
-	/* Init primitive header */
-	new_prim->payload_len = pl_len;
-	new_prim->chan = lchan_type;
-
-	/* Set external pointer */
-	*prim = new_prim;
-
-	return 0;
-}
-
-int sched_trx_push_prim(struct trx_instance *trx,
-	struct trx_ts_prim *prim, uint8_t chan_nr)
-{
-	struct trx_ts *ts;
-	uint8_t tn;
-
-	/* Determine TS index */
-	tn = chan_nr & 0x7;
-	if (tn > 7) {
-		LOGP(DSCH, LOGL_ERROR, "Incorrect TS index %u\n", tn);
-		return -EINVAL;
-	}
-
-	/* Check whether required timeslot is allocated and configured */
-	ts = trx->ts_list[tn];
-	if (ts == NULL || ts->mf_layout == NULL) {
-		LOGP(DSCH, LOGL_ERROR, "Timeslot %u isn't configured\n", tn);
-		return -EINVAL;
-	}
-
-	/**
-	 * Change talloc context of primitive
-	 * from trx to the parent ts
-	 */
-	talloc_steal(ts, prim);
-
-	/* Add primitive to TS transmit queue */
-	llist_add_tail(&prim->list, &ts->tx_prims);
-
-	return 0;
 }
 
 enum gsm_phys_chan_config sched_trx_chan_nr2pchan_config(uint8_t chan_nr)
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index f2c091e..f1ad7d3 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -264,11 +264,13 @@
 	enum trx_lchan_type chan);
 
 /* Primitive management functions */
-int sched_trx_init_prim(struct trx_instance *trx, struct trx_ts_prim **prim,
+int sched_prim_init(struct trx_instance *trx, struct trx_ts_prim **prim,
 	size_t pl_len, uint8_t chan_nr, uint8_t link_id);
-int sched_trx_push_prim(struct trx_instance *trx,
+int sched_prim_push(struct trx_instance *trx,
 	struct trx_ts_prim *prim, uint8_t chan_nr);
-struct trx_ts_prim *sched_dequeue_tch_prim(struct llist_head *queue);
+
+struct trx_ts_prim *sched_prim_dequeue_tch(struct llist_head *queue);
+void sched_prim_flush_queue(struct llist_head *list);
 
 int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
 	uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifec8c9e4f2c95c72b00772688bcb5dc9c11d6de7
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list