summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/trxcon/Makefile.am1
-rw-r--r--src/host/trxcon/l1ctl.c37
-rw-r--r--src/host/trxcon/phy_info.c92
3 files changed, 129 insertions, 1 deletions
diff --git a/src/host/trxcon/Makefile.am b/src/host/trxcon/Makefile.am
index b51db02f..2a472ce5 100644
--- a/src/host/trxcon/Makefile.am
+++ b/src/host/trxcon/Makefile.am
@@ -27,6 +27,7 @@ trxcon_SOURCES = \
trx_if.c \
logging.c \
trxcon.c \
+ phy_info.c \
$(NULL)
# Scheduler
diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index 83cdc2e4..1b5985b2 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -3,7 +3,7 @@
* GSM L1 control interface handlers
*
* (C) 2014 by Sylvain Munaut <tnt@246tNt.com>
- * (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2016-2018 by Vadim Yanitskiy <axilirator@gmail.com>
*
* All Rights Reserved
*
@@ -778,6 +778,39 @@ exit:
return rc;
}
+/* Forward-declaration of the actual implementation */
+int trxcon_compose_phy_info(struct msgb *msg);
+
+static int l1ctl_rx_nego_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+ struct msgb *info_msg;
+ int rc;
+
+ LOGP(DL1C, LOGL_NOTICE, "PHY info / features negotiation\n");
+
+ /**
+ * In the future the higher layers may also send some
+ * information within negotiation request, so we don't
+ * abuse this message (by changing its type),
+ * and allocate a new one.
+ */
+ msgb_free(msg);
+
+ info_msg = l1ctl_alloc_msg(L1CTL_PHY_NEGO_IND);
+ if (info_msg == NULL)
+ return -ENOMEM;
+
+ rc = trxcon_compose_phy_info(info_msg);
+ if (rc)
+ goto exit_free;
+
+ return l1ctl_link_send(l1l, info_msg);
+
+exit_free:
+ msgb_free(info_msg);
+ return rc;
+}
+
int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
{
struct l1ctl_hdr *l1h;
@@ -812,6 +845,8 @@ int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
return l1ctl_rx_tch_mode_req(l1l, msg);
case L1CTL_CRYPTO_REQ:
return l1ctl_rx_crypto_req(l1l, msg);
+ case L1CTL_PHY_NEGO_REQ:
+ return l1ctl_rx_nego_req(l1l, msg);
/* Not (yet) handled messages */
case L1CTL_NEIGH_PM_REQ:
diff --git a/src/host/trxcon/phy_info.c b/src/host/trxcon/phy_info.c
new file mode 100644
index 00000000..2b73c82d
--- /dev/null
+++ b/src/host/trxcon/phy_info.c
@@ -0,0 +1,92 @@
+/*
+ * L1CTL PHY info / features negotiation
+ *
+ * (C) 2018 by Vadim Yanitskiy <axilirator@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 <stdint.h>
+
+#include <arpa/inet.h>
+
+#include <osmocom/core/negotiation.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+
+#include "l1ctl_proto.h"
+
+static const struct value_string phy_info[] = {
+ {L1CTL_PHY_INFO_NAME, "trxcon"},
+ { 0, NULL }
+};
+
+int trxcon_compose_phy_info(struct msgb *msg)
+{
+ struct l1ctl_phy_nego_ind *hdr;
+ uint8_t *features_tlv;
+ int rc;
+
+ /* Header first */
+ hdr = (struct l1ctl_phy_nego_ind *) msgb_put(msg, sizeof(*hdr));
+ if (!hdr)
+ return -ENOMEM;
+
+ /* Encode basic PHY info */
+ rc = osmo_nego_enc_info(msg, phy_info);
+ if (rc < (ARRAY_SIZE(phy_info) - 1))
+ return -EINVAL;
+
+ /* PHY features TLV, length will be set latter */
+ features_tlv = msgb_put(msg, 2);
+ if (!features_tlv)
+ return -ENOMEM;
+
+ /* Frequency band support */
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_BAND_400);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_BAND_850);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_BAND_900);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_BAND_DCS);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_BAND_PCS);
+
+ /* Channel coding support */
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_CHAN_XCCH);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_CHAN_TCHF);
+
+ /* Voice codecs support */
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_CODEC_FR);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_CODEC_EFR);
+
+ /* A5/X ciphering support */
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_A5_1);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_A5_2);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_A5_3);
+
+ /* Other features */
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_TX);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_PM);
+ osmo_nego_add_feature(msg, L1CTL_PHY_FEATURE_TRAFFIC);
+
+ /* Finally, compute the length fields */
+ features_tlv[0] = L1CTL_PHY_INFO_FEATURES;
+ features_tlv[1] = msg->tail - features_tlv - 2;
+ hdr->len = htons(msg->tail - hdr->data);
+
+ return 0;
+}