<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-e1d/+/19060">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add osmo-e1d-pipe utility<br><br>This adds the 'osmo-e1d-pipe' utlility program, which can be<br>used as a command-line client to open a given E1 timeslot and<br>connect it to stdin/stdout. This in turn allows to rediect<br>file input/output via the shell.<br><br>Change-Id: Ib9d55af786c87e15465b8e73493680b35afb5913<br>---<br>M .gitignore<br>M src/Makefile.am<br>A src/e1d-ts-pipe.c<br>3 files changed, 203 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-e1d refs/changes/60/19060/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/.gitignore b/.gitignore</span><br><span>index 7185862..aef7cd0 100644</span><br><span>--- a/.gitignore</span><br><span>+++ b/.gitignore</span><br><span>@@ -23,5 +23,6 @@</span><br><span> *.o</span><br><span> </span><br><span> src/osmo-e1d</span><br><span style="color: hsl(120, 100%, 40%);">+src/osmo-e1d-pipe</span><br><span> contrib/e1-prbs-test/e1-prbs-test</span><br><span> contrib/e1-prbs-test/ice40-e1-prbs-check</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index e811f0a..9c098e7 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -27,6 +27,7 @@</span><br><span> </span><br><span> bin_PROGRAMS = \</span><br><span> osmo-e1d \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo-e1d-pipe \</span><br><span> $(NULL)</span><br><span> </span><br><span> osmo_e1d_SOURCES = \</span><br><span>@@ -41,3 +42,9 @@</span><br><span> </span><br><span> osmo_e1d_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) \</span><br><span> $(LIBOSMOUSB_LIBS) $(LIBUSB_LIBS) libosmo-e1d.la</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_e1d_pipe_SOURCES = \</span><br><span style="color: hsl(120, 100%, 40%);">+ e1d-ts-pipe.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_e1d_pipe_LDADD = $(LIBOSMOCORE_LIBS) libosmo-e1d.la</span><br><span>diff --git a/src/e1d-ts-pipe.c b/src/e1d-ts-pipe.c</span><br><span>new file mode 100644</span><br><span>index 0000000..b4eb6f5</span><br><span>--- /dev/null</span><br><span>+++ b/src/e1d-ts-pipe.c</span><br><span>@@ -0,0 +1,195 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Virtual E1 interface pair: Two virtual interfaces with N lines each,</span><br><span style="color: hsl(120, 100%, 40%);">+ * where data written to A can be read from B and vice-versa.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by Harald Welte <laforge@osmocom.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</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 along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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 <stdint.h></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 <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <getopt.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <fcntl.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/application.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/e1d/proto_clnt.h></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 *g_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_e1dp_client *g_client;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_fd ts_ofd;</span><br><span style="color: hsl(120, 100%, 40%);">+static int outfd = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+static int infd = 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 int ts_open(uint8_t intf_nr, uint8_t line_nr, uint8_t ts_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum osmo_e1dp_ts_mode mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = osmo_e1dp_client_ts_open(g_client, intf_nr, line_nr, ts_nr, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "Cannot open e1d timeslot %u:%u:%u\n", intf_nr, line_nr, ts_nr);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int ts_fd_cb(struct osmo_fd *ofd, unsigned int what)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t buf[32*10];</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc, count;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (what & OSMO_FD_READ) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = read(ofd->fd, buf, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 && errno != EAGAIN)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(3);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (rc > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ count = rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = write(outfd, buf, count);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 && errno != EAGAIN)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(3);</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%);">+ if (what & OSMO_FD_WRITE) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = read(infd, buf, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 && errno != EAGAIN)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(4);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (rc > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ count = rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = write(ofd->fd, buf, count);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 && errno != EAGAIN)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(4);</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%);">+</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 int set_nonblock(int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc, flags;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ flags = fcntl(fd, F_GETFL);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(flags >= 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(rc >= 0);</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 void print_help(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(</span><br><span style="color: hsl(120, 100%, 40%);">+ " -h --help This help message\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " -p --path PATH Path of the osmo-e1d control socket\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " -i --interface <0-255> E1 Interface Number\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " -l --line <0-255> E1 Line Number\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " -t --timeslot <0-31> E1 Timeslot Number\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " -m --mode (RAW|HDLC-FCS) E1 Timeslot Mode\n"</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%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int intf_nr = -1, line_nr = -1, ts_nr = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum osmo_e1dp_ts_mode mode = E1DP_TSMODE_RAW;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *path = E1DP_DEFAULT_SOCKET;</span><br><span style="color: hsl(120, 100%, 40%);">+ int tsfd;</span><br><span style="color: hsl(120, 100%, 40%);">+ int option_index, rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ g_ctx = talloc_named_const(NULL, 0, "g_ctx");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(g_ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_init_logging2(g_ctx, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: handle options */</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int c;</span><br><span style="color: hsl(120, 100%, 40%);">+ static const struct option long_options[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { "help", 0, 0, 'h' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "path", 1, 0, 'p' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "interface", 1, 0, 'i' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "line", 1, 0, 'l' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "timeslot", 1, 0, 't' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "mode", 1, 0, 'm' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0,0,0,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%);">+ c = getopt_long(argc, argv, "hp:i:l:t:m:", long_options, &option_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (c == -1)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (c) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'h':</span><br><span style="color: hsl(120, 100%, 40%);">+ print_help();</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(0);</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'p':</span><br><span style="color: hsl(120, 100%, 40%);">+ path = optarg;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'i':</span><br><span style="color: hsl(120, 100%, 40%);">+ intf_nr = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'l':</span><br><span style="color: hsl(120, 100%, 40%);">+ line_nr = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case 't':</span><br><span style="color: hsl(120, 100%, 40%);">+ ts_nr = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'm':</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = get_string_value(osmo_e1dp_ts_mode_names, optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "Unknown mode '%s'\n", optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(2);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ mode = rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</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%);">+ if (intf_nr == -1 || line_nr == -1 || ts_nr == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "You must at least specify interface, line and timeslot numbers\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(2);</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%);">+ g_client = osmo_e1dp_client_create(g_ctx, path);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!g_client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "Cannot establish connection to osmo-e1d at %s\n", path);</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(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%);">+ tsfd = ts_open(intf_nr, line_nr, ts_nr, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tsfd < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fd_setup(&ts_ofd, tsfd, OSMO_FD_READ|OSMO_FD_WRITE, ts_fd_cb, NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fd_register(&ts_ofd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ set_nonblock(infd);</span><br><span style="color: hsl(120, 100%, 40%);">+ set_nonblock(outfd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_select_main(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%);">+</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-e1d/+/19060">change 19060</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/osmo-e1d/+/19060"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-e1d </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ib9d55af786c87e15465b8e73493680b35afb5913 </div>
<div style="display:none"> Gerrit-Change-Number: 19060 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>