<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-netif/+/26426">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Introduce osmo_prim_srv APIs<br><br>This new module allows easy exchange of osmo_prim based data types over<br>IPC communication (UD socket supported only so far), by replacing the<br>osmo_prim_hdr struct with a serialized header when submitting/receiving<br>it from the IPC socket.<br><br>This patch introduces the server side of the UD socket, but the client<br>side can easily be introduced in the same file whenever needed.<br><br>Related: SYS#5516<br>Change-Id: I7cab15ac092e45a256c4f0bab11b3962df861044<br>---<br>M TODO-RELEASE<br>M include/osmocom/netif/Makefile.am<br>A include/osmocom/netif/prim.h<br>M src/Makefile.am<br>A src/prim.c<br>5 files changed, 409 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index 1c9a2a6..b146231 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -8,3 +8,4 @@</span><br><span> # If any interfaces have been removed or changed since the last public release: c:r:0.</span><br><span> #library     what            description / commit summary line</span><br><span> sctp.h          new APIs</span><br><span style="color: hsl(120, 100%, 40%);">+prim.h          new data type, APIs</span><br><span>diff --git a/include/osmocom/netif/Makefile.am b/include/osmocom/netif/Makefile.am</span><br><span>index d9d030b..92712a9 100644</span><br><span>--- a/include/osmocom/netif/Makefile.am</span><br><span>+++ b/include/osmocom/netif/Makefile.am</span><br><span>@@ -4,6 +4,7 @@</span><br><span>                    osmux.h             \</span><br><span>                ipa.h               \</span><br><span>                ipa_unit.h          \</span><br><span style="color: hsl(120, 100%, 40%);">+                 prim.h              \</span><br><span>                rs232.h             \</span><br><span>                rtp.h               \</span><br><span>                stream.h</span><br><span>diff --git a/include/osmocom/netif/prim.h b/include/osmocom/netif/prim.h</span><br><span>new file mode 100644</span><br><span>index 0000000..4f17622</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/netif/prim.h</span><br><span>@@ -0,0 +1,54 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/prim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link;</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int (*osmo_prim_srv_conn_cb)(struct osmo_prim_srv *prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+/*! oph and related msgb is owned by srv and wll be freed after the callback returns. */</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int (*osmo_prim_srv_rx_cb)(struct osmo_prim_srv *prim_srv, struct osmo_prim_hdr *oph);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_hdr *osmo_prim_msgb_alloc(unsigned int sap, unsigned int primitive,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        enum osmo_prim_operation operation, size_t alloc_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link *osmo_prim_srv_link_alloc(void *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_free(struct osmo_prim_srv_link *prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_link_set_addr(struct osmo_prim_srv_link *prim_link, const char *path);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_prim_srv_link_get_addr(struct osmo_prim_srv_link *prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_priv(struct osmo_prim_srv_link *prim_link, void *priv);</span><br><span style="color: hsl(120, 100%, 40%);">+void *osmo_prim_srv_link_get_priv(const struct osmo_prim_srv_link *prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_opened_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb opened_conn_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_closed_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb closed_conn_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_rx_msgb_alloc_len(struct osmo_prim_srv_link *prim_link, size_t alloc_len);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_send(struct osmo_prim_srv *prim_srv, struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link *osmo_prim_srv_get_link(struct osmo_prim_srv *prims_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_set_priv(struct osmo_prim_srv *prim_srv, void *priv);</span><br><span style="color: hsl(120, 100%, 40%);">+void *osmo_prim_srv_get_priv(const struct osmo_prim_srv *prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_close(struct osmo_prim_srv *prim_srv);</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 438b58e..5c23896 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -17,6 +17,7 @@</span><br><span>                      ipa_unit.c            \</span><br><span>                      jibuf.c               \</span><br><span>                      osmux.c               \</span><br><span style="color: hsl(120, 100%, 40%);">+                       prim.c                \</span><br><span>                      rs232.c               \</span><br><span>                      rtp.c                 \</span><br><span>                      stream.c</span><br><span>diff --git a/src/prim.c b/src/prim.c</span><br><span>new file mode 100644</span><br><span>index 0000000..6c6da6e</span><br><span>--- /dev/null</span><br><span>+++ b/src/prim.c</span><br><span>@@ -0,0 +1,352 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/un.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/netif/prim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/netif/stream.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_pkt_hdr {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t sap;    /*!< Service Access Point Identifier */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t primitive;    /*!< Primitive number */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t operation; /*! Primitive Operation (enum osmo_prim_operation) */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Here we take advantage of the fact that sizeof(struct</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_prim_pkt_hdr) <= sizeof(struct osmo_prim_hdr), so we don't need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to allocate headroom when serializing later.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_static_assert(sizeof(struct osmo_prim_pkt_hdr) <= sizeof(struct osmo_prim_hdr),</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_prim_msgb_alloc_validate_headroom);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Allocate a primitive of given type and its associated msgb.</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] sap Service Access Point</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] primitive Primitive Number</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] operation Primitive Operation (REQ/RESP/IND/CONF)</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] alloc_len Total length (including struct osmo_prim_hdr) to allocate for the primitive</span><br><span style="color: hsl(120, 100%, 40%);">+*  \returns Pointer to allocated prim_hdr inisde its own msgb. The osmo_prim_hdr</span><br><span style="color: hsl(120, 100%, 40%);">+*         is pre-alocated & pre-filled.</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_hdr *osmo_prim_msgb_alloc(unsigned int sap, unsigned int primitive,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         enum osmo_prim_operation operation, size_t alloc_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_prim_hdr *oph;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (alloc_len < sizeof(*oph))</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        msg = msgb_alloc(alloc_len, "osmo_prim_msgb_alloc");</span><br><span style="color: hsl(120, 100%, 40%);">+        oph = (struct osmo_prim_hdr *)msgb_put(msg, sizeof(*oph));</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_prim_init(oph, sap, primitive, operation, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  msg->l2h = msg->tail;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return oph;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link {</span><br><span style="color: hsl(120, 100%, 40%);">+ void *priv;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+   int log_cat; /* Defaults to DLGLOBAL */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_stream_srv_link *stream;</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_prim_srv_conn_cb opened_conn_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_prim_srv_conn_cb closed_conn_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_prim_srv_rx_cb rx_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t rx_msgb_alloc_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv {</span><br><span style="color: hsl(120, 100%, 40%);">+       void *priv;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_prim_srv_link *link; /* backpointer */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_stream_srv *stream;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/******************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_prim_srv</span><br><span style="color: hsl(120, 100%, 40%);">+ ******************************/</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGSRV(srv, lvl, fmt, args...) LOGP((srv)->link->log_cat, lvl, fmt, ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int _osmo_prim_srv_read_cb(struct osmo_stream_srv *srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_prim_srv *prim_srv = osmo_stream_srv_get_data(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_prim_pkt_hdr *pkth;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_prim_hdr oph;</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msg = msgb_alloc_c(prim_srv, sizeof(*pkth) + prim_srv->link->rx_msgb_alloc_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "osmo_prim_srv_link_rx");</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = osmo_stream_srv_recv(srv, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          goto close;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (errno == EAGAIN) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             goto close;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc < sizeof(*pkth)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGSRV(prim_srv, LOGL_ERROR, "Received %d bytes on UD Socket, but primitive hdr size "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "is %zu, discarding\n", rc, sizeof(*pkth));</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     pkth = (struct osmo_prim_pkt_hdr *)msgb_data(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* De-serialize message: */</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_prim_init(&oph, pkth->sap, pkth->primitive, pkth->operation, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_pull(msg, sizeof(*pkth));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (prim_srv->link->rx_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = prim_srv->link->rx_cb(prim_srv, &oph);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* as we always synchronously process the message in _osmo_prim_srv_link_rx() and</span><br><span style="color: hsl(120, 100%, 40%);">+      * its callbacks, we can free the message here. */</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+close:</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_prim_srv_close(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+        return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void osmo_prim_srv_free(struct osmo_prim_srv *prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+static int _osmo_prim_srv_closed_cb(struct osmo_stream_srv *srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_prim_srv *prim_srv = osmo_stream_srv_get_data(srv);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_prim_srv_link *prim_link = prim_srv->link;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (prim_link->closed_conn_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+             return prim_link->closed_conn_cb(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_prim_srv_free(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Allocate a primitive of given type and its associated msgb.</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] srv The osmo_prim_srv_link instance where message is to be sent through</span><br><span style="color: hsl(120, 100%, 40%);">+*  \param[in] msg msgb containing osmo_prim_hdr plus extra content, allocated through \ref osmo_prim_msgb_alloc()</span><br><span style="color: hsl(120, 100%, 40%);">+*  \returns zero on success, negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_send(struct osmo_prim_srv *prim_srv, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_prim_hdr *oph;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_prim_pkt_hdr *pkth;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int sap;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int primitive;</span><br><span style="color: hsl(120, 100%, 40%);">+       enum osmo_prim_operation operation;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Serialize the oph: */</span><br><span style="color: hsl(120, 100%, 40%);">+      oph = (struct osmo_prim_hdr *)msgb_data(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(oph && msgb_length(msg) >= sizeof(*oph));</span><br><span style="color: hsl(120, 100%, 40%);">+      sap = oph->sap;</span><br><span style="color: hsl(120, 100%, 40%);">+    primitive = oph->primitive;</span><br><span style="color: hsl(120, 100%, 40%);">+        operation = oph->operation;</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_pull(msg, sizeof(*oph));</span><br><span style="color: hsl(120, 100%, 40%);">+ pkth = (struct osmo_prim_pkt_hdr *)msgb_push(msg, sizeof(*pkth));</span><br><span style="color: hsl(120, 100%, 40%);">+     pkth->sap = sap;</span><br><span style="color: hsl(120, 100%, 40%);">+   pkth->primitive = primitive;</span><br><span style="color: hsl(120, 100%, 40%);">+       pkth->operation = operation;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Finally enqueue the msg */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_stream_srv_send(prim_srv->stream, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_prim_srv *osmo_prim_srv_alloc(struct osmo_prim_srv_link *prim_link, int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_prim_srv *prim_srv;</span><br><span style="color: hsl(120, 100%, 40%);">+       prim_srv = talloc_zero(prim_link, struct osmo_prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!prim_srv)</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  prim_srv->link = prim_link;</span><br><span style="color: hsl(120, 100%, 40%);">+        prim_srv->stream = osmo_stream_srv_create(prim_link, prim_link->stream, fd,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          _osmo_prim_srv_read_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       _osmo_prim_srv_closed_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+                                             prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!prim_srv->stream) {</span><br><span style="color: hsl(120, 100%, 40%);">+           talloc_free(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Inherit link priv pointer by default, user can later set it through API: */</span><br><span style="color: hsl(120, 100%, 40%);">+        prim_srv->priv = prim_link->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+       return prim_srv;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void osmo_prim_srv_free(struct osmo_prim_srv *prim_srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      talloc_free(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link *osmo_prim_srv_get_link(struct osmo_prim_srv *prim_srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return prim_srv->link;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_set_priv(struct osmo_prim_srv *prim_srv, void *priv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    prim_srv->priv = priv;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void *osmo_prim_srv_get_priv(const struct osmo_prim_srv *prim_srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return prim_srv->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_close(struct osmo_prim_srv *prim_srv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_stream_srv_destroy(prim_srv->stream);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we free prim_srv in _osmo_prim_srv_closed_cb() */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/******************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_prim_srv_link</span><br><span style="color: hsl(120, 100%, 40%);">+ ******************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGSRVLINK(srv, lvl, fmt, args...) LOGP((srv)->log_cat, lvl, fmt, ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* accept connection coming from PCU */</span><br><span style="color: hsl(120, 100%, 40%);">+static int _osmo_prim_srv_link_accept(struct osmo_stream_srv_link *link, int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_prim_srv *prim_srv;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_prim_srv_link *prim_link = osmo_stream_srv_link_get_data(link);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ prim_srv = osmo_prim_srv_alloc(prim_link, fd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (prim_link->opened_conn_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+             return prim_link->opened_conn_cb(prim_srv);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_prim_srv_link *osmo_prim_srv_link_alloc(void *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_prim_srv_link *prim_link;</span><br><span style="color: hsl(120, 100%, 40%);">+ prim_link = talloc_zero(ctx, struct osmo_prim_srv_link);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+               return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  prim_link->stream = osmo_stream_srv_link_create(prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!prim_link->stream) {</span><br><span style="color: hsl(120, 100%, 40%);">+          talloc_free(prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+               return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_stream_srv_link_set_data(prim_link->stream, prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_stream_srv_link_set_domain(prim_link->stream, AF_UNIX);</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_stream_srv_link_set_type(prim_link->stream, SOCK_SEQPACKET);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_stream_srv_link_set_accept_cb(prim_link->stream, _osmo_prim_srv_link_accept);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       prim_link->log_cat = DLGLOBAL;</span><br><span style="color: hsl(120, 100%, 40%);">+     prim_link->rx_msgb_alloc_len = 1600 - sizeof(struct osmo_prim_pkt_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+    return prim_link;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_free(struct osmo_prim_srv_link *prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (prim_link->stream) {</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_stream_srv_link_close(prim_link->stream);</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_stream_srv_link_destroy(prim_link->stream);</span><br><span style="color: hsl(120, 100%, 40%);">+           prim_link->stream = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(prim_link);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_link_set_addr(struct osmo_prim_srv_link *prim_link, const char *path)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_talloc_replace_string(prim_link, &prim_link->addr, path);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_stream_srv_link_set_addr(prim_link->stream, path);</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_prim_srv_link_get_addr(struct osmo_prim_srv_link *prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return prim_link->addr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_priv(struct osmo_prim_srv_link *prim_link, void *priv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        prim_link->priv = priv;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void *osmo_prim_srv_link_get_priv(const struct osmo_prim_srv_link *prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return prim_link->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       prim_link->log_cat = log_cat;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_opened_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb opened_conn_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      prim_link->opened_conn_cb = opened_conn_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_closed_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb closed_conn_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  prim_link->closed_conn_cb = closed_conn_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    prim_link->rx_cb = rx_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_prim_srv_link_set_rx_msgb_alloc_len(struct osmo_prim_srv_link *prim_link, size_t alloc_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   prim_link->rx_msgb_alloc_len = alloc_len;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!prim_link->addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGSRVLINK(prim_link, LOGL_ERROR, "Cannot open, Address not configured\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   rc = osmo_stream_srv_link_open(prim_link->stream);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGSRVLINK(prim_link, LOGL_INFO, "Started listening on Lower Layer Unix Domain Socket: %s\n", prim_link->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-netif/+/26426">change 26426</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmo-netif/+/26426"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-netif </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I7cab15ac092e45a256c4f0bab11b3962df861044 </div>
<div style="display:none"> Gerrit-Change-Number: 26426 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>