[PATCH] osmocom-bb[master]: host/trxcon/scheduler: implement xCCH decoding

Harald Welte gerrit-no-reply at lists.osmocom.org
Thu Feb 22 15:32:37 UTC 2018


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

host/trxcon/scheduler: implement xCCH decoding

Change-Id: Ieb71e3727b525e85d161855973f63042366ccb05
---
M src/host/trxcon/Makefile.am
M src/host/trxcon/l1ctl.c
M src/host/trxcon/l1ctl.h
M src/host/trxcon/sched_lchan_desc.c
A src/host/trxcon/sched_lchan_handlers.c
M src/host/trxcon/trxcon.c
M src/host/trxcon/trxcon.h
7 files changed, 197 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/96/6696/1

diff --git a/src/host/trxcon/Makefile.am b/src/host/trxcon/Makefile.am
index 1a373f7..b2f22fa 100644
--- a/src/host/trxcon/Makefile.am
+++ b/src/host/trxcon/Makefile.am
@@ -31,6 +31,7 @@
 
 # Scheduler
 trxcon_SOURCES += \
+	sched_lchan_handlers.c \
 	sched_lchan_desc.c \
 	sched_mframe.c \
 	sched_clck.c \
diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index 0bb26f7..3bcc5cb 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -123,6 +123,28 @@
 	return l1ctl_link_send(l1l, msg);
 }
 
+int l1ctl_tx_data_ind(struct l1ctl_link *l1l, struct l1ctl_info_dl *data)
+{
+	struct l1ctl_info_dl *dl;
+	struct msgb *msg;
+	size_t len;
+
+	msg = l1ctl_alloc_msg(L1CTL_DATA_IND);
+	if (msg == NULL)
+		return -ENOMEM;
+
+	/* We store the 23-byte payload as a flexible array member */
+	len = sizeof(struct l1ctl_info_dl) + 23;
+	dl = (struct l1ctl_info_dl *) msgb_put(msg, len);
+
+	/* Copy header and data from source message */
+	memcpy(dl, data, len);
+	talloc_free(data);
+
+	/* Put message to upper layers */
+	return l1ctl_link_send(l1l, msg);
+}
+
 static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
 {
 	struct l1ctl_fbsb_req *fbsb, *fbsb_copy;
diff --git a/src/host/trxcon/l1ctl.h b/src/host/trxcon/l1ctl.h
index ffd1a81..05a2c54 100644
--- a/src/host/trxcon/l1ctl.h
+++ b/src/host/trxcon/l1ctl.h
@@ -4,9 +4,12 @@
 #include <osmocom/core/msgb.h>
 
 #include "l1ctl_link.h"
+#include "l1ctl_proto.h"
 
 int l1ctl_tx_pm_conf(struct l1ctl_link *l1l, uint16_t band_arfcn,
 	int dbm, int last);
 int l1ctl_tx_reset_conf(struct l1ctl_link *l1l, uint8_t type);
 int l1ctl_tx_reset_ind(struct l1ctl_link *l1l, uint8_t type);
 int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg);
+
+int l1ctl_tx_data_ind(struct l1ctl_link *l1l, struct l1ctl_info_dl *ind);
diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c
index 880c2a5..93927a6 100644
--- a/src/host/trxcon/sched_lchan_desc.c
+++ b/src/host/trxcon/sched_lchan_desc.c
@@ -35,11 +35,15 @@
 #define tx_tchh_fn	NULL
 #define tx_rach_fn	NULL
 
-#define rx_data_fn	NULL
 #define rx_pdtch_fn	NULL
 #define rx_tchf_fn	NULL
 #define rx_tchh_fn	NULL
 
+/* Forward declaration of handlers */
+int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
+	uint32_t fn, enum trx_lchan_type chan, uint8_t bid,
+	sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);
+
 const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = {
 	{
 		TRXC_IDLE,		"IDLE",
diff --git a/src/host/trxcon/sched_lchan_handlers.c b/src/host/trxcon/sched_lchan_handlers.c
new file mode 100644
index 0000000..2c2cb6a
--- /dev/null
+++ b/src/host/trxcon/sched_lchan_handlers.c
@@ -0,0 +1,161 @@
+/*
+ * OsmocomBB <-> SDR connection bridge
+ * TDMA scheduler: handlers for DL / UL bursts on logical channels
+ *
+ * (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 <stdint.h>
+
+#include <arpa/inet.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/fsm.h>
+
+#include <osmocom/coding/gsm0503_coding.h>
+
+#include "l1ctl_proto.h"
+#include "scheduler.h"
+#include "sched_trx.h"
+#include "logging.h"
+#include "trx_if.h"
+#include "trxcon.h"
+
+extern struct osmo_fsm_inst *trxcon_fsm;
+
+int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
+	uint32_t fn, enum trx_lchan_type chan, uint8_t bid,
+	sbit_t *bits, uint16_t nbits, int8_t rssi, float toa)
+{
+	int n_errors, n_bits_total, rc;
+	struct trx_lchan_state *lchan;
+	uint8_t *rssi_num, *toa_num;
+	float *rssi_sum, *toa_sum;
+	sbit_t *buffer, *offset;
+	uint8_t l2[23], *mask;
+	uint32_t *first_fn;
+
+	LOGP(DSCH, LOGL_DEBUG, "Data received on %s: fn=%u ts=%u bid=%u\n",
+		trx_lchan_desc[chan].name, fn, ts->index, bid);
+
+	/* Find required channel state */
+	lchan = sched_trx_find_lchan(ts, chan);
+	if (lchan == NULL)
+		return -EINVAL;
+
+	/* Set up pointers */
+	first_fn = &lchan->rx_first_fn;
+	mask = &lchan->rx_burst_mask;
+	buffer = lchan->rx_bursts;
+
+	rssi_sum = &lchan->rssi_sum;
+	rssi_num = &lchan->rssi_num;
+	toa_sum = &lchan->toa_sum;
+	toa_num = &lchan->toa_num;
+
+	/* Clear buffer & store frame number of first burst */
+	if (bid == 0) {
+		memset(buffer, 0, 464);
+
+		*first_fn = fn;
+		*mask = 0x0;
+
+		*rssi_sum = 0;
+		*rssi_num = 0;
+		*toa_sum = 0;
+		*toa_num = 0;
+	}
+
+	/* Update mask and RSSI */
+	*mask |= (1 << bid);
+	*rssi_sum += rssi;
+	(*rssi_num)++;
+	*toa_sum += toa;
+	(*toa_num)++;
+
+	/* Copy burst to buffer of 4 bursts */
+	offset = buffer + bid * 116;
+	memcpy(offset, bits + 3, 58);
+	memcpy(offset + 58, bits + 87, 58);
+
+	/* Wait until complete set of bursts */
+	if (bid != 3)
+		return 0;
+
+	/* Check for complete set of bursts */
+	if ((*mask & 0xf) != 0xf) {
+		LOGP(DSCH, LOGL_DEBUG, "Received incomplete data frame at "
+			"fn=%u (%u/%u) for %s\n", *first_fn,
+			(*first_fn) % ts->mf_layout->period,
+			ts->mf_layout->period,
+			trx_lchan_desc[chan].name);
+
+		/* We require first burst to have correct FN */
+		if (!(*mask & 0x1)) {
+			*mask = 0x0;
+			return 0;
+		}
+
+		/* FIXME: return from here? */
+	}
+
+	/* Attempt to decode */
+	rc = gsm0503_xcch_decode(l2, buffer, &n_errors, &n_bits_total);
+	if (rc) {
+		LOGP(DSCH, LOGL_DEBUG, "Received bad data frame at fn=%u "
+			"(%u/%u) for %s\n", *first_fn,
+			(*first_fn) % ts->mf_layout->period,
+			ts->mf_layout->period,
+			trx_lchan_desc[chan].name);
+		return rc;
+	}
+
+	/* Compose a message to the higher layers */
+	struct l1ctl_info_dl *data;
+	data = talloc_zero_size(ts, sizeof(struct l1ctl_info_dl) + 23);
+	if (data == NULL)
+		return -ENOMEM;
+
+	/* Fill in some downlink info */
+	data->chan_nr = trx_lchan_desc[chan].chan_nr | ts->index;
+	data->link_id = trx_lchan_desc[chan].link_id;
+	data->band_arfcn = htons(trx->band_arfcn);
+	data->frame_nr = htonl(*first_fn);
+	data->rx_level = -(*rssi_sum / *rssi_num);
+
+	/* FIXME: set proper values */
+	data->num_biterr = n_errors;
+	data->fire_crc = 0;
+	data->snr = 0;
+
+	/* Fill in decoded payload */
+	memcpy(data->payload, l2, 23);
+
+	/* Raise an event to trxcon */
+	osmo_fsm_inst_dispatch(trxcon_fsm, SCH_EVENT_DATA, data);
+
+	/* TODO: AGC, TA loops */
+	return 0;
+}
diff --git a/src/host/trxcon/trxcon.c b/src/host/trxcon/trxcon.c
index 6f50d1a..32de253 100644
--- a/src/host/trxcon/trxcon.c
+++ b/src/host/trxcon/trxcon.c
@@ -130,6 +130,8 @@
 	case L1CTL_EVENT_FBSB_REQ:
 		trxcon_handle_fbsb_req((struct l1ctl_fbsb_req *) data);
 		break;
+	case SCH_EVENT_DATA:
+		l1ctl_tx_data_ind(app_data.l1l, (struct l1ctl_info_dl *) data);
 	case TRX_EVENT_RSP_ERROR:
 	case TRX_EVENT_OFFLINE:
 	case SCH_EVENT_CLCK_IND:
@@ -157,7 +159,8 @@
 			GEN_MASK(TRX_EVENT_RSP_ERROR) |
 			GEN_MASK(TRX_EVENT_OFFLINE) |
 			GEN_MASK(SCH_EVENT_CLCK_IND) |
-			GEN_MASK(SCH_EVENT_CLCK_LOSS)),
+			GEN_MASK(SCH_EVENT_CLCK_LOSS) |
+			GEN_MASK(SCH_EVENT_DATA)),
 		.out_state_mask = GEN_MASK(TRXCON_STATE_IDLE),
 		.name = "MANAGED",
 		.action = trxcon_fsm_managed_action,
diff --git a/src/host/trxcon/trxcon.h b/src/host/trxcon/trxcon.h
index c266eae..da777a9 100644
--- a/src/host/trxcon/trxcon.h
+++ b/src/host/trxcon/trxcon.h
@@ -22,4 +22,5 @@
 	/* Scheduler specific events */
 	SCH_EVENT_CLCK_IND,
 	SCH_EVENT_CLCK_LOSS,
+	SCH_EVENT_DATA,
 };

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieb71e3727b525e85d161855973f63042366ccb05
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