aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2024-03-02 19:42:17 +0100
committerHarald Welte <laforge@osmocom.org>2024-03-02 19:42:17 +0100
commit2d462bba670d5706fbc41c629b2edeb98558f247 (patch)
tree64dfee09049aec83e19fa06f631cbc9aa0ba8e06
parent319a77e519bb2e7ba086290d5ed57af2c097a725 (diff)
WIP: port ctrl over to osmo_iolaforge/ctrl_osmo_io
This is more difficult than expected, let's not proceed further Change-Id: I75d0ab2bf9ce08a0213daf1112e784984bd505e0
-rw-r--r--include/osmocom/ctrl/control_cmd.h13
-rw-r--r--src/ctrl/control_if.c115
2 files changed, 58 insertions, 70 deletions
diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h
index 64227107..4430a7eb 100644
--- a/include/osmocom/ctrl/control_cmd.h
+++ b/include/osmocom/ctrl/control_cmd.h
@@ -4,6 +4,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/osmo_io.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
@@ -45,9 +46,15 @@ extern const struct value_string ctrl_type_vals[];
/*! Represents a single ctrl connection */
struct ctrl_connection {
struct llist_head list_entry;
-
- /*! The queue for sending data back */
- struct osmo_wqueue write_queue;
+ /*! back-pointer to parent ctrl_handle */
+ struct ctrl_handle *ctrl;
+
+ union {
+ /*! The io_fd for sending data back */
+ struct osmo_io_fd *iofd;
+ /* backwards-compatibility (ctrl_cmd_send) */
+ struct osmo_wqueue write_queue;
+ };
/*! Buffer for partial input data */
struct msgb *pending_msg;
diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c
index c265c3a9..8795380d 100644
--- a/src/ctrl/control_if.c
+++ b/src/ctrl/control_if.c
@@ -3,7 +3,7 @@
/*
* (C) 2010-2011 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2010-2011 by On-Waves
- * (C) 2014 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2014-2024 by Harald Welte <laforge@gnumonks.org>
* (C) 2016-2017 by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
@@ -56,6 +56,7 @@
#include <osmocom/core/counter.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/socket.h>
+#include <osmocom/core/osmo_io.h>
#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmocom/gsm/ipa.h>
@@ -140,7 +141,7 @@ int ctrl_cmd_send2(struct ctrl_connection *ccon, struct ctrl_cmd *cmd)
ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_CTRL);
ipa_prepend_header(msg, IPAC_PROTO_OSMO);
- ret = osmo_wqueue_enqueue(&ccon->write_queue, msg);
+ ret = osmo_iofd_write_msgb(ccon->iofd, msg);
if (ret != 0) {
LOGP(DLCTRL, LOGL_ERROR, "Failed to enqueue the command.\n");
msgb_free(msg);
@@ -188,14 +189,12 @@ struct ctrl_cmd *ctrl_cmd_trap(struct ctrl_cmd *cmd)
static void control_close_conn(struct ctrl_connection *ccon)
{
struct ctrl_cmd_def *cd, *cd2;
- char *name = osmo_sock_get_name(ccon, ccon->write_queue.bfd.fd);
- LOGP(DLCTRL, LOGL_INFO, "close()d CTRL connection %s\n", name);
- talloc_free(name);
+ LOGP(DLCTRL, LOGL_INFO, "close()d CTRL connection %s\n", osmo_iofd_get_name(ccon->iofd));
+
+ osmo_iofd_free(ccon->iofd);
+ ccon->iofd = NULL;
- osmo_wqueue_clear(&ccon->write_queue);
- close(ccon->write_queue.bfd.fd);
- osmo_fd_unregister(&ccon->write_queue.bfd);
llist_del(&ccon->list_entry);
if (ccon->closed_cb)
ccon->closed_cb(ccon);
@@ -349,40 +348,28 @@ err:
}
-static int handle_control_read(struct osmo_fd * bfd)
+static void control_read_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg)
{
+ struct ctrl_connection *ccon = osmo_iofd_get_data(iofd);
int ret;
- struct osmo_wqueue *queue;
- struct ctrl_connection *ccon;
- struct msgb *msg = NULL;
- struct ctrl_handle *ctrl = bfd->data;
- queue = container_of(bfd, struct osmo_wqueue, bfd);
- ccon = container_of(queue, struct ctrl_connection, write_queue);
-
- ret = ipa_msg_recv_buffered(bfd->fd, &msg, &ccon->pending_msg);
- if (ret == 0) {
+ if (res == 0) {
/* msg was already discarded. */
- goto close_fd;
- } else if (ret == -EAGAIN) {
+ control_close_conn(ccon);
+ return;
+ } else if (res == -EAGAIN) {
/* received part of a message, it is stored in ccon->pending_msg and there's
* nothing left to do now. */
- return 0;
- } else if (ret < 0) {
+ return;
+ } else if (res < 0) {
LOGP(DLCTRL, LOGL_ERROR, "Failed to parse ip access message: %d (%s)\n", ret, strerror(-ret));
- return 0;
+ return;
}
- ret = ctrl_handle_msg(ctrl, ccon, msg);
+ ret = ctrl_handle_msg(ccon->ctrl, ccon, msg);
msgb_free(msg);
if (ret)
- goto close_fd;
-
- return 0;
-
-close_fd:
- control_close_conn(ccon);
- return -EBADF;
+ control_close_conn(ccon);
}
/*! Handle a received CTRL command contained in a \ref msgb.
@@ -480,32 +467,25 @@ just_free:
return 0;
}
-static int control_write_cb(struct osmo_fd *bfd, struct msgb *msg)
+static void control_write_cb(struct osmo_io_fd *iofd, int rc, struct msgb *msg)
{
- struct osmo_wqueue *queue;
- struct ctrl_connection *ccon;
- int rc;
-
- queue = container_of(bfd, struct osmo_wqueue, bfd);
- ccon = container_of(queue, struct ctrl_connection, write_queue);
+ struct ctrl_connection *ccon = osmo_iofd_get_data(iofd);
- rc = write(bfd->fd, msg->data, msg->len);
if (rc == 0) {
control_close_conn(ccon);
- return -EBADF;
- }
- if (rc < 0) {
+ } else if (rc < 0) {
LOGP(DLCTRL, LOGL_ERROR, "Failed to write message to the CTRL connection.\n");
- return 0;
- }
- if (rc < msg->len) {
- msgb_pull(msg, rc);
- return -EAGAIN;
}
- return 0;
+ msgb_free(msg);
}
+static const struct osmo_io_ops ctrl_srv_ioops = {
+ .read_cb = control_read_cb,
+ .write_cb = control_write_cb,
+ .segmentation_cb = FIXME_osmo_ipa_segmentation_cb,
+};
+
/*! Allocate CTRL connection
* \param[in] ctx Context from which talloc should allocate it
* \param[in] data caller's private data parameter which should assigned to
@@ -518,17 +498,10 @@ struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data)
if (!ccon)
return NULL;
- osmo_wqueue_init(&ccon->write_queue, 100);
- /* Error handling here? */
-
+ ccon->ctrl = (struct ctrl_handle *) data;
INIT_LLIST_HEAD(&ccon->cmds);
INIT_LLIST_HEAD(&ccon->def_cmds);
- ccon->write_queue.bfd.data = data;
- ccon->write_queue.bfd.fd = -1;
- ccon->write_queue.write_cb = control_write_cb;
- ccon->write_queue.read_cb = handle_control_read;
-
return ccon;
}
@@ -562,26 +535,34 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
ccon = osmo_ctrl_conn_alloc(listen_bfd->data, ctrl);
if (!ccon) {
LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate.\n");
- close(fd);
- return -1;
+ goto out_close;
}
name = osmo_sock_get_name(ccon, fd);
- LOGP(DLCTRL, LOGL_INFO, "accept()ed new CTRL connection from %s\n", name);
+ ccon->iofd = osmo_iofd_setup(ccon, fd, name, OSMO_IO_FD_MODE_READ_WRITE, &ctrl_srv_ioops, ccon);
+ if (!ccon->iofd)
+ goto out_free_ccon;
- ccon->write_queue.bfd.fd = fd;
- ccon->write_queue.bfd.when = OSMO_FD_READ;
+ ret = osmo_iofd_register(ccon->iofd, -1);
+ if (ret < 0)
+ goto out_free_iofd;
- ret = osmo_fd_register(&ccon->write_queue.bfd);
- if (ret < 0) {
- LOGP(DLCTRL, LOGL_ERROR, "Could not register FD.\n");
- close(ccon->write_queue.bfd.fd);
- talloc_free(ccon);
- }
+ osmo_iofd_set_alloc_info(ccon->iofd, 1024, 0);
+ osmo_iofd_set_txqueue_max_length(ccon->iofd, 100);
+
+ LOGP(DLCTRL, LOGL_INFO, "accept()ed new CTRL connection from %s\n", name);
llist_add(&ccon->list_entry, &ctrl->ccon_list);
return ret;
+
+out_free_iofd:
+ osmo_iofd_free(ccon->iofd);
+out_free_ccon:
+ talloc_free(ccon);
+out_close:
+ close(fd);
+ return -1;
}
static uint64_t get_rate_ctr_value(const struct rate_ctr *ctr, int intv, const char *grp)