[PATCH] osmocom-bb[master]: host/trxcon: initial release of L1CTL handlers

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:32:31 UTC 2018


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

host/trxcon: initial release of L1CTL handlers

Now it's possible to handle the following requests
from layer23 apps:

- L1CTL_FBSB_REQ
- L1CTL_PM_REQ
- L1CTL_RESET_REQ
- L1CTL_ECHO_REQ

It should be noted, that the L1CTL_PM_REQ isn't
handled correctly yet, due to required task isn't
implemented on the TRX side yet. Instead of this,
temporary we are sending some fake responses.

Change-Id: I343eca3e20922ddd83e06231811200b26da442f3
---
M src/host/trxcon/Makefile.am
A src/host/trxcon/l1ctl.c
A src/host/trxcon/l1ctl.h
M src/host/trxcon/l1ctl_link.c
A src/host/trxcon/l1ctl_proto.h
M src/host/trxcon/trxcon.c
M src/host/trxcon/trxcon.h
7 files changed, 290 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/87/6687/1

diff --git a/src/host/trxcon/Makefile.am b/src/host/trxcon/Makefile.am
index 9da2199..869ed8b 100644
--- a/src/host/trxcon/Makefile.am
+++ b/src/host/trxcon/Makefile.am
@@ -22,6 +22,7 @@
 
 trxcon_SOURCES = \
 	l1ctl_link.c \
+	l1ctl.c \
 	trx_if.c \
 	logging.c \
 	trxcon.c \
diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
new file mode 100644
index 0000000..26670f1
--- /dev/null
+++ b/src/host/trxcon/l1ctl.c
@@ -0,0 +1,253 @@
+/*
+ * OsmocomBB <-> SDR connection bridge
+ * GSM L1 control interface handlers
+ *
+ * (C) 2014 by Sylvain Munaut <tnt at 246tNt.com>
+ * (C) 2016-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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+
+#include <arpa/inet.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/select.h>
+#include <osmocom/gsm/gsm_utils.h>
+
+#include "trxcon.h"
+#include "logging.h"
+#include "l1ctl_link.h"
+#include "l1ctl_proto.h"
+
+extern void *tall_trx_ctx;
+extern struct osmo_fsm_inst *trxcon_fsm;
+
+static struct msgb *l1ctl_alloc_msg(uint8_t msg_type)
+{
+	struct l1ctl_hdr *l1h;
+	struct msgb *msg = msgb_alloc_headroom(256, 4, "osmo_l1");
+
+	if (!msg) {
+		LOGP(DL1C, LOGL_ERROR, "Failed to allocate memory\n");
+		return NULL;
+	}
+
+	msg->l1h = msgb_put(msg, sizeof(*l1h));
+	l1h = (struct l1ctl_hdr *) msg->l1h;
+	l1h->msg_type = msg_type;
+
+	return msg;
+}
+
+int l1ctl_tx_pm_conf(struct l1ctl_link *l1l, uint16_t band_arfcn,
+	int dbm, int last)
+{
+	struct l1ctl_pm_conf *pmc;
+	struct msgb *msg;
+
+	msg = l1ctl_alloc_msg(L1CTL_PM_CONF);
+	if (!msg)
+		return -ENOMEM;
+
+	LOGP(DL1C, LOGL_DEBUG, "Send PM Conf (%s %d = %d dBm)\n",
+		gsm_band_name(gsm_arfcn2band(band_arfcn)),
+		band_arfcn &~ ARFCN_FLAG_MASK, dbm);
+
+	pmc = (struct l1ctl_pm_conf *) msgb_put(msg, sizeof(*pmc));
+	pmc->band_arfcn = htons(band_arfcn);
+	pmc->pm[0] = dbm2rxlev(dbm);
+	pmc->pm[1] = 0;
+
+	if (last) {
+		struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->l1h;
+		l1h->flags |= L1CTL_F_DONE;
+	}
+
+	return l1ctl_link_send(l1l, msg);
+}
+
+int l1ctl_tx_reset_ind(struct l1ctl_link *l1l, uint8_t type)
+{
+	struct msgb *msg;
+	struct l1ctl_reset *res;
+
+	msg = l1ctl_alloc_msg(L1CTL_RESET_IND);
+	if (!msg)
+		return -ENOMEM;
+
+	LOGP(DL1C, LOGL_DEBUG, "Send Reset Ind (%u)\n", type);
+
+	res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
+	res->type = type;
+
+	return l1ctl_link_send(l1l, msg);
+}
+
+int l1ctl_tx_reset_conf(struct l1ctl_link *l1l, uint8_t type)
+{
+	struct msgb *msg;
+	struct l1ctl_reset *res;
+
+	msg = l1ctl_alloc_msg(L1CTL_RESET_CONF);
+	if (!msg)
+		return -ENOMEM;
+
+	LOGP(DL1C, LOGL_DEBUG, "Send Reset Conf (%u)\n", type);
+	res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
+	res->type = type;
+
+	return l1ctl_link_send(l1l, msg);
+}
+
+static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+	struct l1ctl_fbsb_req *fbsb;
+	uint16_t band_arfcn;
+	int rc = 0;
+
+	fbsb = (struct l1ctl_fbsb_req *) msg->l1h;
+	if (msgb_l1len(msg) < sizeof(*fbsb)) {
+		LOGP(DL1C, LOGL_ERROR, "MSG too short FBSB Req: %u\n",
+			msgb_l1len(msg));
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	band_arfcn = ntohs(fbsb->band_arfcn);
+
+	LOGP(DL1C, LOGL_DEBUG, "Recv FBSB Req (%s %d)\n",
+		gsm_band_name(gsm_arfcn2band(band_arfcn)),
+		band_arfcn &~ ARFCN_FLAG_MASK);
+
+	osmo_fsm_inst_dispatch(trxcon_fsm,
+		L1CTL_EVENT_FBSB_REQ, &band_arfcn);
+
+exit:
+	msgb_free(msg);
+	return rc;
+}
+
+static int l1ctl_rx_pm_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+	uint16_t arfcn_start, arfcn_stop, arfcn;
+	struct l1ctl_pm_req *pmr;
+	int rc = 0;
+
+	pmr = (struct l1ctl_pm_req *) msg->l1h;
+	if (msgb_l1len(msg) < sizeof(*pmr)) {
+		LOGP(DL1C, LOGL_ERROR, "MSG too short PM Req: %u\n",
+			msgb_l1len(msg));
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	arfcn_start = ntohs(pmr->range.band_arfcn_from);
+	arfcn_stop  = ntohs(pmr->range.band_arfcn_to);
+
+	LOGP(DL1C, LOGL_DEBUG, "Recv PM Req (%s: %d -> %d)\n",
+		gsm_band_name(gsm_arfcn2band(arfcn_start)),
+		arfcn_start &~ ARFCN_FLAG_MASK,
+		arfcn_stop &~ ARFCN_FLAG_MASK);
+
+	/**
+	 * HACK: power measurement isn't implemented yet,
+	 * sending fake results for now...
+	 *
+	 * FIXME: l1ctl_link.c:203 Failed to enqueue msg!
+	 * l1l->wq size is limited to 100, so we cannot
+	 * put more messages until osmo_select_main()
+	 * is called.
+	 */
+	for (arfcn = arfcn_start; arfcn <= arfcn_stop; arfcn++)
+		l1ctl_tx_pm_conf(l1l, arfcn, arfcn == 33 ?
+			-60 : -120, arfcn == arfcn_stop);
+
+exit:
+	msgb_free(msg);
+	return rc;
+}
+
+static int l1ctl_rx_reset_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+	struct l1ctl_reset *res;
+	int rc = 0;
+
+	res = (struct l1ctl_reset *) msg->l1h;
+	if (msgb_l1len(msg) < sizeof(*res)) {
+		LOGP(DL1C, LOGL_ERROR, "MSG too short Reset Req: %u\n",
+			msgb_l1len(msg));
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	LOGP(DL1C, LOGL_DEBUG, "Recv Reset Req (%u)\n", res->type);
+
+	osmo_fsm_inst_dispatch(trxcon_fsm,
+		L1CTL_EVENT_RESET_REQ, res);
+
+exit:
+	msgb_free(msg);
+	return rc;
+}
+
+static int l1ctl_rx_echo_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+	struct l1ctl_hdr *l1h;
+
+	LOGP(DL1C, LOGL_NOTICE, "Recv Echo Req\n");
+	LOGP(DL1C, LOGL_NOTICE, "Send Echo Conf\n");
+
+	/* Nothing to do, just send it back */
+	l1h = (struct l1ctl_hdr *) msg->l1h;
+	l1h->msg_type = L1CTL_ECHO_CONF;
+	msg->data = msg->l1h;
+
+	return l1ctl_link_send(l1l, msg);
+}
+
+int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
+{
+	struct l1ctl_hdr *l1h;
+
+	l1h = (struct l1ctl_hdr *) msg->l1h;
+	msg->l1h = l1h->data;
+
+	switch (l1h->msg_type) {
+	case L1CTL_FBSB_REQ:
+		return l1ctl_rx_fbsb_req(l1l, msg);
+	case L1CTL_PM_REQ:
+		return l1ctl_rx_pm_req(l1l, msg);
+	case L1CTL_RESET_REQ:
+		return l1ctl_rx_reset_req(l1l, msg);
+	case L1CTL_ECHO_REQ:
+		return l1ctl_rx_echo_req(l1l, msg);
+	default:
+		LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", l1h->msg_type);
+		msgb_free(msg);
+		return -EINVAL;
+	}
+}
diff --git a/src/host/trxcon/l1ctl.h b/src/host/trxcon/l1ctl.h
new file mode 100644
index 0000000..ffd1a81
--- /dev/null
+++ b/src/host/trxcon/l1ctl.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <stdint.h>
+#include <osmocom/core/msgb.h>
+
+#include "l1ctl_link.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);
diff --git a/src/host/trxcon/l1ctl_link.c b/src/host/trxcon/l1ctl_link.c
index 34aa4aa..d2ceb17 100644
--- a/src/host/trxcon/l1ctl_link.c
+++ b/src/host/trxcon/l1ctl_link.c
@@ -43,6 +43,7 @@
 #include "trxcon.h"
 #include "logging.h"
 #include "l1ctl_link.h"
+#include "l1ctl.h"
 
 extern void *tall_trx_ctx;
 extern struct osmo_fsm_inst *trxcon_fsm;
@@ -112,8 +113,8 @@
 	LOGP(DL1C, LOGL_DEBUG, "RX: '%s'\n",
 		osmo_hexdump(msg->data, msg->len));
 
-	/* TODO: call L1CTL handler here */
-	msgb_free(msg);
+	/* Call L1CTL handler */
+	l1ctl_rx_cb(l1l, msg);
 
 	return 0;
 }
diff --git a/src/host/trxcon/l1ctl_proto.h b/src/host/trxcon/l1ctl_proto.h
new file mode 120000
index 0000000..75862ba
--- /dev/null
+++ b/src/host/trxcon/l1ctl_proto.h
@@ -0,0 +1 @@
+../../../include/l1ctl_proto.h
\ No newline at end of file
diff --git a/src/host/trxcon/trxcon.c b/src/host/trxcon/trxcon.c
index 5874560..a90d038 100644
--- a/src/host/trxcon/trxcon.c
+++ b/src/host/trxcon/trxcon.c
@@ -39,7 +39,9 @@
 #include "trxcon.h"
 #include "trx_if.h"
 #include "logging.h"
+#include "l1ctl.h"
 #include "l1ctl_link.h"
+#include "l1ctl_proto.h"
 
 #define COPYRIGHT \
 	"Copyright (C) 2016-2017 by Vadim Yanitskiy <axilirator at gmail.com>\n" \
@@ -76,6 +78,8 @@
 static void trxcon_fsm_managed_action(struct osmo_fsm_inst *fi,
 	uint32_t event, void *data)
 {
+	uint16_t *band_arfcn;
+
 	switch (event) {
 	case L1CTL_EVENT_DISCONNECT:
 		osmo_fsm_inst_state_chg(trxcon_fsm, TRXCON_STATE_IDLE, 0, 0);
@@ -85,7 +89,19 @@
 			trx_if_cmd_poweroff(app_data.trx);
 		}
 		break;
+	case L1CTL_EVENT_RESET_REQ:
+		trx_if_cmd_echo(app_data.trx);
+		break;
 	case TRX_EVENT_RESET_IND:
+		/* TODO: send proper reset type */
+		l1ctl_tx_reset_conf(app_data.l1l, L1CTL_RES_T_BOOT);
+		break;
+	case L1CTL_EVENT_FBSB_REQ:
+		band_arfcn = (uint16_t *) data;
+		trx_if_cmd_rxtune(app_data.trx, *band_arfcn);
+		trx_if_cmd_txtune(app_data.trx, *band_arfcn);
+		trx_if_cmd_poweron(app_data.trx);
+		break;
 	case TRX_EVENT_RSP_ERROR:
 	case TRX_EVENT_OFFLINE:
 		/* TODO: notify L2 & L3 about that */
@@ -105,6 +121,8 @@
 	[TRXCON_STATE_MANAGED] = {
 		.in_event_mask = (
 			GEN_MASK(L1CTL_EVENT_DISCONNECT) |
+			GEN_MASK(L1CTL_EVENT_FBSB_REQ) |
+			GEN_MASK(L1CTL_EVENT_RESET_REQ) |
 			GEN_MASK(TRX_EVENT_RESET_IND) |
 			GEN_MASK(TRX_EVENT_RSP_ERROR) |
 			GEN_MASK(TRX_EVENT_OFFLINE)),
diff --git a/src/host/trxcon/trxcon.h b/src/host/trxcon/trxcon.h
index a7a3a65..9535578 100644
--- a/src/host/trxcon/trxcon.h
+++ b/src/host/trxcon/trxcon.h
@@ -11,6 +11,8 @@
 	/* L1CTL specific events */
 	L1CTL_EVENT_CONNECT,
 	L1CTL_EVENT_DISCONNECT,
+	L1CTL_EVENT_FBSB_REQ,
+	L1CTL_EVENT_RESET_REQ,
 
 	/* TRX specific events */
 	TRX_EVENT_RESET_IND,

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

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