summaryrefslogtreecommitdiffstats
path: root/src/host/trxcon/l1ctl_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/trxcon/l1ctl_link.c')
-rw-r--r--src/host/trxcon/l1ctl_link.c319
1 files changed, 0 insertions, 319 deletions
diff --git a/src/host/trxcon/l1ctl_link.c b/src/host/trxcon/l1ctl_link.c
deleted file mode 100644
index b7ea262a..00000000
--- a/src/host/trxcon/l1ctl_link.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * OsmocomBB <-> SDR connection bridge
- * GSM L1 control socket (/tmp/osmocom_l2) handlers
- *
- * (C) 2013 by Sylvain Munaut <tnt@246tNt.com>
- * (C) 2016-2017 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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <sys/un.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <osmocom/core/fsm.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/socket.h>
-#include <osmocom/core/write_queue.h>
-
-#include "trxcon.h"
-#include "logging.h"
-#include "l1ctl_link.h"
-#include "l1ctl.h"
-
-static struct value_string l1ctl_evt_names[] = {
- { 0, NULL } /* no events? */
-};
-
-static struct osmo_fsm_state l1ctl_fsm_states[] = {
- [L1CTL_STATE_IDLE] = {
- .out_state_mask = GEN_MASK(L1CTL_STATE_CONNECTED),
- .name = "IDLE",
- },
- [L1CTL_STATE_CONNECTED] = {
- .out_state_mask = GEN_MASK(L1CTL_STATE_IDLE),
- .name = "CONNECTED",
- },
-};
-
-static struct osmo_fsm l1ctl_fsm = {
- .name = "l1ctl_link_fsm",
- .states = l1ctl_fsm_states,
- .num_states = ARRAY_SIZE(l1ctl_fsm_states),
- .log_subsys = DL1C,
- .event_names = l1ctl_evt_names,
-};
-
-static int l1ctl_link_read_cb(struct osmo_fd *bfd)
-{
- struct l1ctl_link *l1l = (struct l1ctl_link *) bfd->data;
- struct msgb *msg;
- uint16_t len;
- int rc;
-
- /* Attempt to read from socket */
- rc = read(bfd->fd, &len, L1CTL_MSG_LEN_FIELD);
- if (rc < L1CTL_MSG_LEN_FIELD) {
- LOGP(DL1D, LOGL_NOTICE, "L1CTL has lost connection\n");
- if (rc >= 0)
- rc = -EIO;
- l1ctl_link_close_conn(l1l);
- return rc;
- }
-
- /* Check message length */
- len = ntohs(len);
- if (len > L1CTL_LENGTH) {
- LOGP(DL1D, LOGL_ERROR, "Length is too big: %u\n", len);
- return -EINVAL;
- }
-
- /* Allocate a new msg */
- msg = msgb_alloc_headroom(L1CTL_LENGTH + L1CTL_HEADROOM,
- L1CTL_HEADROOM, "l1ctl_rx_msg");
- if (!msg) {
- LOGP(DL1D, LOGL_ERROR, "Failed to allocate msg\n");
- return -ENOMEM;
- }
-
- msg->l1h = msgb_put(msg, len);
- rc = read(bfd->fd, msg->l1h, msgb_l1len(msg));
- if (rc != len) {
- LOGP(DL1D, LOGL_ERROR, "Can not read data: len=%d < rc=%d: "
- "%s\n", len, rc, strerror(errno));
- msgb_free(msg);
- return rc;
- }
-
- /* Debug print */
- LOGP(DL1D, LOGL_DEBUG, "RX: '%s'\n",
- osmo_hexdump(msg->data, msg->len));
-
- /* Call L1CTL handler */
- l1ctl_rx_cb(l1l, msg);
-
- return 0;
-}
-
-static int l1ctl_link_write_cb(struct osmo_fd *bfd, struct msgb *msg)
-{
- int len;
-
- if (bfd->fd <= 0)
- return -EINVAL;
-
- len = write(bfd->fd, msg->data, msg->len);
- if (len != msg->len) {
- LOGP(DL1D, LOGL_ERROR, "Failed to write data: "
- "written (%d) < msg_len (%d)\n", len, msg->len);
- return -1;
- }
-
- return 0;
-}
-
-/* Connection handler */
-static int l1ctl_link_accept(struct osmo_fd *bfd, unsigned int flags)
-{
- struct l1ctl_link *l1l = (struct l1ctl_link *) bfd->data;
- struct osmo_fd *conn_bfd = &l1l->wq.bfd;
- struct sockaddr_un un_addr;
- socklen_t len;
- int cfd;
-
- len = sizeof(un_addr);
- cfd = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
- if (cfd < 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to accept a new connection\n");
- return -1;
- }
-
- /* Check if we already have an active connection */
- if (conn_bfd->fd != -1) {
- LOGP(DL1C, LOGL_NOTICE, "A new connection rejected: "
- "we already have another active\n");
- close(cfd);
- return 0;
- }
-
- osmo_wqueue_init(&l1l->wq, 100);
- INIT_LLIST_HEAD(&conn_bfd->list);
-
- l1l->wq.write_cb = l1ctl_link_write_cb;
- l1l->wq.read_cb = l1ctl_link_read_cb;
- conn_bfd->when = BSC_FD_READ;
- conn_bfd->data = l1l;
- conn_bfd->fd = cfd;
-
- if (osmo_fd_register(conn_bfd) != 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to register new connection fd\n");
- close(conn_bfd->fd);
- conn_bfd->fd = -1;
- return -1;
- }
-
- osmo_fsm_inst_dispatch(trxcon_fsm, L1CTL_EVENT_CONNECT, l1l);
- osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_CONNECTED, 0, 0);
-
- LOGP(DL1C, LOGL_NOTICE, "L1CTL has a new connection\n");
-
- return 0;
-}
-
-int l1ctl_link_send(struct l1ctl_link *l1l, struct msgb *msg)
-{
- uint16_t *len;
-
- /* Debug print */
- LOGP(DL1D, LOGL_DEBUG, "TX: '%s'\n",
- osmo_hexdump(msg->data, msg->len));
-
- if (msg->l1h != msg->data)
- LOGP(DL1D, LOGL_INFO, "Message L1 header != Message Data\n");
-
- /* Prepend 16-bit length before sending */
- len = (uint16_t *) msgb_push(msg, L1CTL_MSG_LEN_FIELD);
- *len = htons(msg->len - L1CTL_MSG_LEN_FIELD);
-
- if (osmo_wqueue_enqueue(&l1l->wq, msg) != 0) {
- LOGP(DL1D, LOGL_ERROR, "Failed to enqueue msg!\n");
- msgb_free(msg);
- return -EIO;
- }
-
- return 0;
-}
-
-int l1ctl_link_close_conn(struct l1ctl_link *l1l)
-{
- struct osmo_fd *conn_bfd = &l1l->wq.bfd;
-
- if (conn_bfd->fd <= 0)
- return -EINVAL;
-
- /* Close connection socket */
- osmo_fd_unregister(conn_bfd);
- close(conn_bfd->fd);
- conn_bfd->fd = -1;
-
- /* Clear pending messages */
- osmo_wqueue_clear(&l1l->wq);
-
- osmo_fsm_inst_dispatch(trxcon_fsm, L1CTL_EVENT_DISCONNECT, l1l);
- osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_IDLE, 0, 0);
-
- return 0;
-}
-
-struct l1ctl_link *l1ctl_link_init(void *tall_ctx, const char *sock_path)
-{
- struct l1ctl_link *l1l;
- struct osmo_fd *bfd;
- int rc;
-
- LOGP(DL1C, LOGL_NOTICE, "Init L1CTL link (%s)\n", sock_path);
-
- l1l = talloc_zero(tall_ctx, struct l1ctl_link);
- if (!l1l) {
- LOGP(DL1C, LOGL_ERROR, "Failed to allocate memory\n");
- return NULL;
- }
-
- /* Allocate a new dedicated state machine */
- l1l->fsm = osmo_fsm_inst_alloc(&l1ctl_fsm, l1l,
- NULL, LOGL_DEBUG, "l1ctl_link");
- if (l1l->fsm == NULL) {
- LOGP(DTRX, LOGL_ERROR, "Failed to allocate an instance "
- "of FSM '%s'\n", l1ctl_fsm.name);
- talloc_free(l1l);
- return NULL;
- }
-
- /* Create a socket and bind handlers */
- bfd = &l1l->listen_bfd;
- rc = osmo_sock_unix_init_ofd(bfd, SOCK_STREAM, 0, sock_path,
- OSMO_SOCK_F_BIND);
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "Could not create UNIX socket: %s\n",
- strerror(errno));
- osmo_fsm_inst_free(l1l->fsm);
- talloc_free(l1l);
- return NULL;
- }
-
- /* Bind shutdown handler */
- l1l->shutdown_cb = l1ctl_shutdown_cb;
-
- /* Bind connection handler */
- bfd->cb = l1ctl_link_accept;
- bfd->when = BSC_FD_READ;
- bfd->data = l1l;
-
- /**
- * To be able to accept first connection and
- * drop others, it should be set to -1
- */
- l1l->wq.bfd.fd = -1;
-
- return l1l;
-}
-
-void l1ctl_link_shutdown(struct l1ctl_link *l1l)
-{
- struct osmo_fd *listen_bfd;
-
- /* May be unallocated due to init error */
- if (!l1l)
- return;
-
- LOGP(DL1C, LOGL_NOTICE, "Shutdown L1CTL link\n");
-
- /* Call shutdown callback */
- if (l1l->shutdown_cb != NULL)
- l1l->shutdown_cb(l1l);
-
- listen_bfd = &l1l->listen_bfd;
-
- /* Check if we have an established connection */
- if (l1l->wq.bfd.fd != -1)
- l1ctl_link_close_conn(l1l);
-
- /* Unbind listening socket */
- if (listen_bfd->fd != -1) {
- osmo_fd_unregister(listen_bfd);
- close(listen_bfd->fd);
- listen_bfd->fd = -1;
- }
-
- osmo_fsm_inst_free(l1l->fsm);
- talloc_free(l1l);
-}
-
-static __attribute__((constructor)) void on_dso_load(void)
-{
- OSMO_ASSERT(osmo_fsm_register(&l1ctl_fsm) == 0);
-}