diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-08-09 14:48:11 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-08-09 14:48:11 +0200 |
commit | f98f8e39f65ccac13a01aed4cca2cb5c11c5d09d (patch) | |
tree | 3b16a1e32df766365df93ebd8ae63caa3cca1c11 | |
parent | 81fa7911194703c7076575943c3e83e794487897 (diff) | |
parent | 1f164e0cfecab645ecb63477bab5762279affc96 (diff) |
Merge tag 'upstream/0.3.0'
Upstream version 0.3.0
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | examples/Makefile.am | 2 | ||||
-rw-r--r-- | examples/channel/Makefile.am | 14 | ||||
-rw-r--r-- | examples/channel/abis_ipa_stream_client.c | 92 | ||||
-rw-r--r-- | examples/channel/abis_ipa_stream_server.c | 79 | ||||
-rw-r--r-- | include/osmocom/netif/Makefile.am | 3 | ||||
-rw-r--r-- | include/osmocom/netif/channel.h | 54 | ||||
-rw-r--r-- | include/osmocom/netif/channel/Makefile.am | 3 | ||||
-rw-r--r-- | include/osmocom/netif/channel/abis_ipa_client.h | 13 | ||||
-rw-r--r-- | include/osmocom/netif/channel/abis_ipa_server.h | 14 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/channel.c | 116 | ||||
-rw-r--r-- | src/channel/Makefile.am | 1 | ||||
-rw-r--r-- | src/channel/abis/Makefile.am | 9 | ||||
-rw-r--r-- | src/channel/abis/ipa_stream_client.c | 309 | ||||
-rw-r--r-- | src/channel/abis/ipa_stream_server.c | 421 | ||||
-rw-r--r-- | src/ipa.c | 1 | ||||
-rw-r--r-- | src/jibuf.c | 36 | ||||
-rw-r--r-- | src/osmux.c | 4 | ||||
-rw-r--r-- | src/stream.c | 2 | ||||
-rw-r--r-- | tests/jibuf/jibuf_test.c | 64 | ||||
-rw-r--r-- | tests/jibuf/jibuf_test.ok | 22 |
23 files changed, 125 insertions, 1153 deletions
@@ -35,8 +35,6 @@ tests/testsuite tests/osmux/osmux_test tests/testsuite.log -examples/channel/abis_ipa_stream_client -examples/channel/abis_ipa_stream_server examples/ipa-stream-client examples/ipa-stream-server examples/lapd-over-datagram-network diff --git a/configure.ac b/configure.ac index a04390c..4246c00 100644 --- a/configure.ac +++ b/configure.ac @@ -82,10 +82,10 @@ AC_SUBST(SYMBOL_VISIBILITY) dnl Generate the output AM_CONFIG_HEADER(config.h) -PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.11.0) -PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0) +PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.12.0) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.12.0) dnl FIXME: We depend on libosmoabis by now until we can move LAPD code here -PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.5.0) +PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.5.1) old_LIBS=$LIBS AC_SEARCH_LIBS([sctp_send], [sctp], [ @@ -118,12 +118,8 @@ AC_OUTPUT( include/Makefile include/osmocom/Makefile include/osmocom/netif/Makefile - include/osmocom/netif/channel/Makefile src/Makefile - src/channel/Makefile - src/channel/abis/Makefile examples/Makefile - examples/channel/Makefile tests/Makefile Doxyfile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am index df13808..52f4c83 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -2,8 +2,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) AM_LDFLAGS = $(COVERAGE_LDFLAGS) -SUBDIRS = channel - noinst_PROGRAMS = ipa-stream-client \ ipa-stream-server \ lapd-over-datagram-user \ diff --git a/examples/channel/Makefile.am b/examples/channel/Makefile.am deleted file mode 100644 index c417909..0000000 --- a/examples/channel/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) - -noinst_PROGRAMS = abis_ipa_stream_server \ - abis_ipa_stream_client - -abis_ipa_stream_server_SOURCES = abis_ipa_stream_server.c -abis_ipa_stream_server_LDADD = $(top_builddir)/src/libosmonetif.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) - -abis_ipa_stream_client_SOURCES = abis_ipa_stream_client.c -abis_ipa_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) diff --git a/examples/channel/abis_ipa_stream_client.c b/examples/channel/abis_ipa_stream_client.c deleted file mode 100644 index 8795cc6..0000000 --- a/examples/channel/abis_ipa_stream_client.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <osmocom/core/select.h> -#include <osmocom/core/talloc.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/application.h> - -#include <osmocom/netif/channel.h> -#include <osmocom/netif/channel/abis_ipa_client.h> -#include <osmocom/netif/ipa_unit.h> - -static void *tall_example; - -#define DEXAMPLE 0 - -struct log_info_cat example_cat[] = { - [DEXAMPLE] = { - .name = "DEXAMPLE", - .description = "example", - .color = "\033[1;35m", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -const struct log_info example_log_info = { - .filter_fn = NULL, - .cat = example_cat, - .num_cat = ARRAY_SIZE(example_cat), -}; - -void sighandler(int foo) -{ - LOGP(DEXAMPLE, LOGL_NOTICE, "closing test.\n"); - exit(EXIT_SUCCESS); -} - -static void signal_msg_cb(struct msgb *msg, int type) -{ - LOGP(DEXAMPLE, LOGL_NOTICE, "received signal message\n"); -} - -static struct osmo_chan *chan; - -int main(void) -{ - struct osmo_ipa_unit *unit; - - tall_example = talloc_named_const(NULL, 1, "example"); - msgb_talloc_ctx_init(tall_example, 0); - osmo_init_logging2(tall_example, &example_log_info); - log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - - /* initialize channel infrastructure. */ - osmo_chan_init(tall_example); - - /* create channel. */ - chan = osmo_chan_create(OSMO_CHAN_ABIS_IPA_CLI, OSMO_SUBCHAN_STREAM); - if (chan == NULL) { - LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create A-bis IPA client\n"); - exit(EXIT_FAILURE); - } - - /* set specific parameters (depends on channel type). */ - osmo_abis_ipa_cli_set_oml_addr(chan, "127.0.0.1"); - osmo_abis_ipa_cli_set_rsl_addr(chan, "127.0.0.1"); - - unit = osmo_ipa_unit_alloc(0); - if (unit == NULL) { - LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create IPA unit\n"); - exit(EXIT_FAILURE); - } - osmo_ipa_unit_set_site_id(unit, 1801); - - osmo_abis_ipa_cli_set_unit(chan, unit); - osmo_abis_ipa_cli_set_cb_signalmsg(chan, signal_msg_cb); - - /* open channel. */ - if (osmo_chan_open(chan) < 0) { - LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create A-bis IPA client\n"); - exit(EXIT_FAILURE); - } - - LOGP(DEXAMPLE, LOGL_NOTICE, "Entering main loop\n"); - - while(1) { - osmo_select_main(0); - } -} diff --git a/examples/channel/abis_ipa_stream_server.c b/examples/channel/abis_ipa_stream_server.c deleted file mode 100644 index 58a4e15..0000000 --- a/examples/channel/abis_ipa_stream_server.c +++ /dev/null @@ -1,79 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <osmocom/core/select.h> -#include <osmocom/core/talloc.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/application.h> - -#include <osmocom/netif/channel.h> -#include <osmocom/netif/channel/abis_ipa_server.h> - -static void *tall_example; - -#define DEXAMPLE 0 - -struct log_info_cat example_cat[] = { - [DEXAMPLE] = { - .name = "DEXAMPLE", - .description = "example", - .color = "\033[1;35m", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -const struct log_info example_log_info = { - .filter_fn = NULL, - .cat = example_cat, - .num_cat = ARRAY_SIZE(example_cat), -}; - -void sighandler(int foo) -{ - LOGP(DEXAMPLE, LOGL_NOTICE, "closing test.\n"); - exit(EXIT_SUCCESS); -} - -static void signal_msg_cb(struct msgb *msg, int type) -{ - LOGP(DEXAMPLE, LOGL_NOTICE, "received signal message\n"); -} - -static struct osmo_chan *chan; - -int main(void) -{ - tall_example = talloc_named_const(NULL, 1, "example"); - msgb_talloc_ctx_init(tall_example, 0); - osmo_init_logging2(tall_example, &example_log_info); - log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - - /* initialize channel infrastructure. */ - osmo_chan_init(tall_example); - - /* create channel. */ - chan = osmo_chan_create(OSMO_CHAN_ABIS_IPA_SRV, OSMO_SUBCHAN_STREAM); - if (chan == NULL) { - LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create A-bis IPA server\n"); - exit(EXIT_FAILURE); - } - - /* set specific parameters (depends on channel type). */ - osmo_abis_ipa_srv_set_cb_signalmsg(chan, signal_msg_cb); - osmo_abis_ipa_unit_add(chan, 1801, 0); - - /* open channel. */ - if (osmo_chan_open(chan) < 0) { - LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create A-bis IPA server\n"); - exit(EXIT_FAILURE); - } - - LOGP(DEXAMPLE, LOGL_NOTICE, "Entering main loop\n"); - - while(1) { - osmo_select_main(0); - } -} diff --git a/include/osmocom/netif/Makefile.am b/include/osmocom/netif/Makefile.am index 0db78fb..39df08a 100644 --- a/include/osmocom/netif/Makefile.am +++ b/include/osmocom/netif/Makefile.am @@ -1,7 +1,4 @@ -SUBDIRS = channel - osmonetif_HEADERS = amr.h \ - channel.h \ datagram.h \ jibuf.h \ osmux.h \ diff --git a/include/osmocom/netif/channel.h b/include/osmocom/netif/channel.h deleted file mode 100644 index 1abc828..0000000 --- a/include/osmocom/netif/channel.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef _CHANNEL_H_ -#define _CHANNEL_H_ - -#include <stdint.h> - -/* channel types */ -enum { - OSMO_CHAN_NONE, - OSMO_CHAN_ABIS_IPA_SRV, - OSMO_CHAN_ABIS_IPA_CLI, - OSMO_CHAN_MAX, -}; - -/* channel subtypes */ -enum { - OSMO_SUBCHAN_STREAM, - OSMO_SUBCHAN_MAX, -}; - -struct osmo_chan; -struct msgb; - -struct osmo_chan_type { - struct llist_head head; - - char *name; - int type; - int subtype; - int datasiz; - - int (*create)(struct osmo_chan *chan); - void (*destroy)(struct osmo_chan *chan); - int (*open)(struct osmo_chan *chan); - void (*close)(struct osmo_chan *chan); - int (*enqueue)(struct osmo_chan *chan, struct msgb *msg); -}; - -struct osmo_chan { - void *ctx; - struct osmo_chan_type *ops; - char data[0]; -}; - -void osmo_chan_init(void *ctx); - -struct osmo_chan *osmo_chan_create(int type, int subtype); -void osmo_chan_destroy(struct osmo_chan *c); - -int osmo_chan_open(struct osmo_chan *c); -void osmo_chan_close(struct osmo_chan *c); - -int osmo_chan_enqueue(struct osmo_chan *c, struct msgb *msg); - -#endif /* _CHANNEL_H_ */ diff --git a/include/osmocom/netif/channel/Makefile.am b/include/osmocom/netif/channel/Makefile.am deleted file mode 100644 index dec19b2..0000000 --- a/include/osmocom/netif/channel/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -osmonetif_channel_HEADERS = abis_ipa_server.h abis_ipa_client.h - -osmonetif_channeldir = $(includedir)/osmocom/netif/channel diff --git a/include/osmocom/netif/channel/abis_ipa_client.h b/include/osmocom/netif/channel/abis_ipa_client.h deleted file mode 100644 index cd35852..0000000 --- a/include/osmocom/netif/channel/abis_ipa_client.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _OSMO_ABIS_IPA_CLIENT_H_ -#define _OSMO_ABIS_IPA_CLIENT_H_ - -struct osmo_ipa_unit; - -void osmo_abis_ipa_cli_set_oml_addr(struct osmo_chan *c, const char *addr); -void osmo_abis_ipa_cli_set_oml_port(struct osmo_chan *c, uint16_t port); -void osmo_abis_ipa_cli_set_rsl_addr(struct osmo_chan *c, const char *addr); -void osmo_abis_ipa_cli_set_rsl_port(struct osmo_chan *c, uint16_t port); -void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct osmo_ipa_unit *unit); -void osmo_abis_ipa_cli_set_cb_signalmsg(struct osmo_chan *c, void (*signal_msg)(struct msgb *msg, int type)); - -#endif /* _OSMO_ABIS_IPA_CLIENT_H_ */ diff --git a/include/osmocom/netif/channel/abis_ipa_server.h b/include/osmocom/netif/channel/abis_ipa_server.h deleted file mode 100644 index 6518f99..0000000 --- a/include/osmocom/netif/channel/abis_ipa_server.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _ABIS_IPA_SERVER_H_ -#define _ABIS_IPA_SERVER_H_ - -void osmo_abis_ipa_srv_set_oml_addr(struct osmo_chan *c, const char *addr); -void osmo_abis_ipa_srv_set_oml_port(struct osmo_chan *c, uint16_t port); - -void osmo_abis_ipa_srv_set_rsl_addr(struct osmo_chan *c, const char *addr); -void osmo_abis_ipa_srv_set_rsl_port(struct osmo_chan *c, uint16_t port); - -void osmo_abis_ipa_srv_set_cb_signalmsg(struct osmo_chan *c, void (*signal_msg)(struct msgb *msg, int type)); - -int osmo_abis_ipa_unit_add(struct osmo_chan *c, uint16_t site_id, uint16_t bts_id); - -#endif diff --git a/src/Makefile.am b/src/Makefile.am index 9dc5e46..d88f0a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,20 +1,17 @@ # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification -LIBVERSION=5:0:1 +LIBVERSION=6:0:0 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS= -fPIC -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSCTP_CFLAGS) AM_LDFLAGS = $(COVERAGE_LDFLAGS) -SUBDIRS = channel - lib_LTLIBRARIES = libosmonetif.la -libosmonetif_la_LIBADD = channel/abis/libosmonetif-abis.la $(LIBOSMOCORE_LIBS) $(LIBSCTP_LIBS) +libosmonetif_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBSCTP_LIBS) libosmonetif_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined libosmonetif_la_SOURCES = amr.c \ - channel.c \ datagram.c \ ipa.c \ ipa_unit.c \ diff --git a/src/channel.c b/src/channel.c deleted file mode 100644 index 2784f22..0000000 --- a/src/channel.c +++ /dev/null @@ -1,116 +0,0 @@ -/* (C) 2011-2012 by Pablo Neira Ayuso <pablo@gnumonks.org> - * All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - * - * 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, see <http://www.gnu.org/licenses/>. - * - */ -#include <osmocom/core/talloc.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/linuxlist.h> - -#include <osmocom/netif/channel.h> - -static LLIST_HEAD(channel_list); - -extern struct osmo_chan_type chan_abis_ipa_srv; -extern struct osmo_chan_type chan_abis_ipa_cli; - -static void *osmo_chan_ctx; - -void osmo_chan_init(void *ctx) -{ - osmo_chan_ctx = ctx; - llist_add(&chan_abis_ipa_srv.head, &channel_list); - llist_add(&chan_abis_ipa_cli.head, &channel_list); - /* add your new channel type here */ -} - -struct osmo_chan *osmo_chan_create(int type_id, int subtype_id) -{ - struct osmo_chan_type *cur = NULL; - int found = 0, found_partial = 0; - struct osmo_chan *c; - - if (type_id > OSMO_CHAN_MAX) { - LOGP(DLINP, LOGL_ERROR, "unsupported channel type " - "number `%u'\n", type_id); - return NULL; - } - if (subtype_id > OSMO_SUBCHAN_MAX) { - LOGP(DLINP, LOGL_ERROR, "unsupported subchannel type " - "number `%u'\n", type_id); - return NULL; - } - - llist_for_each_entry(cur, &channel_list, head) { - if (type_id == cur->type && subtype_id == cur->subtype) { - found = 1; - break; - } else if (type_id == cur->type) { - found_partial = 1; - break; - } - } - - if (!found) { - LOGP(DLINP, LOGL_ERROR, "unsupported channel type `%s'\n", - cur->name); - return NULL; - } - if (found_partial) { - LOGP(DLINP, LOGL_ERROR, "Sorry, channel type `%s' does not " - "support subtype `%u'\n", cur->name, subtype_id); - return NULL; - } - - c = talloc_zero_size(osmo_chan_ctx, - sizeof(struct osmo_chan) + cur->datasiz); - if (c == NULL) { - LOGP(DLINP, LOGL_ERROR, "cannot allocate channel data\n"); - return NULL; - } - - c->ops = cur; - - if (c->ops->create(c) < 0) { - LOGP(DLINP, LOGL_ERROR, "cannot create channel\n"); - talloc_free(c); - return NULL; - } - return c; -} - -void osmo_chan_destroy(struct osmo_chan *c) -{ - c->ops->destroy(c); - talloc_free(c); -} - -int osmo_chan_open(struct osmo_chan *c) -{ - return c->ops->open(c); -} - -void osmo_chan_close(struct osmo_chan *c) -{ - c->ops->close(c); -} - -int osmo_chan_enqueue(struct osmo_chan *c, struct msgb *msg) -{ - return c->ops->enqueue(c, msg); -} diff --git a/src/channel/Makefile.am b/src/channel/Makefile.am deleted file mode 100644 index 1c4b7a9..0000000 --- a/src/channel/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = abis diff --git a/src/channel/abis/Makefile.am b/src/channel/abis/Makefile.am deleted file mode 100644 index 615abff..0000000 --- a/src/channel/abis/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS= -fPIC -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) - -noinst_LTLIBRARIES = libosmonetif-abis.la - -libosmonetif_abis_la_SOURCES = ipa_stream_server.c \ - ipa_stream_client.c -libosmonetif_abis_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/src/channel/abis/ipa_stream_client.c b/src/channel/abis/ipa_stream_client.c deleted file mode 100644 index c610730..0000000 --- a/src/channel/abis/ipa_stream_client.c +++ /dev/null @@ -1,309 +0,0 @@ -/* (C) 2012 by Pablo Neira Ayuso <pablo@gnumonks.org> - * All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/socket.h> -#include <errno.h> - -#include <osmocom/core/talloc.h> -#include <osmocom/core/select.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/logging.h> - -#include <osmocom/gsm/tlv.h> - -#include <osmocom/netif/channel.h> -#include <osmocom/netif/stream.h> -#include <osmocom/netif/ipa.h> -#include <osmocom/netif/ipa_unit.h> - -#define CHAN_SIGN_OML 0 -#define CHAN_SIGN_RSL 1 - -/* default IPA cli ports. */ -#define IPA_TCP_PORT_OML 3002 -#define IPA_TCP_PORT_RSL 3003 - -static void *abis_ipa_cli_tall; - -struct chan_abis_ipa_cli { - struct osmo_ipa_unit *unit; - - struct osmo_stream_cli *oml; - struct osmo_stream_cli *rsl; - - void (*signal_msg)(struct msgb *msg, int type); -}; - -static int oml_read_cb(struct osmo_stream_cli *conn); -static int rsl_read_cb(struct osmo_stream_cli *conn); - -static int chan_abis_ipa_cli_create(struct osmo_chan *chan) -{ - struct chan_abis_ipa_cli *c = (struct chan_abis_ipa_cli *)chan->data; - - c->unit = osmo_ipa_unit_alloc(0); - if (c->unit == NULL) - goto err; - - c->oml = osmo_stream_cli_create(abis_ipa_cli_tall); - if (c->oml == NULL) - goto err_oml; - - /* default address and port for OML. */ - osmo_stream_cli_set_addr(c->oml, "0.0.0.0"); - osmo_stream_cli_set_port(c->oml, IPA_TCP_PORT_OML); - osmo_stream_cli_set_read_cb(c->oml, oml_read_cb); - osmo_stream_cli_set_data(c->oml, chan); - - c->rsl = osmo_stream_cli_create(abis_ipa_cli_tall); - if (c->rsl == NULL) - goto err_rsl; - - /* default address and port for RSL. */ - osmo_stream_cli_set_addr(c->rsl, "0.0.0.0"); - osmo_stream_cli_set_port(c->rsl, IPA_TCP_PORT_RSL); - osmo_stream_cli_set_read_cb(c->rsl, rsl_read_cb); - osmo_stream_cli_set_data(c->rsl, chan); - - return 0; -err_rsl: - osmo_stream_cli_destroy(c->oml); -err_oml: - osmo_ipa_unit_free(c->unit); -err: - return -1; -} - -static void chan_abis_ipa_cli_destroy(struct osmo_chan *chan) -{ - struct chan_abis_ipa_cli *c = (struct chan_abis_ipa_cli *)chan->data; - - osmo_ipa_unit_free(c->unit); - talloc_free(c->rsl); - talloc_free(c->oml); -} - -static int chan_abis_ipa_cli_open(struct osmo_chan *chan) -{ - struct chan_abis_ipa_cli *c = (struct chan_abis_ipa_cli *)chan->data; - struct osmo_fd *ofd; - int ret, on = 1; - - if (osmo_stream_cli_open(c->oml) < 0) - goto err; - - ofd = osmo_stream_cli_get_ofd(c->oml); - ret = setsockopt(ofd->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); - if (ret < 0) - goto err_oml; - - if (osmo_stream_cli_open(c->rsl) < 0) - goto err_oml; - - ofd = osmo_stream_cli_get_ofd(c->rsl); - ret = setsockopt(ofd->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); - if (ret < 0) - goto err_rsl; - - return 0; - -err_rsl: - osmo_stream_cli_close(c->rsl); -err_oml: - osmo_stream_cli_close(c->oml); -err: - return -1; -} - -static void chan_abis_ipa_cli_close(struct osmo_chan *chan) -{ - struct chan_abis_ipa_cli *c = (struct chan_abis_ipa_cli *)chan->data; - - osmo_stream_cli_close(c->oml); - osmo_stream_cli_close(c->rsl); -} - -static int chan_abis_ipa_cli_enqueue(struct osmo_chan *c, struct msgb *msg) -{ - osmo_stream_cli_send(msg->dst, msg); - return 0; -} - -void osmo_abis_ipa_cli_set_oml_addr(struct osmo_chan *c, const char *addr) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - osmo_stream_cli_set_addr(s->oml, addr); -} - -void osmo_abis_ipa_cli_set_oml_port(struct osmo_chan *c, uint16_t port) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - osmo_stream_cli_set_port(s->oml, port); -} - -void osmo_abis_ipa_cli_set_rsl_addr(struct osmo_chan *c, const char *addr) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - osmo_stream_cli_set_addr(s->rsl, addr); -} - -void osmo_abis_ipa_cli_set_rsl_port(struct osmo_chan *c, uint16_t port) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - osmo_stream_cli_set_port(s->rsl, port); -} - -void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct osmo_ipa_unit *unit) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - osmo_ipa_unit_free(s->unit); - s->unit = unit; -} - -void osmo_abis_ipa_cli_set_cb_signalmsg(struct osmo_chan *c, - void (*signal_msg)(struct msgb *msg, int type)) -{ - struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data; - - s->signal_msg = signal_msg; -} - -static int -abis_ipa_cli_rcvmsg(struct osmo_chan *c, struct osmo_stream_cli *conn, - struct msgb *msg, int type) -{ - uint8_t msg_type = *(msg->l2h); - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct chan_abis_ipa_cli *chan = (struct chan_abis_ipa_cli *)&c->data; - int ret; - - /* Handle IPA PING, PONG and ID_ACK messages. */ - if (osmo_ipa_rcvmsg_base(msg, ofd, 0)) /* XXX: 0 indicates client */ - return 0; - - if (msg_type == IPAC_MSGT_ID_GET) { - struct msgb *rmsg; - uint8_t *data = msgb_l2(msg); - int len = msgb_l2len(msg); - - LOGP(DLINP, LOGL_NOTICE, "received ID get\n"); - - rmsg = ipa_cli_id_resp(chan->unit, data + 1, len - 1); - osmo_stream_cli_send(conn, rmsg); - - /* send ID_ACK. */ - rmsg = ipa_cli_id_ack(); - osmo_stream_cli_send(conn, rmsg); - ret = 0; - } else { - LOGP(DLINP, LOGL_ERROR, "Unknown IPA message type\n"); - ret = -EINVAL; - } - return ret; -} - -static int read_cb(struct osmo_stream_cli *conn, int type) -{ - int ret; - struct msgb *msg; - struct osmo_chan *chan = osmo_stream_cli_get_data(conn); - struct chan_abis_ipa_cli *s; - struct ipa_head *hh; - - LOGP(DLINP, LOGL_DEBUG, "received message from stream\n"); - - msg = osmo_ipa_msg_alloc(0); - if (msg == NULL) { - LOGP(DLINP, LOGL_ERROR, "cannot allocate message\n"); - return 0; - } - ret = osmo_stream_cli_recv(conn, msg); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "cannot receive message\n"); - msgb_free(msg); - /* not the dummy connection, release it. */ - return 0; - } else if (ret == 0) { - /* link has vanished, dead socket. */ - LOGP(DLINP, LOGL_ERROR, "closed connection\n"); - msgb_free(msg); - return 0; - } - - if (osmo_ipa_process_msg(msg) < 0) { - LOGP(DLINP, LOGL_ERROR, "Bad IPA message\n"); - msgb_free(msg); - return -EIO; - } - - hh = (struct ipa_head *) msg->data; - if (hh->proto == IPAC_PROTO_IPACCESS) { - abis_ipa_cli_rcvmsg(chan, conn, msg, type); - msgb_free(msg); - return -EIO; - } - - chan = osmo_stream_cli_get_data(conn); - if (chan == NULL) { - LOGP(DLINP, LOGL_ERROR, "no matching signalling link\n"); - msgb_free(msg); - return -EIO; - } - if (hh->proto != IPAC_PROTO_OML && hh->proto != IPAC_PROTO_RSL) { - LOGP(DLINP, LOGL_ERROR, "wrong protocol\n"); - return -EIO; - } - msg->dst = chan; - - s = (struct chan_abis_ipa_cli *)chan->data; - s->signal_msg(msg, type); - - return 0; -} - -static int oml_read_cb(struct osmo_stream_cli *conn) -{ - return read_cb(conn, CHAN_SIGN_OML); -} - -static int rsl_read_cb(struct osmo_stream_cli *conn) -{ - return read_cb(conn, CHAN_SIGN_RSL); -} - -struct osmo_chan_type chan_abis_ipa_cli = { - .type = OSMO_CHAN_ABIS_IPA_CLI, - .subtype = OSMO_SUBCHAN_STREAM, - .name = "A-bis IPA client", - .datasiz = sizeof(struct chan_abis_ipa_cli), - .create = chan_abis_ipa_cli_create, - .destroy = chan_abis_ipa_cli_destroy, - .open = chan_abis_ipa_cli_open, - .close = chan_abis_ipa_cli_close, - .enqueue = chan_abis_ipa_cli_enqueue, -}; diff --git a/src/channel/abis/ipa_stream_server.c b/src/channel/abis/ipa_stream_server.c deleted file mode 100644 index 1cd889c..0000000 --- a/src/channel/abis/ipa_stream_server.c +++ /dev/null @@ -1,421 +0,0 @@ -/* (C) 2012 by Pablo Neira Ayuso <pablo@gnumonks.org> - * All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/socket.h> -#include <errno.h> - -#include <osmocom/core/talloc.h> -#include <osmocom/core/select.h> -#include <osmocom/core/msgb.h> -#include <osmocom/core/logging.h> - -#include <osmocom/gsm/tlv.h> - -#include <osmocom/netif/channel.h> -#include <osmocom/netif/stream.h> -#include <osmocom/netif/ipa.h> -#include <osmocom/netif/ipa_unit.h> - -#define CHAN_SIGN_OML 0 -#define CHAN_SIGN_RSL 1 - -/* default IPA srv ports. */ -#define IPA_TCP_PORT_OML 3002 -#define IPA_TCP_PORT_RSL 3003 - -static void *abis_ipa_srv_tall; - -static int oml_accept_cb(struct osmo_stream_srv_link *srv, int fd); -static int rsl_accept_cb(struct osmo_stream_srv_link *srv, int fd); - -struct chan_abis_ipa_srv { - struct osmo_chan *chan; - struct osmo_stream_srv_link *oml; - struct osmo_stream_srv_link *rsl; - - struct llist_head bts_list; - - void (*signal_msg)(struct msgb *msg, int type); -}; - -struct chan_abis_ipa_srv_conn { - struct chan_abis_ipa_srv *master; - - struct osmo_stream_srv *oml; - struct osmo_stream_srv *rsl; -}; - -static int chan_abis_ipa_srv_create(struct osmo_chan *chan) -{ - struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data; - - c->oml = osmo_stream_srv_link_create(abis_ipa_srv_tall); - if (c->oml == NULL) - goto err_oml; - - /* default address and port for OML. */ - osmo_stream_srv_link_set_addr(c->oml, "0.0.0.0"); - osmo_stream_srv_link_set_port(c->oml, IPA_TCP_PORT_OML); - osmo_stream_srv_link_set_accept_cb(c->oml, oml_accept_cb); - osmo_stream_srv_link_set_data(c->oml, c); - - c->rsl = osmo_stream_srv_link_create(abis_ipa_srv_tall); - if (c->rsl == NULL) - goto err_rsl; - - /* default address and port for RSL. */ - osmo_stream_srv_link_set_addr(c->rsl, "0.0.0.0"); - osmo_stream_srv_link_set_port(c->rsl, IPA_TCP_PORT_RSL); - osmo_stream_srv_link_set_accept_cb(c->rsl, rsl_accept_cb); - osmo_stream_srv_link_set_data(c->rsl, c); - - INIT_LLIST_HEAD(&c->bts_list); - - return 0; -err_rsl: - osmo_stream_srv_link_destroy(c->oml); -err_oml: - return -1; -} - -static void chan_abis_ipa_srv_destroy(struct osmo_chan *chan) -{ - struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data; - - osmo_stream_srv_link_destroy(c->rsl); - osmo_stream_srv_link_destroy(c->oml); -} - -static int chan_abis_ipa_srv_open(struct osmo_chan *chan) -{ - struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data; - struct osmo_fd *ofd; - int ret, on = 1; - - if (osmo_stream_srv_link_open(c->oml) < 0) - goto err; - - ofd = osmo_stream_srv_link_get_ofd(c->oml); - ret = setsockopt(ofd->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); - if (ret < 0) - goto err_oml; - - if (osmo_stream_srv_link_open(c->rsl) < 0) - goto err_oml; - - ofd = osmo_stream_srv_link_get_ofd(c->rsl); - ret = setsockopt(ofd->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); - if (ret < 0) - goto err_rsl; - - return 0; - -err_rsl: - osmo_stream_srv_link_close(c->rsl); -err_oml: - osmo_stream_srv_link_close(c->oml); -err: - return -1; -} - -static void chan_abis_ipa_srv_close(struct osmo_chan *chan) -{ - struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data; - - osmo_stream_srv_link_close(c->oml); - osmo_stream_srv_link_close(c->rsl); -} - -static int chan_abis_ipa_srv_enqueue(struct osmo_chan *c, struct msgb *msg) -{ - osmo_stream_srv_send(msg->dst, msg); - return 0; -} - -void osmo_abis_ipa_srv_set_oml_addr(struct osmo_chan *c, const char *addr) -{ - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - - osmo_stream_srv_link_set_addr(s->oml, addr); -} - -void osmo_abis_ipa_srv_set_oml_port(struct osmo_chan *c, uint16_t port) -{ - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - - osmo_stream_srv_link_set_port(s->oml, port); -} - -void osmo_abis_ipa_srv_set_rsl_addr(struct osmo_chan *c, const char *addr) -{ - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - - osmo_stream_srv_link_set_addr(s->rsl, addr); -} - -void osmo_abis_ipa_srv_set_rsl_port(struct osmo_chan *c, uint16_t port) -{ - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - - osmo_stream_srv_link_set_port(s->rsl, port); -} - -void osmo_abis_ipa_srv_set_cb_signalmsg(struct osmo_chan *c, - void (*signal_msg)(struct msgb *msg, int type)) -{ - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - - s->signal_msg = signal_msg; -} - -int -osmo_abis_ipa_unit_add(struct osmo_chan *c, uint16_t site_id, uint16_t bts_id) -{ - struct osmo_ipa_unit *unit; - struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data; - struct chan_abis_ipa_srv_conn *inst; - - unit = osmo_ipa_unit_alloc(sizeof(struct chan_abis_ipa_srv_conn)); - if (unit == NULL) - return -1; - - osmo_ipa_unit_set_site_id(unit, site_id); - osmo_ipa_unit_set_bts_id(unit, bts_id); - osmo_ipa_unit_add(&s->bts_list, unit); - - inst = osmo_ipa_unit_get_data(unit); - inst->master = s; - - return 0; -} - -static int oml_read_cb(struct osmo_stream_srv *conn); - -static int oml_accept_cb(struct osmo_stream_srv_link *srv, int fd) -{ - struct osmo_stream_srv *conn; - struct osmo_fd *ofd; - - conn = osmo_stream_srv_create(abis_ipa_srv_tall, - srv, fd, oml_read_cb, NULL, NULL); - if (conn == NULL) { - LOGP(DLINP, LOGL_ERROR, "error while creating connection\n"); - return -1; - } - - ofd = osmo_stream_srv_get_ofd(conn); - - /* XXX: better use chan_abis_ipa_srv_enqueue. */ - ipaccess_send_id_req(ofd->fd); - - return 0; -} - -static int rsl_read_cb(struct osmo_stream_srv *conn); - -static int rsl_accept_cb(struct osmo_stream_srv_link *srv, int fd) -{ - struct osmo_stream_srv *conn; - struct osmo_fd *ofd; - - conn = osmo_stream_srv_create(abis_ipa_srv_tall, srv, fd, - rsl_read_cb, NULL, NULL); - if (conn == NULL) { - LOGP(DLINP, LOGL_ERROR, "error while creating connection\n"); - return -1; - } - - ofd = osmo_stream_srv_get_ofd(conn); - - /* XXX: better use chan_abis_ipa_srv_enqueue. */ - ipaccess_send_id_req(ofd->fd); - - return 0; -} - -static void abis_ipa_put(struct osmo_ipa_unit *unit) -{ - struct chan_abis_ipa_srv_conn *inst = osmo_ipa_unit_get_data(unit); - - osmo_stream_srv_destroy(inst->oml); - osmo_stream_srv_destroy(inst->rsl); - inst->oml = NULL; - inst->rsl = NULL; -} - -static int -abis_ipa_srv_rcvmsg(struct osmo_stream_srv *conn, struct msgb *msg, int type) -{ - uint8_t msg_type = *(msg->l2h); - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_stream_srv_link *link = osmo_stream_srv_get_master(conn); - struct chan_abis_ipa_srv *s = osmo_stream_srv_link_get_data(link); - struct chan_abis_ipa_srv_conn *inst; - int ret; - - /* Handle IPA PING, PONG and ID_ACK messages */ - if (osmo_ipa_rcvmsg_base(msg, ofd, 1)) /* XXX: 1 indicates server */ - return 0; - - if (msg_type == IPAC_MSGT_ID_RESP) { - struct osmo_ipa_unit *unit; - struct ipaccess_unit unit_data; - - if (osmo_ipa_parse_msg_id_resp(msg, &unit_data) < 0) { - LOGP(DLINP, LOGL_ERROR, "bad ID RESP message\n"); - return -EIO; - } - - unit = osmo_ipa_unit_find(&s->bts_list, unit_data.site_id, - unit_data.bts_id); - - if (unit == NULL) { - LOGP(DLINP, LOGL_ERROR, "Unable to find BTS " - "configuration for %u/%u/%u, disconnecting\n", - unit_data.site_id, unit_data.bts_id, - unit_data.trx_id); - return 0; - } - DEBUGP(DLINP, "Identified BTS %u/%u/%u\n", - unit_data.site_id, unit_data.bts_id, - unit_data.trx_id); - - inst = osmo_ipa_unit_get_data(unit); - - if (type == CHAN_SIGN_OML) { - if (inst->oml) { - /* link already exists, kill it. */ - osmo_stream_srv_destroy(inst->oml); - return 0; - } - inst->oml = conn; - } else if (type == CHAN_SIGN_RSL) { - if (!inst->oml) { - /* no OML link? Restart from scratch. */ - abis_ipa_put(unit); - return 0; - } - if (inst->rsl) { - /* RSL link already exists, kill it. */ - osmo_stream_srv_destroy(inst->rsl); - return 0; - } - inst->rsl = conn; - } - osmo_stream_srv_set_data(conn, unit); - ret = 0; - } else { - LOGP(DLINP, LOGL_ERROR, "Unknown IPA message type\n"); - ret = -EINVAL; - } - return ret; -} - -static int read_cb(struct osmo_stream_srv *conn, int type) -{ - int ret; - struct msgb *msg; - struct osmo_ipa_unit *unit = osmo_stream_srv_get_data(conn); - struct chan_abis_ipa_srv_conn *inst; - struct ipa_head *hh; - - LOGP(DLINP, LOGL_DEBUG, "received message from stream\n"); - - msg = osmo_ipa_msg_alloc(0); - if (msg == NULL) { - LOGP(DLINP, LOGL_ERROR, "cannot allocate message\n"); - return 0; - } - ret = osmo_stream_srv_recv(conn, msg); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "cannot receive message\n"); - msgb_free(msg); - if (unit != NULL) - abis_ipa_put(unit); - else - osmo_stream_srv_destroy(conn); - - return 0; - } else if (ret == 0) { - /* link has vanished, dead socket. */ - LOGP(DLINP, LOGL_ERROR, "closed connection\n"); - msgb_free(msg); - if (unit != NULL) - abis_ipa_put(unit); - else - osmo_stream_srv_destroy(conn); - - return 0; - } - ret = osmo_ipa_process_msg(msg); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "invalid IPA message\n"); - msgb_free(msg); - } - - hh = (struct ipa_head *) msg->data; - if (hh->proto == IPAC_PROTO_IPACCESS) { - abis_ipa_srv_rcvmsg(conn, msg, type); - msgb_free(msg); - return -EIO; - } - - if (unit == NULL) { - LOGP(DLINP, LOGL_ERROR, "no IPA unit associated to this " - "connection\n"); - return -EIO; - } - inst = osmo_ipa_unit_get_data(unit); - - if (hh->proto != IPAC_PROTO_OML && hh->proto != IPAC_PROTO_RSL) { - LOGP(DLINP, LOGL_ERROR, "wrong protocol\n"); - return -EIO; - } - msg->dst = conn; - - inst->master->signal_msg(msg, type); - - return 0; -} - -static int oml_read_cb(struct osmo_stream_srv *conn) -{ - return read_cb(conn, CHAN_SIGN_OML); -} - -static int rsl_read_cb(struct osmo_stream_srv *conn) -{ - return read_cb(conn, CHAN_SIGN_RSL); -} - -struct osmo_chan_type chan_abis_ipa_srv = { - .type = OSMO_CHAN_ABIS_IPA_SRV, - .subtype = OSMO_SUBCHAN_STREAM, - .name = "A-bis IPA server", - .datasiz = sizeof(struct chan_abis_ipa_srv), - .create = chan_abis_ipa_srv_create, - .destroy = chan_abis_ipa_srv_destroy, - .open = chan_abis_ipa_srv_open, - .close = chan_abis_ipa_srv_close, - .enqueue = chan_abis_ipa_srv_enqueue, -}; @@ -31,7 +31,6 @@ #include <osmocom/gsm/tlv.h> -#include <osmocom/netif/channel.h> #include <osmocom/netif/ipa.h> #include <osmocom/netif/ipa_unit.h> diff --git a/src/jibuf.c b/src/jibuf.c index 45019ae..2632a57 100644 --- a/src/jibuf.c +++ b/src/jibuf.c @@ -119,6 +119,35 @@ static void llist_add_sorted(struct msgb *msg, struct llist_head *msg_list) } +static void enqueue_pkt(struct osmo_jibuf *jb, struct msgb *msg, bool is_syncpoint) +{ + struct msgb *cur; + struct timeval *msg_ts; + + if (!is_syncpoint) { + llist_add_sorted(msg, &jb->msg_list); + return; + } + + /* syncpoints change the reference timings, and as such they can provoke + out of order enqueuing of this packet and its followups with regards + to the already stored packets which may be scheduled for later times. + We thus need to adapt dequeue time for the already stored pkts to be + dequeued before the syncpoint pkt. See OS#3262 for related scenarios. + */ + + msg_ts = msgb_scheduled_ts(msg); + + llist_for_each_entry(cur, &jb->msg_list, list) { + struct timeval *cur_ts = msgb_scheduled_ts(cur); + if (timercmp(msg_ts, cur_ts, <)) + *cur_ts = *msg_ts; + } + /* syncpoint goes always to the end since we moved all older packets + before it */ + llist_add_tail(&msg->list, &jb->msg_list); +} + static bool msg_get_marker(struct msgb *msg) { /* TODO: make it more generic as a callback so that different types of @@ -314,11 +343,13 @@ int osmo_jibuf_enqueue(struct osmo_jibuf *jb, struct msgb *msg) { int rel_delay, delay; struct timeval delay_ts, sched_ts; + bool is_syncpoint; clock_gettime_timeval(CLOCK_MONOTONIC, &jb->last_enqueue_time); /* Check if it's time to sync, ie. start of talkspurt */ - if (!jb->started || msg_is_syncpoint(jb, msg)) { + is_syncpoint = !jb->started || msg_is_syncpoint(jb, msg); + if (is_syncpoint) { jb->started = true; msg_set_as_reference(jb, msg); rel_delay = 0; @@ -365,8 +396,7 @@ int osmo_jibuf_enqueue(struct osmo_jibuf *jb, struct msgb *msg) jbcb->ts = sched_ts; jbcb->old_cb = old_cb; - llist_add_sorted(msg, &jb->msg_list); - + enqueue_pkt(jb, msg, is_syncpoint); /* See if updating the timer is needed: */ if (!osmo_timer_pending(&jb->timer) || diff --git a/src/osmux.c b/src/osmux.c index 46170ba..7a6ce60 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -356,7 +356,7 @@ struct osmux_circuit { static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit, uint8_t batch_factor) { - /* Too many messages per batch, discard it. The counter field of the + /* Validate amount of messages per batch. The counter field of the * osmux header is just 3 bits long, so make sure it doesn't overflow. */ if (circuit->nmsgs >= batch_factor || circuit->nmsgs >= 8) { @@ -366,7 +366,7 @@ static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit, if (rtph == NULL) return -1; - LOGP(DLMUX, LOGL_ERROR, "too many messages for this RTP " + LOGP(DLMUX, LOGL_DEBUG, "Batch is full for RTP " "ssrc=%u\n", rtph->ssrc); return -1; } diff --git a/src/stream.c b/src/stream.c index 9dcb94b..6eb2313 100644 --- a/src/stream.c +++ b/src/stream.c @@ -451,7 +451,7 @@ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect) ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto, cli->local_addr, cli->local_port, cli->addr, cli->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND); + OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); if (ret < 0) { if (reconnect) osmo_stream_cli_reconnect(cli); diff --git a/tests/jibuf/jibuf_test.c b/tests/jibuf/jibuf_test.c index 6e8c805..ba1bb01 100644 --- a/tests/jibuf/jibuf_test.c +++ b/tests/jibuf/jibuf_test.c @@ -619,7 +619,66 @@ static void test_rtp_marker(void) osmo_jibuf_delete(jb); } -void test_rtp_out_of_sync(unsigned int time_inc_ms, uint16_t seq_nosync_inc, uint32_t ts_nosync_inc, bool expect_drop) +/* This test aims at testing scenarios described in OS#3262, in which syncpoint + packets can provoke a situation in which packets are stored out-of-order in + the queue. */ +static void test_rtp_marker_queue_order() +{ + int min_delay = 60; + struct msgb *msg; + struct rtp_hdr *rtph; + + printf("===test_rtp_marker_queue_order===\n"); + + clock_override_enable(true); + clock_override_set(0, 0); + rtp_init(32, 400); + jb = osmo_jibuf_alloc(NULL); + osmo_jibuf_set_dequeue_cb(jb, dequeue_cb, NULL); + osmo_jibuf_set_min_delay(jb, min_delay); + osmo_jibuf_set_max_delay(jb, 200); + + /* First rtp at t=0, should be scheduled in min_delay time */ + clock_debug("enqueue 1st packet"); + ENQUEUE_NEXT(jb); + clock_override_add(0, TIME_RTP_PKT_MS*1000); + clock_debug("enqueue 2nd packet"); + ENQUEUE_NEXT(jb); + clock_override_add(0, TIME_RTP_PKT_MS*1000); + clock_debug("enqueue 3rd packet"); + ENQUEUE_NEXT(jb); + clock_override_add(0, TIME_RTP_PKT_MS*1000); + + /* We then emulate an scenario in which an Osmux queue in front of us + receives a new frame before expected time, which means the packets in + the osmux genreated rtp queue will be flushed and sent to jibuf + directly. On top, the first packet of the new frame has the RTP + Marker bit set. */ + clock_debug("enqueue 3 packets instantly"); + ENQUEUE_NEXT(jb); /* scheduled min_delay+0 */ + ENQUEUE_NEXT(jb); /* a min_delay+TIME_RTP_PKT_MS */ + ENQUEUE_NEXT(jb); /* scheduled min_delay+TIME_RTP_PKT_MS*2 */ + clock_debug("enqueue pkt with marker=1 instantly"); + msg = rtp_next(); + rtph = osmo_rtp_get_hdr(msg); + rtph->marker = 1; + OSMO_ASSERT(osmo_jibuf_enqueue(jb, msg) == 0); /* syncpoint, scheduled in min_delay+0 */ + osmo_select_main(0); + + clock_override_add(0, TIME_RTP_PKT_MS*1000); + clock_debug("enqueue pkt after syncpoint"); + ENQUEUE_NEXT(jb); /* scheduled min_delay+0 */ + + clock_debug("all packets dequeued"); + clock_override_add(0, min_delay*1000); + osmo_select_main(0); + + OSMO_ASSERT(osmo_jibuf_empty(jb)); + + osmo_jibuf_delete(jb); +} + +static void test_rtp_out_of_sync(unsigned int time_inc_ms, uint16_t seq_nosync_inc, uint32_t ts_nosync_inc, bool expect_drop) { int min_delay = 60; struct msgb *msg; @@ -686,7 +745,7 @@ void test_rtp_out_of_sync(unsigned int time_inc_ms, uint16_t seq_nosync_inc, uin } -void test_skew(unsigned int skew_inc_us, bool skew_compensation) { +static void test_skew(unsigned int skew_inc_us, bool skew_compensation) { int min_delay = 40; unsigned int dropped = 0; struct msgb *msg; @@ -754,6 +813,7 @@ int main(int argc, char **argv) test_seq_wraparound(); test_timestamp_wraparound(); test_rtp_marker(); + test_rtp_marker_queue_order(); test_rtp_out_of_sync(80*TIME_RTP_PKT_MS, 5, 5*SAMPLES_PER_PKT, true); test_rtp_out_of_sync(80*TIME_RTP_PKT_MS, 6, 5*SAMPLES_PER_PKT, false); test_rtp_out_of_sync(80*TIME_RTP_PKT_MS, 5, 5*SAMPLES_PER_PKT + 3, false); diff --git a/tests/jibuf/jibuf_test.ok b/tests/jibuf/jibuf_test.ok index e495435..b92f73c 100644 --- a/tests/jibuf/jibuf_test.ok +++ b/tests/jibuf/jibuf_test.ok @@ -365,6 +365,28 @@ sys={0.140000}, mono={0.140000}: 2 packets dequeued sys={0.200000}, mono={0.200000}: clock_override_add sys={0.200000}, mono={0.200000}: dequeue: seq=35 ts=880 INTERMEDIATE sys={0.200000}, mono={0.200000}: dequeue: seq=36 ts=1040 LATEST +===test_rtp_marker_queue_order=== +sys={0.000000}, mono={0.000000}: clock_override_set +sys={0.000000}, mono={0.000000}: enqueue 1st packet +sys={0.020000}, mono={0.020000}: clock_override_add +sys={0.020000}, mono={0.020000}: enqueue 2nd packet +sys={0.040000}, mono={0.040000}: clock_override_add +sys={0.040000}, mono={0.040000}: enqueue 3rd packet +sys={0.060000}, mono={0.060000}: clock_override_add +sys={0.060000}, mono={0.060000}: enqueue 3 packets instantly +sys={0.060000}, mono={0.060000}: enqueue pkt with marker=1 instantly +sys={0.060000}, mono={0.060000}: dequeue: seq=33 ts=560 INTERMEDIATE +sys={0.080000}, mono={0.080000}: clock_override_add +sys={0.080000}, mono={0.080000}: enqueue pkt after syncpoint +sys={0.080000}, mono={0.080000}: all packets dequeued +sys={0.140000}, mono={0.140000}: clock_override_add +sys={0.140000}, mono={0.140000}: dequeue: seq=34 ts=720 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=35 ts=880 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=36 ts=1040 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=37 ts=1200 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=38 ts=1360 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=39 ts=1520 INTERMEDIATE +sys={0.140000}, mono={0.140000}: dequeue: seq=40 ts=1680 LATEST ===test_rtp_out_of_sync(1600, 5, 800, 1)=== sys={0.000000}, mono={0.000000}: clock_override_set sys={0.000000}, mono={0.000000}: enqueue 1st packet (seq=33, ts=560) |