diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/configure.ac libosmo-abis-0.4.0/configure.ac --- libosmo-abis-0.3.2+20151106git86fc3c8/configure.ac 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/configure.ac 2017-08-25 14:12:37.000000000 +0000 @@ -2,20 +2,37 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc@lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) AC_CONFIG_TESTDIR(tests) dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +dnl include release helper +RELMAKE='-include osmo-release.mk' +AC_SUBST([RELMAKE]) + dnl checks for programs AC_PROG_MAKE_SET AC_PROG_CC AC_PROG_INSTALL LT_INIT([pic-only]) +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + AC_CONFIG_MACRO_DIR([m4]) +CFLAGS="$CFLAGS -Wall" +CPPFLAGS="$CPPFLAGS -Wall" + # The following test is taken from WebKit's webkit.m4 saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden " @@ -33,18 +50,50 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.10) -PKG_CHECK_MODULES([ORTP], [ortp >= 0.13.1], - [ - PKG_CHECK_MODULES([ORTP_VERSION], [ortp >= 0.21], - [AC_DEFINE(HAVE_ORTP_021, 1, - [libortp >= 0.21])], - [AC_DEFINE(HAVE_ORTP_021, 0, - [libortp < 0.21])]) - ] -) +PKG_CHECK_MODULES(ORTP, ortp >= 0.22.0) AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built)) +AC_ARG_ENABLE(sanitize, + [AS_HELP_STRING( + [--enable-sanitize], + [Compile with address sanitizer enabled], + )], + [sanitize=$enableval], [sanitize="no"]) +if test x"$sanitize" = x"yes" +then + CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined" + CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined" +fi + +_cflags_save=$CFLAGS +CFLAGS="$CFLAGS $ORTP_CFLAGS" +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ortp_set_log_level_mask(NULL, 0xffff);]] + )], + [AC_DEFINE([HAVE_ORTP_LOG_DOMAIN], [1], + [ortp_set_log_level_mask requires domain parameter])], + [AC_DEFINE([HAVE_ORTP_LOG_DOMAIN], [0], + [ortp_set_log_level_mask has no domain parameter])]) +CFLAGS=$_cflags_save + +_cflags_save=$CFLAGS +CFLAGS="$CFLAGS $ORTP_CFLAGS" +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + void fake_cb(struct _RtpSession *r, void *arg1, void *arg2, void *arg3) { return; }]], + [[rtp_session_signal_connect(NULL, "", fake_cb, (void*) fake_cb);]] + )], + [AC_DEFINE([RTP_SIGNAL_PTR_CAST(arg)], [(void*)(arg)], + [rtp_session_signal_connect requires pointer parameter])], + [AC_DEFINE([RTP_SIGNAL_PTR_CAST(arg)], [(unsigned long)(arg)], + [rtp_session_signal_connect requires ulong parameter])]) +CFLAGS=$_cflags_save + + AC_OUTPUT( libosmoabis.pc libosmotrau.pc diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/contrib/jenkins.sh libosmo-abis-0.4.0/contrib/jenkins.sh --- libosmo-abis-0.3.2+20151106git86fc3c8/contrib/jenkins.sh 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/contrib/jenkins.sh 2017-08-25 14:12:37.000000000 +0000 @@ -0,0 +1,38 @@ +#!/bin/sh +# jenkins build helper script for libosmo-abis. This is how we build on jenkins.osmocom.org + +if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then + echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !" + exit 2 +fi + +set -ex + +base="$PWD" +deps="$base/deps" +inst="$deps/install" +export deps inst + +mkdir "$deps" || true +rm -rf "$inst" + +osmo-build-dep.sh libosmocore + +"$deps"/libosmocore/contrib/verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]") + +export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" +export LD_LIBRARY_PATH="$inst/lib" + +set +x +echo +echo +echo +echo " =============================== libosmo-abis ===============================" +echo +set -x + +autoreconf --install --force +./configure --enable-sanitize CFLAGS="-Werror" CPPFLAGS="-Werror" +$MAKE $PARALLEL_MAKE +$MAKE distcheck \ + || cat-testlogs.sh diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/changelog libosmo-abis-0.4.0/debian/changelog --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/changelog 2017-09-11 17:11:12.000000000 +0000 +++ libosmo-abis-0.4.0/debian/changelog 2018-04-09 17:17:13.000000000 +0000 @@ -1,3 +1,22 @@ +libosmo-abis (0.4.0-2) unstable; urgency=medium + + * move to unstable + * debian/control: bump standard to 4.1.4 (no changes) + * debian/control: add salsa URLs + * debian/control: use dh11 + + -- Thorsten Alteholz Mon, 09 Apr 2018 18:55:37 +0100 + +libosmo-abis (0.4.0-1) experimental; urgency=medium + + * New upstream release + * debian/control: SONAME bump of libosmoabis6 and libosmotrau2 + * debian/control: bump standard to 4.1.1 (no changes) + * update symbols files + * add spelling patch + + -- Thorsten Alteholz Tue, 28 Nov 2017 18:55:37 +0100 + libosmo-abis (0.3.2+20151106git86fc3c8-3) unstable; urgency=medium * debian/control: add myself to uploaders diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/compat libosmo-abis-0.4.0/debian/compat --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/compat 2017-09-11 11:57:38.000000000 +0000 +++ libosmo-abis-0.4.0/debian/compat 2018-04-09 17:16:55.000000000 +0000 @@ -1 +1 @@ -10 +11 diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/control libosmo-abis-0.4.0/debian/control --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/control 2017-09-11 17:11:12.000000000 +0000 +++ libosmo-abis-0.4.0/debian/control 2018-04-09 17:16:55.000000000 +0000 @@ -4,17 +4,18 @@ , Thorsten Alteholz Section: libs Priority: optional -Build-Depends: debhelper (>= 10), +Build-Depends: debhelper (>= 11), libdpkg-perl, - libosmocore-dev, + libosmocore-dev (>= 0.9.1), + libtalloc-dev, pkg-config, libortp-dev -Standards-Version: 4.1.0 +Standards-Version: 4.1.4 Vcs-Browser: https://anonscm.debian.org/cgit/debian-mobcom/libosmo-abis.git Vcs-Git: https://anonscm.debian.org/git/debian-mobcom/libosmo-abis.git Homepage: http://openbsc.osmocom.org/trac/wiki/libosmo-abis -Package: libosmoabis5 +Package: libosmoabis6 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, @@ -26,7 +27,7 @@ It also implements drivers for mISDN and DAHDI based E1 cards, as well as some A-bis/IP dialects. -Package: libosmotrau1 +Package: libosmotrau2 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, @@ -43,8 +44,8 @@ Multi-Arch: same Section: libdevel Depends: ${misc:Depends}, - libosmotrau1 (= ${binary:Version}), - libosmoabis5 (= ${binary:Version}) + libosmotrau2 (= ${binary:Version}), + libosmoabis6 (= ${binary:Version}) Description: Development headers for A-bis interface The libosmo-abis library contains common/shared code regarding the A-bis interface between GSM BTS and BSC. This package in particular contains the @@ -56,8 +57,8 @@ #Multi-Arch: same #Section: debug #Priority: extra -#Depends: libosmoabis5 (= ${binary:Version}), -# libosmotrau1 (= ${binary:Version}), +#Depends: libosmoabis6 (= ${binary:Version}), +# libosmotrau2 (= ${binary:Version}), # ${misc:Depends} #Description: Debug symbols for A-bis interface # The libosmo-abis library contains common/shared code regarding the A-bis diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/copyright libosmo-abis-0.4.0/debian/copyright --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/copyright 2017-09-11 17:11:12.000000000 +0000 +++ libosmo-abis-0.4.0/debian/copyright 2018-04-09 17:16:55.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: libosmocore Source: git://git.osmocom.org/libosmo-abis.git diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis5.install libosmo-abis-0.4.0/debian/libosmoabis5.install --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis5.install 2017-09-11 09:52:10.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmoabis5.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/libosmoabis.so.* diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis5.symbols libosmo-abis-0.4.0/debian/libosmoabis5.symbols --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis5.symbols 2017-09-11 09:52:10.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmoabis5.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -libosmoabis.so.5 libosmoabis5 #MINVER# - abis_rsl_sendmsg@Base 0.3.2+20151106git86fc3c8 - abis_sendmsg@Base 0.3.2+20151106git86fc3c8 - decode_trau_frame@Base 0.3.2+20151106git86fc3c8 - e1_set_pcap_fd@Base 0.3.2+20151106git86fc3c8 - e1inp_close_socket@Base 0.3.2+20151106git86fc3c8 - e1inp_dlsap_up@Base 0.3.2+20151106git86fc3c8 - e1inp_driver_find@Base 0.3.2+20151106git86fc3c8 - e1inp_driver_list@Base 0.3.2+20151106git86fc3c8 - e1inp_driver_register@Base 0.3.2+20151106git86fc3c8 - e1inp_event@Base 0.3.2+20151106git86fc3c8 - e1inp_get_mux@Base 0.3.2+20151106git86fc3c8 - e1inp_init@Base 0.3.2+20151106git86fc3c8 - e1inp_ipa_bts_rsl_connect@Base 0.3.2+20151106git86fc3c8 - e1inp_ipa_bts_rsl_connect_n@Base 0.3.2+20151106git86fc3c8 - e1inp_ipaccess_init@Base 0.3.2+20151106git86fc3c8 - e1inp_line_bind_ops@Base 0.3.2+20151106git86fc3c8 - e1inp_line_clone@Base 0.3.2+20151106git86fc3c8 - e1inp_line_create@Base 0.3.2+20151106git86fc3c8 - e1inp_line_find@Base 0.3.2+20151106git86fc3c8 - e1inp_line_get@Base 0.3.2+20151106git86fc3c8 - e1inp_line_list@Base 0.3.2+20151106git86fc3c8 - e1inp_line_put@Base 0.3.2+20151106git86fc3c8 - e1inp_line_update@Base 0.3.2+20151106git86fc3c8 - e1inp_lookup_sign_link@Base 0.3.2+20151106git86fc3c8 - e1inp_misdn_init@Base 0.3.2+20151106git86fc3c8 - e1inp_node@Base 0.3.2+20151106git86fc3c8 - e1inp_rs232_init@Base 0.3.2+20151106git86fc3c8 - e1inp_rx_ts@Base 0.3.2+20151106git86fc3c8 - e1inp_rx_ts_lapd@Base 0.3.2+20151106git86fc3c8 - e1inp_sign_link_create@Base 0.3.2+20151106git86fc3c8 - e1inp_sign_link_destroy@Base 0.3.2+20151106git86fc3c8 - e1inp_signtype_name@Base 0.3.2+20151106git86fc3c8 - e1inp_ts_config_sign@Base 0.3.2+20151106git86fc3c8 - e1inp_ts_config_trau@Base 0.3.2+20151106git86fc3c8 - e1inp_tstype_name@Base 0.3.2+20151106git86fc3c8 - e1inp_tx_ts@Base 0.3.2+20151106git86fc3c8 - e1inp_vty_init@Base 0.3.2+20151106git86fc3c8 - encode_trau_frame@Base 0.3.2+20151106git86fc3c8 - ft_data_down_bits@Base 0.3.2+20151106git86fc3c8 - ft_fr_down_bits@Base 0.3.2+20151106git86fc3c8 - ft_idle_down_bits@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_clear_queue@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_close@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_create@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_destroy@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_open@Base 0.3.2+20151106git86fc3c8 - ipa_client_conn_send@Base 0.3.2+20151106git86fc3c8 - ipa_msg_push_header@Base 0.3.2+20151106git86fc3c8 - ipa_node@Base 0.3.2+20151106git86fc3c8 - ipa_proxy_vty_init@Base 0.3.2+20151106git86fc3c8 - ipa_server_conn_create@Base 0.3.2+20151106git86fc3c8 - ipa_server_conn_destroy@Base 0.3.2+20151106git86fc3c8 - ipa_server_conn_send@Base 0.3.2+20151106git86fc3c8 - ipa_server_link_close@Base 0.3.2+20151106git86fc3c8 - ipa_server_link_create@Base 0.3.2+20151106git86fc3c8 - ipa_server_link_destroy@Base 0.3.2+20151106git86fc3c8 - ipa_server_link_open@Base 0.3.2+20151106git86fc3c8 - ipaccess_bts_handle_ccm@Base 0.3.2+20151106git86fc3c8 - ipaccess_driver@Base 0.3.2+20151106git86fc3c8 - ipaccess_fd_cb@Base 0.3.2+20151106git86fc3c8 - lapd_instance_alloc@Base 0.3.2+20151106git86fc3c8 - lapd_instance_free@Base 0.3.2+20151106git86fc3c8 - lapd_profile_abis@Base 0.3.2+20151106git86fc3c8 - lapd_profile_isdn@Base 0.3.2+20151106git86fc3c8 - lapd_profile_sat@Base 0.3.2+20151106git86fc3c8 - lapd_receive@Base 0.3.2+20151106git86fc3c8 - lapd_sap_start@Base 0.3.2+20151106git86fc3c8 - lapd_sap_stop@Base 0.3.2+20151106git86fc3c8 - lapd_tei_alloc@Base 0.3.2+20151106git86fc3c8 - lapd_tei_states@Base 0.3.2+20151106git86fc3c8 - lapd_transmit@Base 0.3.2+20151106git86fc3c8 - libosmo_abis_ctx@Base 0.3.2+20151106git86fc3c8 - libosmo_abis_init@Base 0.3.2+20151106git86fc3c8 - misdn_driver@Base 0.3.2+20151106git86fc3c8 - misdn_lapd_driver@Base 0.3.2+20151106git86fc3c8 - osmo_pcap_lapd_close@Base 0.3.2+20151106git86fc3c8 - osmo_pcap_lapd_open@Base 0.3.2+20151106git86fc3c8 - osmo_pcap_lapd_write@Base 0.3.2+20151106git86fc3c8 - prim_names@Base 0.3.2+20151106git86fc3c8 - subch_demux_activate@Base 0.3.2+20151106git86fc3c8 - subch_demux_deactivate@Base 0.3.2+20151106git86fc3c8 - subch_demux_in@Base 0.3.2+20151106git86fc3c8 - subch_demux_init@Base 0.3.2+20151106git86fc3c8 - subchan_mux_enqueue@Base 0.3.2+20151106git86fc3c8 - subchan_mux_init@Base 0.3.2+20151106git86fc3c8 - subchan_mux_out@Base 0.3.2+20151106git86fc3c8 - tall_tqe_ctx@Base 0.3.2+20151106git86fc3c8 - trau_frame_up2down@Base 0.3.2+20151106git86fc3c8 - trau_idle_frame@Base 0.3.2+20151106git86fc3c8 diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis6.install libosmo-abis-0.4.0/debian/libosmoabis6.install --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis6.install 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmoabis6.install 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*/libosmoabis.so.* diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis6.symbols libosmo-abis-0.4.0/debian/libosmoabis6.symbols --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmoabis6.symbols 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmoabis6.symbols 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1,105 @@ +libosmoabis.so.6 libosmoabis6 #MINVER# + abis_rsl_sendmsg@Base 0.4.0 + abis_sendmsg@Base 0.4.0 + decode_trau_frame@Base 0.4.0 + e1_set_pcap_fd@Base 0.4.0 + e1inp_close_socket@Base 0.4.0 + e1inp_dlsap_up@Base 0.4.0 + e1inp_driver_find@Base 0.4.0 + e1inp_driver_list@Base 0.4.0 + e1inp_driver_register@Base 0.4.0 + e1inp_ericsson_set_altc@Base 0.4.0 + e1inp_event@Base 0.4.0 + e1inp_get_mux@Base 0.4.0 + e1inp_init@Base 0.4.0 + e1inp_ipa_bts_rsl_connect@Base 0.4.0 + e1inp_ipa_bts_rsl_connect_n@Base 0.4.0 + e1inp_ipa_get_bind_addr@Base 0.4.0 + e1inp_ipa_set_bind_addr@Base 0.4.0 + e1inp_ipaccess_init@Base 0.4.0 + e1inp_line_bind_ops@Base 0.4.0 + e1inp_line_clone@Base 0.4.0 + e1inp_line_create@Base 0.4.0 + e1inp_line_find@Base 0.4.0 + e1inp_line_get@Base 0.4.0 + e1inp_line_list@Base 0.4.0 + e1inp_line_put@Base 0.4.0 + e1inp_line_update@Base 0.4.0 + e1inp_lookup_sign_link@Base 0.4.0 + e1inp_misdn_init@Base 0.4.0 + e1inp_node@Base 0.4.0 + e1inp_rs232_init@Base 0.4.0 + e1inp_rx_ts@Base 0.4.0 + e1inp_rx_ts_lapd@Base 0.4.0 + e1inp_sign_link_create@Base 0.4.0 + e1inp_sign_link_destroy@Base 0.4.0 + e1inp_sign_type_names@Base 0.4.0 + e1inp_signal_names@Base 0.4.0 + e1inp_signtype_name@Base 0.4.0 + e1inp_ts_config_hdlc@Base 0.4.0 + e1inp_ts_config_raw@Base 0.4.0 + e1inp_ts_config_sign@Base 0.4.0 + e1inp_ts_config_trau@Base 0.4.0 + e1inp_ts_type_names@Base 0.4.0 + e1inp_tstype_name@Base 0.4.0 + e1inp_tx_ts@Base 0.4.0 + e1inp_unixsocket_init@Base 0.4.0 + e1inp_vty_init@Base 0.4.0 + encode_trau_frame@Base 0.4.0 + ft_data_down_bits@Base 0.4.0 + ft_fr_down_bits@Base 0.4.0 + ft_idle_down_bits@Base 0.4.0 + ipa_client_conn_clear_queue@Base 0.4.0 + ipa_client_conn_close@Base 0.4.0 + ipa_client_conn_create@Base 0.4.0 + ipa_client_conn_destroy@Base 0.4.0 + ipa_client_conn_open@Base 0.4.0 + ipa_client_conn_send@Base 0.4.0 + ipa_msg_push_header@Base 0.4.0 + ipa_node@Base 0.4.0 + ipa_proxy_vty_init@Base 0.4.0 + ipa_server_conn_ccm@Base 0.4.0 + ipa_server_conn_create@Base 0.4.0 + ipa_server_conn_destroy@Base 0.4.0 + ipa_server_conn_send@Base 0.4.0 + ipa_server_link_close@Base 0.4.0 + ipa_server_link_create@Base 0.4.0 + ipa_server_link_destroy@Base 0.4.0 + ipa_server_link_open@Base 0.4.0 + ipaccess_bts_handle_ccm@Base 0.4.0 + ipaccess_driver@Base 0.4.0 + ipaccess_fd_cb@Base 0.4.0 + lapd_instance_alloc@Base 0.4.0 + lapd_instance_free@Base 0.4.0 + lapd_instance_set_profile@Base 0.4.0 + lapd_profile_abis@Base 0.4.0 + lapd_profile_abis_ericsson@Base 0.4.0 + lapd_profile_isdn@Base 0.4.0 + lapd_profile_sat@Base 0.4.0 + lapd_receive@Base 0.4.0 + lapd_sap_start@Base 0.4.0 + lapd_sap_stop@Base 0.4.0 + lapd_tei_alloc@Base 0.4.0 + lapd_tei_states@Base 0.4.0 + lapd_transmit@Base 0.4.0 + libosmo_abis_ctx@Base 0.4.0 + libosmo_abis_init@Base 0.4.0 + misdn_driver@Base 0.4.0 + misdn_lapd_driver@Base 0.4.0 + osmo_pcap_lapd_close@Base 0.4.0 + osmo_pcap_lapd_open@Base 0.4.0 + osmo_pcap_lapd_set_fd@Base 0.4.0 + osmo_pcap_lapd_write@Base 0.4.0 + prim_names@Base 0.4.0 + subch_demux_activate@Base 0.4.0 + subch_demux_deactivate@Base 0.4.0 + subch_demux_in@Base 0.4.0 + subch_demux_init@Base 0.4.0 + subchan_mux_enqueue@Base 0.4.0 + subchan_mux_init@Base 0.4.0 + subchan_mux_out@Base 0.4.0 + tall_tqe_ctx@Base 0.4.0 + tall_unixsocket_ctx@Base 0.4.0 + trau_frame_up2down@Base 0.4.0 + trau_idle_frame@Base 0.4.0 + unixsocket_driver@Base 0.4.0 diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau1.install libosmo-abis-0.4.0/debian/libosmotrau1.install --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau1.install 2017-09-11 09:52:10.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmotrau1.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/libosmotrau.so.* diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau1.symbols libosmo-abis-0.4.0/debian/libosmotrau1.symbols --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau1.symbols 2017-09-11 09:52:10.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmotrau1.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -libosmotrau.so.1 libosmotrau1 #MINVER# - osmo_rtp_get_bound_addr@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_get_bound_ip_port@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_init@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_send_frame@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_bind@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_connect@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_create@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_free@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_log_stats@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_poll@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_set_param@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_set_pt@Base 0.3.2+20151106git86fc3c8 - osmo_rtp_socket_stats@Base 0.3.2+20151106git86fc3c8 diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau2.install libosmo-abis-0.4.0/debian/libosmotrau2.install --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau2.install 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmotrau2.install 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*/libosmotrau.so.* diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau2.symbols libosmo-abis-0.4.0/debian/libosmotrau2.symbols --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/libosmotrau2.symbols 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/libosmotrau2.symbols 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1,16 @@ +libosmotrau.so.2 libosmotrau2 #MINVER# + osmo_rtp_get_bound_addr@Base 0.4.0 + osmo_rtp_get_bound_ip_port@Base 0.4.0 + osmo_rtp_init@Base 0.4.0 + osmo_rtp_send_frame@Base 0.4.0 + osmo_rtp_send_frame_ext@Base 0.4.0 + osmo_rtp_skipped_frame@Base 0.4.0 + osmo_rtp_socket_bind@Base 0.4.0 + osmo_rtp_socket_connect@Base 0.4.0 + osmo_rtp_socket_create@Base 0.4.0 + osmo_rtp_socket_free@Base 0.4.0 + osmo_rtp_socket_log_stats@Base 0.4.0 + osmo_rtp_socket_poll@Base 0.4.0 + osmo_rtp_socket_set_param@Base 0.4.0 + osmo_rtp_socket_set_pt@Base 0.4.0 + osmo_rtp_socket_stats@Base 0.4.0 diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/patches/series libosmo-abis-0.4.0/debian/patches/series --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/patches/series 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1 @@ +spelling.patch diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/patches/spelling.patch libosmo-abis-0.4.0/debian/patches/spelling.patch --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/patches/spelling.patch 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/debian/patches/spelling.patch 2018-04-08 17:45:38.000000000 +0000 @@ -0,0 +1,15 @@ +Description: fix spelling that was detected by lintian +Author: Thorsten Alteholz +Index: libosmo-abis-0.4.0/src/input/ipa.c +=================================================================== +--- libosmo-abis-0.4.0.orig/src/input/ipa.c 2017-08-25 16:12:37.000000000 +0200 ++++ libosmo-abis-0.4.0/src/input/ipa.c 2017-11-28 15:29:11.274860753 +0100 +@@ -265,7 +265,7 @@ + ret = link->accept_cb(link, fd); + if (ret < 0) { + LOGP(DLINP, LOGL_ERROR, +- "failed to processs accept()ed new link, " ++ "failed to process accept()ed new link, " + "reason=`%s'\n", strerror(-ret)); + close(fd); + return ret; diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/debian/watch libosmo-abis-0.4.0/debian/watch --- libosmo-abis-0.3.2+20151106git86fc3c8/debian/watch 2017-09-11 09:52:10.000000000 +0000 +++ libosmo-abis-0.4.0/debian/watch 2018-04-08 17:45:38.000000000 +0000 @@ -1,2 +1,2 @@ -version=3 -https://github.com/osmocom/libosmo-abis/releases /osmocom/libosmo-abis/archive/(\d\S+)\.tar\.(?:bz2|gz|xz) +version=4 +opts="mode=git, dversionmangle=s/\+ds//" https://git.osmocom.org/libosmo-abis refs/tags/([\d\.]+) debian uupdate diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/.gitignore libosmo-abis-0.4.0/.gitignore --- libosmo-abis-0.3.2+20151106git86fc3c8/.gitignore 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/.gitignore 2017-08-25 14:12:37.000000000 +0000 @@ -21,10 +21,12 @@ ltmain.sh install-sh stamp-h1 -libtool #libosmo-abis-* tests/*_test +# libtool and e.g. arm-poky-linux-gnueabi-libtool +*libtool + .tarball-version .version .dirstamp diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/.gitreview libosmo-abis-0.4.0/.gitreview --- libosmo-abis-0.3.2+20151106git86fc3c8/.gitreview 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/.gitreview 2017-08-25 14:12:37.000000000 +0000 @@ -0,0 +1,3 @@ +[gerrit] +host=gerrit.osmocom.org +project=libosmo-abis diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/internal.h libosmo-abis-0.4.0/include/internal.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/internal.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/internal.h 2017-08-25 14:12:37.000000000 +0000 @@ -13,6 +13,9 @@ /* use libosmo_abis_init, this is only for internal use. */ void e1inp_init(void); +void e1inp_ipa_set_bind_addr(const char *ip_bind_addr); +const char *e1inp_ipa_get_bind_addr(void); + /* ipaccess.c requires these functions defined here */ struct msgb; struct msgb *ipa_msg_alloc(int headroom); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/Makefile.am libosmo-abis-0.4.0/include/Makefile.am --- libosmo-abis-0.3.2+20151106git86fc3c8/include/Makefile.am 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/Makefile.am 2017-08-25 14:12:37.000000000 +0000 @@ -3,4 +3,5 @@ nobase_include_HEADERS = osmocom/abis/ipa.h osmocom/abis/trau_frame.h \ osmocom/abis/ipa_proxy.h osmocom/abis/ipaccess.h osmocom/abis/abis.h \ osmocom/abis/subchan_demux.h osmocom/abis/e1_input.h \ - osmocom/abis/lapd.h osmocom/abis/lapd_pcap.h osmocom/trau/osmo_ortp.h + osmocom/abis/lapd.h osmocom/abis/lapd_pcap.h osmocom/trau/osmo_ortp.h \ + osmocom/abis/unixsocket_proto.h diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/e1_input.h libosmo-abis-0.4.0/include/osmocom/abis/e1_input.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/e1_input.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/abis/e1_input.h 2017-08-25 14:12:37.000000000 +0000 @@ -21,6 +21,7 @@ E1INP_SIGN_OSMO, /* IPA CCM OSMO sub-type */ }; const char *e1inp_signtype_name(enum e1inp_sign_type tp); +extern const struct value_string e1inp_sign_type_names[5]; enum e1inp_ctr { E1I_CTR_HDLC_ABORT, @@ -63,8 +64,11 @@ E1INP_TS_TYPE_NONE, E1INP_TS_TYPE_SIGN, E1INP_TS_TYPE_TRAU, + E1INP_TS_TYPE_RAW, + E1INP_TS_TYPE_HDLC, }; const char *e1inp_tstype_name(enum e1inp_ts_type tp); +extern const struct value_string e1inp_ts_type_names[6]; /* A timeslot in the E1 interface */ struct e1inp_ts { @@ -92,6 +96,18 @@ /* subchannel muxer for frames to E1 */ struct subch_mux mux; } trau; + struct { + /* call-back for every received frame */ + void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg); + /* queue of pending to-be-transmitted msgbs */ + struct llist_head tx_queue; + } raw; + struct { + /* call-back for every received frame */ + void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg); + /* queue of pending to-be-transmitted msgbs */ + struct llist_head tx_queue; + } hdlc; }; union { struct { @@ -139,6 +155,7 @@ void (*vty_show)(struct vty *vty, struct e1inp_line *line); int default_delay; int has_keepalive; + const char *bind_addr; }; struct e1inp_line_ops { @@ -166,6 +183,7 @@ unsigned int num; const char *name; unsigned int port_nr; + char *sock_path; struct rate_ctr_group *rate_ctr; /* keepalive configuration */ @@ -194,15 +212,14 @@ S_L_INP_LINE_NOALARM, }; +extern const struct value_string e1inp_signal_names[]; + /* register a driver with the E1 core */ int e1inp_driver_register(struct e1inp_driver *drv); /* fine a previously registered driver */ struct e1inp_driver *e1inp_driver_find(const char *name); -/* register a line with the E1 core */ -int e1inp_line_register(struct e1inp_line *line); - /* get a line by its ID */ struct e1inp_line *e1inp_line_find(uint8_t e1_nr); @@ -240,8 +257,15 @@ int (*trau_rcv_cb)(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *_priv)); -/* Call from the Stack: configuration of this TS has changed */ -int e1inp_update_ts(struct e1inp_ts *ts); +/* configure and initialize one timeslot dedicated to RAW frames */ +int e1inp_ts_config_raw(struct e1inp_ts *ts, struct e1inp_line *line, + void (*raw_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)); + +/* configure and initialize one timeslot dedicated to HDLC frames */ +int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line, + void (*hdlc_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)); /* Receive a packet from the E1 driver */ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, @@ -282,6 +306,9 @@ struct gsm_network; int ipaccess_setup(struct gsm_network *gsmnet); +/* activate superchannel or deactive to use timeslots. only valid for unixsocket driver */ +void e1inp_ericsson_set_altc(struct e1inp_line *unixlinue, int superchannel); + extern struct llist_head e1inp_driver_list; extern struct llist_head e1inp_line_list; @@ -290,6 +317,7 @@ int link_type; uint8_t tei; uint8_t sapi; + uint8_t ts_nr; struct gsm_bts_trx *trx; struct e1inp_line *line; }; diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/ipa.h libosmo-abis-0.4.0/include/osmocom/abis/ipa.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/ipa.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/abis/ipa.h 2017-08-25 14:12:37.000000000 +0000 @@ -35,9 +35,14 @@ struct osmo_fd ofd; struct llist_head tx_queue; int (*closed_cb)(struct ipa_server_conn *peer); + int (*ccm_cb)(struct ipa_server_conn *peer, struct msgb *msg, + struct tlv_parsed *tlvp, struct ipaccess_unit *ud); int (*cb)(struct ipa_server_conn *peer, struct msgb *msg); void *data; struct msgb *pending_msg; + /* remote address information */ + const char *addr; + uint16_t port; }; struct ipa_server_conn * @@ -48,6 +53,7 @@ void ipa_server_conn_destroy(struct ipa_server_conn *peer); void ipa_server_conn_send(struct ipa_server_conn *peer, struct msgb *msg); +int ipa_server_conn_ccm(struct ipa_server_conn *conn, struct msgb *msg); enum ipa_client_conn_state { IPA_CLIENT_LINK_STATE_NONE = 0, diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/lapd.h libosmo-abis-0.4.0/include/osmocom/abis/lapd.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/lapd.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/abis/lapd.h 2017-08-25 14:12:37.000000000 +0000 @@ -18,8 +18,10 @@ int short_address; }; +/* predefined lapd profiles (see lapd.c for definition) */ extern const struct lapd_profile lapd_profile_isdn; extern const struct lapd_profile lapd_profile_abis; +extern const struct lapd_profile lapd_profile_abis_ericsson; extern const struct lapd_profile lapd_profile_sat; struct lapd_instance { @@ -63,6 +65,13 @@ void *rx_cbdata), void *rx_cbdata, const struct lapd_profile *profile); +/* In rare cases (e.g. Ericsson's lapd dialect), it may be necessary to + * exchange the lapd profile on the fly. lapd_instance_set_profile() + * allwos to set the lapd profile on a lapd instance danymically to + * one of the lapd profiles define above. */ +void lapd_instance_set_profile(struct lapd_instance *li, + const struct lapd_profile *profile); + void lapd_instance_free(struct lapd_instance *li); /* Start a (user-side) SAP for the specified TEI/SAPI on the LAPD instance */ diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/lapd_pcap.h libosmo-abis-0.4.0/include/osmocom/abis/lapd_pcap.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/lapd_pcap.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/abis/lapd_pcap.h 2017-08-25 14:12:37.000000000 +0000 @@ -1,10 +1,14 @@ #ifndef _LAPD_PCAP_H_ #define _LAPD_PCAP_H_ +#include +#include + #define OSMO_LAPD_PCAP_INPUT 0 #define OSMO_LAPD_PCAP_OUTPUT 1 int osmo_pcap_lapd_open(char *filename, mode_t mode); +int osmo_pcap_lapd_set_fd(int fd); int osmo_pcap_lapd_write(int fd, int direction, struct msgb *msg); int osmo_pcap_lapd_close(int fd); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/unixsocket_proto.h libosmo-abis-0.4.0/include/osmocom/abis/unixsocket_proto.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/abis/unixsocket_proto.h 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/abis/unixsocket_proto.h 2017-08-25 14:12:37.000000000 +0000 @@ -0,0 +1,31 @@ + +#ifndef UNIXSOCKET_PROTO_H +#define UNIXSOCKET_PROTO_H + +/* The unix socket protocol is using a 2 byte header + * containg the version and type. + * + * header: | 1b version | 1b type | + * + * for data packets it would be + * + * data: | 0x1 | 0x0 | lapd ..| + * control: | 0x1 | 0x1 | control payload | + * + * Atm there is only one control packet: + * - set_altc (superchannel or timeslot) + * + * set_altc payload: + * | 4b magic | 1b new_state| + * | 0x23004200 | 0x0 | to timeslot + * | 0x23004200 | 0x1 | to superchannel + */ + +#define UNIXSOCKET_PROTO_VERSION 0x1 + +enum { + UNIXSOCKET_PROTO_DATA = 0x0, + UNIXSOCKET_PROTO_CONTROL = 0x1, +}; + +#endif /* UNIXSOCKET_PROTO_H */ diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/trau/osmo_ortp.h libosmo-abis-0.4.0/include/osmocom/trau/osmo_ortp.h --- libosmo-abis-0.3.2+20151106git86fc3c8/include/osmocom/trau/osmo_ortp.h 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/include/osmocom/trau/osmo_ortp.h 2017-08-25 14:12:37.000000000 +0000 @@ -2,6 +2,7 @@ #define _OSMO_ORTP_H #include +#include #include #include @@ -21,6 +22,15 @@ /*! \brief Osmocom pseudo-static paylaod type for Adaptive Multi Rate (AMR) */ #define RTP_PT_AMR 98 +#define GSM_VOICE_SAMPLE_RATE_HZ 8000 +#define GSM_VOICE_SAMPLES_PER_MS (GSM_VOICE_SAMPLE_RATE_HZ / 1000) +#define GSM_VOICE_MULTIFRAME 26 +#define GSM_RTP_FRAME_DURATION_MS 20 +#define GSM_SAMPLES_PER_RTP_FRAME (GSM_RTP_FRAME_DURATION_MS * GSM_VOICE_SAMPLES_PER_MS) +#define GSM_TDMA_FRAME_MS (120 / GSM_VOICE_MULTIFRAME) +#define GSM_MS_TO_SAMPLES(ms) ((ms) * GSM_VOICE_SAMPLES_PER_MS) +#define GSM_FN_TO_MS(fn) ((fn) * GSM_TDMA_FRAME_MS) + /*! \brief Parameter to osmo_rtp_socket_param_set() */ enum osmo_rtp_param { OSMO_RTP_P_JITBUF = 1, @@ -29,6 +39,7 @@ /*! \brief Flag to indicate the socket is in polling-only mode */ #define OSMO_RTP_F_POLL 0x0001 +#define OSMO_RTP_F_DISABLED 0x0002 /*! \brief A structure representing one RTP socket */ struct osmo_rtp_socket { @@ -44,7 +55,8 @@ /*! \brief callback for incoming data */ void (*rx_cb)(struct osmo_rtp_socket *rs, const uint8_t *payload, - unsigned int payload_len); + unsigned int payload_len, uint16_t seq_number, + uint32_t timestamp, bool marker); /*! \brief Receive user timestamp, to be incremented by user */ uint32_t rx_user_ts; @@ -64,8 +76,12 @@ int osmo_rtp_socket_connect(struct osmo_rtp_socket *rs, const char *ip, uint16_t port); int osmo_rtp_socket_set_pt(struct osmo_rtp_socket *rs, int payload_type); int osmo_rtp_socket_free(struct osmo_rtp_socket *rs); +int osmo_rtp_skipped_frame(struct osmo_rtp_socket *rs, unsigned int duration); int osmo_rtp_send_frame(struct osmo_rtp_socket *rs, const uint8_t *payload, unsigned int payload_len, unsigned int duration); +int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload, + unsigned int payload_len, unsigned int duration, + bool marker); int osmo_rtp_socket_poll(struct osmo_rtp_socket *rs); int osmo_rtp_get_bound_ip_port(struct osmo_rtp_socket *rs, diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/Makefile.am libosmo-abis-0.4.0/Makefile.am --- libosmo-abis-0.3.2+20151106git86fc3c8/Makefile.am 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/Makefile.am 2017-08-25 14:12:37.000000000 +0000 @@ -11,3 +11,7 @@ echo $(VERSION) > $@-t && mv $@-t $@ dist-hook: echo $(VERSION) > $(distdir)/.tarball-version + +EXTRA_DIST = .version README.md + +@RELMAKE@ diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/README.md libosmo-abis-0.4.0/README.md --- libosmo-abis-0.3.2+20151106git86fc3c8/README.md 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/README.md 2017-08-25 14:12:37.000000000 +0000 @@ -0,0 +1,66 @@ +libosmo-abis - Osmocom Abis interface library +============================================= + +This repository contains a set of C-language libraries that form the +A-bis interface library of [Osmocom](https://osmocom.org/) Open Source +Mobile Communications projects such as OpenBSC / OsmoBSC. + +Historically, a lot of this code was developed as part of the +[OpenBSC](https://osmocom.org/projects/openbsc) project, but which are +of a more generic nature and thus useful to (at least) other programs +that we develop in the sphere of Free Software / Open Source mobile +communications. + +The libosmo-abis.git repository build multiple libraries: + +* **libosmoabis** contains some abstraction layer over E1/T1 and IP + based ETSI/3GPP A-bis interface. It can use mISDN and DAHDI as + underlying driver/hardware. +* **libosmotrau** contains routines related to A-bis TRAU frame handling + +Homepage +-------- + +The official homepage of the project is + + +GIT Repository +-------------- + +You can clone from the official libosmo-abis.git repository using + + git clone git://git.osmocom.org/libosmo-abis.git + +There is a cgit interface at + +Documentation +------------- + +There is no Doxygen-generated API documentation yet for this library. It +would be great to some day have it, comparable to libosmocore. + +Mailing List +------------ + +Discussions related to libosmo-abis are happening on the +openbsc@lists.osmocom.org mailing list, please see + for subscription +options and the list archive. + +Please observe the [Osmocom Mailing List +Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules) +when posting. + +Contributing +------------ + +Our coding standards are described at + + +We us a gerrit based patch submission/review process for managing +contributions. Please see + for +more details + +The current patch queue for libosmo-abis can be seen at + diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/e1_input.c libosmo-abis-0.4.0/src/e1_input.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/e1_input.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/e1_input.c 2017-08-25 14:12:37.000000000 +0000 @@ -28,21 +28,13 @@ #include #include #include -#include +#include #include #include #include -#include #include -//#define AF_COMPATIBILITY_FUNC -//#include -#ifndef AF_ISDN -#define AF_ISDN 34 -#define PF_ISDN AF_ISDN -#endif - #include #include #include @@ -200,30 +192,31 @@ write(pcap_fd, msg->l2h, msgb_l2len(msg)); } -static const char *sign_types[] = { - [E1INP_SIGN_NONE] = "None", - [E1INP_SIGN_OML] = "OML", - [E1INP_SIGN_RSL] = "RSL", - [E1INP_SIGN_OSMO] = "OSMO", +const struct value_string e1inp_sign_type_names[5] = { + { E1INP_SIGN_NONE, "None" }, + { E1INP_SIGN_OML, "OML" }, + { E1INP_SIGN_RSL, "RSL" }, + { E1INP_SIGN_OSMO, "OSMO" }, + { 0, NULL } }; + const char *e1inp_signtype_name(enum e1inp_sign_type tp) { - if (tp >= ARRAY_SIZE(sign_types)) - return "undefined"; - return sign_types[tp]; + return get_value_string(e1inp_sign_type_names, tp); } -static const char *ts_types[] = { - [E1INP_TS_TYPE_NONE] = "None", - [E1INP_TS_TYPE_SIGN] = "Signalling", - [E1INP_TS_TYPE_TRAU] = "TRAU", +const struct value_string e1inp_ts_type_names[6] = { + { E1INP_TS_TYPE_NONE, "None" }, + { E1INP_TS_TYPE_SIGN, "Signalling" }, + { E1INP_TS_TYPE_TRAU, "TRAU" }, + { E1INP_TS_TYPE_RAW, "RAW" }, + { E1INP_TS_TYPE_HDLC, "HDLC" }, + { 0, NULL } }; const char *e1inp_tstype_name(enum e1inp_ts_type tp) { - if (tp >= ARRAY_SIZE(ts_types)) - return "undefined"; - return ts_types[tp]; + return get_value_string(e1inp_ts_type_names, tp); } int abis_sendmsg(struct msgb *msg) @@ -231,7 +224,7 @@ struct e1inp_sign_link *sign_link = msg->dst; struct e1inp_driver *e1inp_driver; struct e1inp_ts *e1i_ts; -; + msg->l2h = msg->data; /* don't know how to route this message. */ @@ -249,8 +242,14 @@ } msgb_enqueue(&sign_link->tx_list, msg); - /* dump it */ - write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, sign_link->tei, msg); + /* we only need to write a 'Fake LAPD' packet here, if the + * underlying driver hides LAPD from us. If we use the + * libosmocore LAPD implementation, it will take care of writing + * the _actual_ LAPD packet */ + if (!e1i_ts->lapd) { + write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, + sign_link->tei, msg); + } return 0; } @@ -294,6 +293,36 @@ return 0; } +int e1inp_ts_config_raw(struct e1inp_ts *ts, struct e1inp_line *line, + void (*raw_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)) +{ + if (ts->type == E1INP_TS_TYPE_RAW && ts->line && line) + return 0; + + ts->type = E1INP_TS_TYPE_RAW; + ts->line = line; + ts->raw.recv_cb = raw_recv_cb; + INIT_LLIST_HEAD(&ts->raw.tx_queue); + + return 0; +} + +int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line, + void (*hdlc_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)) +{ + if (ts->type == E1INP_TS_TYPE_HDLC && ts->line && line) + return 0; + + ts->type = E1INP_TS_TYPE_HDLC; + ts->line = line; + ts->hdlc.recv_cb = hdlc_recv_cb; + INIT_LLIST_HEAD(&ts->hdlc.tx_queue); + + return 0; +} + struct e1inp_line *e1inp_line_find(uint8_t e1_nr) { struct e1inp_line *e1i_line; @@ -335,6 +364,11 @@ line->num = e1_nr; line->rate_ctr = rate_ctr_group_alloc(line, &e1inp_ctr_g_d, line->num); + if (!line->rate_ctr) { + LOGP(DLINP, LOGL_ERROR, "Cannot allocate counter group\n"); + talloc_free(line); + return NULL; + } line->num_ts = NUM_E1_TS; for (i = 0; i < line->num_ts; i++) { @@ -499,8 +533,13 @@ switch (ts->type) { case E1INP_TS_TYPE_SIGN: + /* we only need to write a 'Fake LAPD' packet here, if + * the underlying driver hides LAPD from us. If we use + * the libosmocore LAPD implementation, it will take + * care of writing the _actual_ LAPD packet */ + if (!ts->lapd) + write_pcap_packet(PCAP_INPUT, sapi, tei, msg); /* consult the list of signalling links */ - write_pcap_packet(PCAP_INPUT, sapi, tei, msg); link = e1inp_lookup_sign_link(ts, tei, sapi); if (!link) { LOGP(DLMI, LOGL_ERROR, "didn't find signalling link for " @@ -521,6 +560,12 @@ ret = subch_demux_in(&ts->trau.demux, msg->l2h, msgb_l2len(msg)); msgb_free(msg); break; + case E1INP_TS_TYPE_RAW: + ts->raw.recv_cb(ts, msg); + break; + case E1INP_TS_TYPE_HDLC: + ts->hdlc.recv_cb(ts, msg); + break; default: ret = -EINVAL; LOGP(DLMI, LOGL_ERROR, "unknown TS type %u\n", ts->type); @@ -644,6 +689,14 @@ } msgb_put(msg, 40); break; + case E1INP_TS_TYPE_RAW: + /* Get msgb from tx_queue */ + msg = msgb_dequeue(&e1i_ts->raw.tx_queue); + break; + case E1INP_TS_TYPE_HDLC: + /* Get msgb from tx_queue */ + msg = msgb_dequeue(&e1i_ts->hdlc.tx_queue); + break; default: LOGP(DLMI, LOGL_ERROR, "unsupported E1 TS type %u\n", e1i_ts->type); return NULL; @@ -656,6 +709,7 @@ { struct input_signal_data isd; isd.line = ts->line; + isd.ts_nr = ts->num; isd.link_type = link->type; isd.trx = link->trx; isd.tei = link->tei; @@ -712,7 +766,7 @@ int e1inp_line_update(struct e1inp_line *line) { struct input_signal_data isd; - int rc; + int i, rc; e1inp_line_get(line); @@ -721,6 +775,15 @@ } else rc = 0; + /* Set the PCAP file descriptor for all timeslots that have + * software LAPD instances, to ensure the osmo_lapd_pcap code is + * used to write PCAP files (if requested) */ + for (i = 0; i < ARRAY_SIZE(line->ts); i++) { + struct e1inp_ts *e1i_ts = &line->ts[i]; + if (e1i_ts->lapd) + e1i_ts->lapd->pcap_fd = pcap_fd; + } + /* Send a signal to anyone who is interested in new lines being * configured */ memset(&isd, 0, sizeof(isd)); @@ -745,10 +808,22 @@ return 0; } +const struct value_string e1inp_signal_names[] = { + { S_L_INP_NONE, "NONE" }, + { S_L_INP_TEI_UP, "TEI-UP" }, + { S_L_INP_TEI_DN, "TEI-DOWN" }, + { S_L_INP_TEI_UNKNOWN, "TEI-UNKNOWN" }, + { S_L_INP_LINE_INIT, "LINE-INIT" }, + { S_L_INP_LINE_ALARM, "LINE-ALARM" }, + { S_L_INP_LINE_NOALARM, "LINE-NOALARM" }, + { 0, NULL } +}; + void e1inp_misdn_init(void); void e1inp_dahdi_init(void); void e1inp_ipaccess_init(void); void e1inp_rs232_init(void); +void e1inp_unixsocket_init(void); void e1inp_init(void) { @@ -763,4 +838,5 @@ #endif e1inp_ipaccess_init(); e1inp_rs232_init(); + e1inp_unixsocket_init(); } diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/e1_input_vty.c libosmo-abis-0.4.0/src/e1_input_vty.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/e1_input_vty.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/e1_input_vty.c 2017-08-25 14:12:37.000000000 +0000 @@ -38,12 +38,13 @@ /* CONFIG */ -#define E1_DRIVER_NAMES "(misdn|misdn_lapd|dahdi|ipa)" +#define E1_DRIVER_NAMES "(misdn|misdn_lapd|dahdi|ipa|unixsocket)" #define E1_DRIVER_HELP "mISDN supported E1 Card (kernel LAPD)\n" \ "mISDN supported E1 Card (userspace LAPD)\n" \ "DAHDI supported E1/T1/J1 Card\n" \ "IPA TCP/IP input\n" \ - "HSL TCP/IP input" + "HSL TCP/IP input\n" \ + "Unix socket input\n" #define E1_LINE_HELP "Configure E1/T1/J1 Line\n" "Line Number\n" @@ -88,6 +89,25 @@ return CMD_SUCCESS; } +DEFUN(cfg_e1line_socket, cfg_e1_line_socket_cmd, + "e1_line <0-255> socket .SOCKET", + E1_LINE_HELP "Set socket path for unixsocket\n" + "socket path\n") +{ + struct e1inp_line *line; + int e1_nr = atoi(argv[0]); + + line = e1inp_line_find(e1_nr); + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + + line->sock_path = talloc_strdup(line, argv[1]); + + return CMD_SUCCESS; +} + #define KEEPALIVE_HELP "Enable keep-alive probing\n" static int set_keepalive_params(struct vty *vty, int e1_nr, int idle, int num_probes, int probe_interval) @@ -168,6 +188,17 @@ return CMD_SUCCESS; } +DEFUN(cfg_ipa_bind, + cfg_ipa_bind_cmd, + "ipa bind A.B.C.D", + "ipa driver config\n" + "Set ipa local bind address\n" + "Listen on this IP address (default 0.0.0.0)\n") +{ + e1inp_ipa_set_bind_addr(argv[0]); + return CMD_SUCCESS; +} + static int e1inp_config_write(struct vty *vty) { struct e1inp_line *line; @@ -202,6 +233,12 @@ VTY_NEWLINE); } + + const char *ipa_bind = e1inp_ipa_get_bind_addr(); + if (ipa_bind && (strcmp(ipa_bind, "0.0.0.0") != 0)) + vty_out(vty, " ipa bind %s%s", + ipa_bind, VTY_NEWLINE); + return CMD_SUCCESS; } @@ -346,11 +383,14 @@ vty_install_default(L_E1INP_NODE); install_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_socket_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_name_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd); + install_element(L_E1INP_NODE, &cfg_ipa_bind_cmd); + install_element_ve(&show_e1drv_cmd); install_element_ve(&show_e1line_cmd); install_element_ve(&show_e1ts_cmd); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/dahdi.c libosmo-abis-0.4.0/src/input/dahdi.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/dahdi.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/dahdi.c 2017-08-25 14:12:37.000000000 +0000 @@ -139,6 +139,7 @@ get_value_string(dahdi_evt_names, evt)); isd.line = ts->line; + isd.ts_nr = ts->num; switch (evt) { case DAHDI_EVENT_ALARM: @@ -251,13 +252,57 @@ sign_link->sapi, msg); /* set tx delay timer for next event */ - e1i_ts->sign.tx_timer.cb = timeout_ts1_write; - e1i_ts->sign.tx_timer.data = e1i_ts; + osmo_timer_setup(&e1i_ts->sign.tx_timer, timeout_ts1_write, e1i_ts); osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, 50000); return 0; } +static void handle_hdlc_write(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg; + int ret; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, NULL); + if (!msg) + return; + + ret = write(bfd->fd, msg->data, msg->len + 2); + msgb_free(msg); + if (ret == -1) + handle_dahdi_exception(e1i_ts); + else if (ret < 0) + LOGP(DLMI, LOGL_NOTICE, "%s write failed %d\n", __func__, ret); +} + +static int handle_hdlc_read(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg = msgb_alloc(TS1_ALLOC_SIZE, "DAHDI HDLC Rx"); + int ret; + + if (!msg) + return -ENOMEM; + + ret = read(bfd->fd, msg->data, TS1_ALLOC_SIZE - 16); + if (ret == -1) + handle_dahdi_exception(e1i_ts); + else if (ret < 0) { + perror("read "); + } + msgb_put(msg, ret - 2); + if (ret <= 3) { + perror("read "); + } + + return e1inp_rx_ts(e1i_ts, msg, 0, 0); +} static int invertbits = 1; @@ -359,6 +404,79 @@ return ret; } +/* write to a raw channel TS */ +static int handle_ts_raw_write(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg; + int ret; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, NULL); + if (!msg) + return 0; + + if (msg->len != D_BCHAN_TX_GRAN) { + /* This might lead to a transmit underrun, as we call tx + * from the rx path, as there's no select/poll on dahdi + * */ + LOGP(DLINP, LOGL_NOTICE, "unexpected msg->len = %u, " + "expected %u\n", msg->len, D_BCHAN_TX_GRAN); + } + + DEBUGP(DLMIB, "RAW CHAN TX: %s\n", + osmo_hexdump(msg->data, msg->len)); + + if (0/*invertbits*/) { + flip_buf_bits(msg->data, msg->len); + } + + ret = write(bfd->fd, msg->data, msg->len); + if (ret < msg->len) + LOGP(DLINP, LOGL_DEBUG, "send returns %d instead of %d\n", + ret, msg->len); + msgb_free(msg); + + return ret; +} + +static int handle_ts_raw_read(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg = msgb_alloc(D_TSX_ALLOC_SIZE, "DAHDI Raw TS"); + int ret; + + if (!msg) + return -ENOMEM; + + ret = read(bfd->fd, msg->data, D_TSX_ALLOC_SIZE); + if (ret < 0 || ret != D_TSX_ALLOC_SIZE) { + LOGP(DLINP, LOGL_DEBUG, "read error %d %s\n", + ret, strerror(errno)); + return ret; + } + + if (0/*invertbits*/) { + flip_buf_bits(msg->data, ret); + } + + msgb_put(msg, ret); + + msg->l2h = msg->data; + DEBUGP(DLMIB, "RAW CHAN RX: %s\n", + osmo_hexdump(msgb_l2(msg), ret)); + ret = e1inp_rx_ts(e1i_ts, msg, 0, 0); + /* physical layer indicates that data has been sent, + * we thus can send some more data */ + ret = handle_ts_raw_write(bfd); + + return ret; +} + /* callback from select.c in case one of the fd's can be read/written */ static int dahdi_fd_cb(struct osmo_fd *bfd, unsigned int what) { @@ -377,6 +495,14 @@ if (what & BSC_FD_WRITE) rc = handle_ts1_write(bfd); break; + case E1INP_TS_TYPE_HDLC: + if (what & BSC_FD_EXCEPT) + handle_dahdi_exception(e1i_ts); + if (what & BSC_FD_READ) + rc = handle_hdlc_read(bfd); + if (what & BSC_FD_WRITE) + handle_hdlc_write(bfd); + break; case E1INP_TS_TYPE_TRAU: if (what & BSC_FD_EXCEPT) handle_dahdi_exception(e1i_ts); @@ -388,6 +514,17 @@ * writeset, since it doesn't support poll() based * write flow control */ break; + case E1INP_TS_TYPE_RAW: + if (what & BSC_FD_EXCEPT) + handle_dahdi_exception(e1i_ts); + if (what & BSC_FD_READ) + rc = handle_ts_raw_read(bfd); + if (what & BSC_FD_WRITE) + rc = handle_ts_raw_write(bfd); + /* We never include the DAHDI B-Channel FD into the + * writeset, since it doesn't support poll() based + * write flow control */ + break; default: LOGP(DLINP, LOGL_NOTICE, "unknown E1 TS type %u\n", e1i_ts->type); @@ -535,7 +672,22 @@ dahdi_write_msg, bfd, e1inp_dlsap_up, e1i_ts, &lapd_profile_abis); break; + case E1INP_TS_TYPE_HDLC: + if (!bfd->fd) + bfd->fd = open(openstr, O_RDWR | O_NONBLOCK); + if (bfd->fd == -1) { + LOGP(DLINP, LOGL_ERROR, + "%s could not open %s %s\n", + __func__, openstr, strerror(errno)); + return -EIO; + } + bfd->when = BSC_FD_READ | BSC_FD_EXCEPT; + ret = dahdi_set_bufinfo(bfd->fd, 1); + if (ret < 0) + return ret; + break; case E1INP_TS_TYPE_TRAU: + case E1INP_TS_TYPE_RAW: /* close/release LAPD instance, if any */ if (e1i_ts->lapd) { lapd_instance_free(e1i_ts->lapd); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/ipa.c libosmo-abis-0.4.0/src/input/ipa.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/ipa.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/ipa.c 2017-08-25 14:12:37.000000000 +0000 @@ -213,10 +213,8 @@ ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP, link->addr, link->port, OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK); - if (ret < 0) { - if (errno != EINPROGRESS) - return ret; - } + if (ret < 0) + return ret; link->ofd->fd = ret; link->ofd->when |= BSC_FD_WRITE; if (osmo_fd_register(link->ofd) < 0) { @@ -401,6 +399,8 @@ int (*closed_cb)(struct ipa_server_conn *conn), void *data) { struct ipa_server_conn *conn; + struct sockaddr_in sa; + socklen_t sa_len = sizeof(sa); conn = talloc_zero(ctx, struct ipa_server_conn); if (conn == NULL) { @@ -418,6 +418,12 @@ conn->data = data; INIT_LLIST_HEAD(&conn->tx_queue); + if (!getpeername(fd, (struct sockaddr *)&sa, &sa_len)) { + char *str = inet_ntoa(sa.sin_addr); + conn->addr = talloc_strdup(conn, str); + conn->port = ntohs(sa.sin_port); + } + if (osmo_fd_register(&conn->ofd) < 0) { LOGP(DLINP, LOGL_ERROR, "could not register FD\n"); talloc_free(conn); @@ -426,6 +432,73 @@ return conn; } +int ipa_server_conn_ccm(struct ipa_server_conn *conn, struct msgb *msg) +{ + struct tlv_parsed tlvp; + uint8_t msg_type = *(msg->l2h); + struct ipaccess_unit unit_data = {}; + char *unitid; + int len, rc; + + /* shared CCM handling on both server and client */ + rc = ipa_ccm_rcvmsg_base(msg, &conn->ofd); + switch (rc) { + case -1: + /* error in IPA CCM processing */ + goto err; + case 1: + /* IPA CCM message that was handled in _base */ + return 0; + case 0: + /* IPA CCM message that we need to handle */ + break; + default: + /* Error */ + LOGP(DLINP, LOGL_ERROR, "Unexpected return from " + "ipa_ccm_rcvmsg_base: %d\n", rc); + goto err; + } + + switch (msg_type) { + case IPAC_MSGT_ID_RESP: + rc = ipa_ccm_idtag_parse(&tlvp, (uint8_t *)msg->l2h + 2, + msgb_l2len(msg)-2); + if (rc < 0) { + LOGP(DLINP, LOGL_ERROR, "IPA CCM RESPonse with " + "malformed TLVs\n"); + goto err; + } + if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT)) { + LOGP(DLINP, LOGL_ERROR, "IPA CCM RESP without " + "unit ID\n"); + goto err; + } + len = TLVP_LEN(&tlvp, IPAC_IDTAG_UNIT); + if (len < 1) { + LOGP(DLINP, LOGL_ERROR, "IPA CCM RESP with short" + "unit ID\n"); + goto err; + } + unitid = (char *) TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT); + unitid[len-1] = '\0'; + ipa_parse_unitid(unitid, &unit_data); + + /* FIXME */ + rc = conn->ccm_cb(conn, msg, &tlvp, &unit_data); + if (rc < 0) + goto err; + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown IPA message type\n"); + break; + } + return 0; +err: + /* in case of any error, we close the connection */ + ipa_server_conn_destroy(conn); + return -1; +} + void ipa_server_conn_destroy(struct ipa_server_conn *conn) { close(conn->ofd.fd); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/ipaccess.c libosmo-abis-0.4.0/src/input/ipaccess.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/ipaccess.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/ipaccess.c 2017-08-25 14:12:37.000000000 +0000 @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -196,7 +196,12 @@ newbfd->priv_nr = E1INP_SIGN_RSL + unit_data.trx_id; osmo_fd_unregister(bfd); bfd->fd = -1; - osmo_fd_register(newbfd); + ret = osmo_fd_register(newbfd); + if (ret < 0) { + LOGP(DLINP, LOGL_ERROR, + "could not register FD\n"); + goto err; + } /* now we can release the dummy RSL line. */ e1inp_line_put(line); } @@ -223,7 +228,7 @@ struct e1inp_sign_link *link; struct ipaccess_head *hh; struct msgb *msg = NULL; - int ret; + int ret, rc; ret = ipa_msg_recv_buffered(bfd->fd, &msg, &e1i_ts->pending_msg); if (ret < 0) { @@ -268,13 +273,14 @@ ret = -EINVAL; goto err_msg; } - if (e1i_ts->line->ops->sign_link(msg) < 0) { + rc = e1i_ts->line->ops->sign_link(msg); + if (rc < 0) { /* Don't close the signalling link if the upper layers report * an error, that's too strict. BTW, the signalling layer is * resposible for releasing the message. */ LOGP(DLINP, LOGL_ERROR, "Bad signalling message," - "sign_link returned error\n"); + " sign_link returned error: %s.\n", strerror(-rc)); } return 0; @@ -348,8 +354,7 @@ } /* set tx delay timer for next event */ - e1i_ts->sign.tx_timer.cb = timeout_ts1_write; - e1i_ts->sign.tx_timer.data = e1i_ts; + osmo_timer_setup(&e1i_ts->sign.tx_timer, timeout_ts1_write, e1i_ts); /* Reducing this might break the nanoBTS 900 init. */ osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay); @@ -570,6 +575,8 @@ char str[IPA_STRING_MAX]; uint8_t *tag; + memset(str, 0, sizeof(str)); + nmsg = ipa_msg_alloc(0); if (!nmsg) return NULL; @@ -595,16 +602,20 @@ dev->mac_addr[4], dev->mac_addr[5]); break; case IPAC_IDTAG_LOCATION1: - strncpy(str, dev->location1, IPA_STRING_MAX); + if (dev->location1) + strncpy(str, dev->location1, IPA_STRING_MAX); break; case IPAC_IDTAG_LOCATION2: - strncpy(str, dev->location2, IPA_STRING_MAX); + if (dev->location2) + strncpy(str, dev->location2, IPA_STRING_MAX); break; case IPAC_IDTAG_EQUIPVERS: - strncpy(str, dev->equipvers, IPA_STRING_MAX); + if (dev->equipvers) + strncpy(str, dev->equipvers, IPA_STRING_MAX); break; case IPAC_IDTAG_SWVERSION: - strncpy(str, dev->swversion, IPA_STRING_MAX); + if (dev->swversion) + strncpy(str, dev->swversion, IPA_STRING_MAX); break; case IPAC_IDTAG_UNITNAME: snprintf(str, sizeof(str), @@ -615,7 +626,8 @@ dev->mac_addr[4], dev->mac_addr[5]); break; case IPAC_IDTAG_SERNR: - strncpy(str, dev->serno, IPA_STRING_MAX); + if (dev->serno) + strncpy(str, dev->serno, IPA_STRING_MAX); break; default: LOGP(DLINP, LOGL_NOTICE, @@ -827,11 +839,14 @@ switch(line->ops->cfg.ipa.role) { case E1INP_LINE_R_BSC: { struct ipa_server_link *oml_link, *rsl_link; + const char *ipa = e1inp_ipa_get_bind_addr(); - LOGP(DLINP, LOGL_NOTICE, "enabling ipaccess BSC mode\n"); + LOGP(DLINP, LOGL_NOTICE, "enabling ipaccess BSC mode on %s " + "with OML %u and RSL %u TCP ports\n", ipa, + IPA_TCP_PORT_OML, IPA_TCP_PORT_RSL); - oml_link = ipa_server_link_create(tall_ipa_ctx, line, - "0.0.0.0", IPA_TCP_PORT_OML, + oml_link = ipa_server_link_create(tall_ipa_ctx, line, ipa, + IPA_TCP_PORT_OML, ipaccess_bsc_oml_cb, NULL); if (oml_link == NULL) { LOGP(DLINP, LOGL_ERROR, "cannot create OML " @@ -844,8 +859,8 @@ ipa_server_link_destroy(oml_link); return -EIO; } - rsl_link = ipa_server_link_create(tall_ipa_ctx, line, - "0.0.0.0", IPA_TCP_PORT_RSL, + rsl_link = ipa_server_link_create(tall_ipa_ctx, line, ipa, + IPA_TCP_PORT_RSL, ipaccess_bsc_rsl_cb, NULL); if (rsl_link == NULL) { LOGP(DLINP, LOGL_ERROR, "cannot create RSL " @@ -864,7 +879,9 @@ case E1INP_LINE_R_BTS: { struct ipa_client_conn *link; - LOGP(DLINP, LOGL_NOTICE, "enabling ipaccess BTS mode\n"); + LOGP(DLINP, LOGL_NOTICE, "enabling ipaccess BTS mode, " + "OML connecting to %s:%u\n", line->ops->cfg.ipa.addr, + IPA_TCP_PORT_OML); link = ipa_client_conn_create(tall_ipa_ctx, &line->ts[E1INP_SIGN_OML-1], @@ -944,3 +961,20 @@ tall_ipa_ctx = talloc_named_const(libosmo_abis_ctx, 1, "ipa"); e1inp_driver_register(&ipaccess_driver); } + +void e1inp_ipa_set_bind_addr(const char *ip_bind_addr) +{ + talloc_free((char*)ipaccess_driver.bind_addr); + ipaccess_driver.bind_addr = NULL; + + if (ip_bind_addr) + ipaccess_driver.bind_addr = talloc_strdup(tall_ipa_ctx, + ip_bind_addr); +} + +const char *e1inp_ipa_get_bind_addr(void) +{ + return ipaccess_driver.bind_addr? + ipaccess_driver.bind_addr + : "0.0.0.0"; +} diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/lapd.c libosmo-abis-0.4.0/src/input/lapd.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/lapd.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/lapd.c 2017-08-25 14:12:37.000000000 +0000 @@ -95,6 +95,27 @@ .short_address = 0 }; +/* Ericssons OM2000 lapd dialect requires a sabm frame retransmission + * timeout of exactly 300 msek. Shorter or longer retransmission will + * cause the link establishment to fail permanently. Since the BTS is + * periodically scanning through all timeslots to find the timeslot + * where the bsc is transmitting its sabm frames the normal maximum + * retransmission (n200) of 3 is not enough. In order not to miss + * the bts, n200 has been increased to 50, which is an educated + * guess. */ + +const struct lapd_profile lapd_profile_abis_ericsson = { + .k = LAPD_SET_K(2,1), + .n200 = 50, + .n201 = 260, + .n202 = 0, /* infinite */ + .t200_sec = 0, .t200_usec = 300000, + .t201_sec = 1, .t201_usec = 0, + .t202_sec = 2, .t202_usec = 0, + .t203_sec = 10, .t203_usec = 0, + .short_address = 0 +}; + const struct lapd_profile lapd_profile_sat = { .k = LAPD_SET_K(15,15), .n200 = 5, @@ -208,8 +229,9 @@ if (!sap) return NULL; - LOGP(DLLAPD, LOGL_NOTICE, "LAPD Allocating SAP for SAPI=%u / TEI=%u\n", - sapi, teip->tei); + LOGP(DLLAPD, LOGL_NOTICE, + "LAPD Allocating SAP for SAPI=%u / TEI=%u (dl=%p, sap=%p)\n", + sapi, teip->tei, &sap->dl, sap); sap->sapi = sapi; sap->tei = teip; @@ -245,6 +267,10 @@ /* Free SAP instance, including the datalink */ static void lapd_sap_free(struct lapd_sap *sap) { + LOGP(DLLAPD, LOGL_NOTICE, + "LAPD Freeing SAP for SAPI=%u / TEI=%u (dl=%p, sap=%p)\n", + sap->sapi, sap->tei->tei, &sap->dl, sap); + /* free datalink structures and timers */ lapd_dl_exit(&sap->dl); @@ -664,6 +690,13 @@ return li; } +/* Change lapd-profile on the fly (use with caution!) */ +void lapd_instance_set_profile(struct lapd_instance *li, + const struct lapd_profile *profile) +{ + memcpy(&li->profile, profile, sizeof(li->profile)); +} + void lapd_instance_free(struct lapd_instance *li) { struct lapd_tei *teip, *teip2; diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/lapd_pcap.c libosmo-abis-0.4.0/src/input/lapd_pcap.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/lapd_pcap.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/lapd_pcap.c 2017-08-25 14:12:37.000000000 +0000 @@ -43,6 +43,8 @@ * pcap format is from http://wiki.wireshark.org/Development/LibpcapFileFormat */ #define DLT_LINUX_LAPD 177 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_OUTGOING 4 struct pcap_hdr { uint32_t magic_number; @@ -65,7 +67,7 @@ uint16_t pkttype; uint16_t hatype; uint16_t halen; - uint64_t addr; + uint8_t addr[8]; int16_t protocol; } __attribute__((packed)); @@ -75,10 +77,9 @@ osmo_static_assert(offsetof(struct pcap_lapdhdr, protocol) == 14, proto_offset); osmo_static_assert(sizeof(struct pcap_lapdhdr) == 16, lapd_header_size); -int osmo_pcap_lapd_open(char *filename, mode_t mode) +int osmo_pcap_lapd_set_fd(int fd) { - int fd; - struct pcap_hdr pcap_header = { + struct pcap_hdr pcap_header = { .magic_number = 0xa1b2c3d4, .version_major = 2, .version_minor = 4, @@ -88,6 +89,21 @@ .network = DLT_LINUX_LAPD, }; + if (write(fd, &pcap_header, sizeof(pcap_header)) + != sizeof(pcap_header)) { + LOGP(DLLAPD, LOGL_ERROR, "cannot write PCAP header: %s\n", + strerror(errno)); + close(fd); + return -1; + } + + return 0; +} + +int osmo_pcap_lapd_open(char *filename, mode_t mode) +{ + int fd, rc; + LOGP(DLLAPD, LOGL_NOTICE, "opening LAPD pcap file `%s'\n", filename); fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, mode); @@ -96,13 +112,13 @@ strerror(errno)); return -1; } - if (write(fd, &pcap_header, sizeof(pcap_header)) - != sizeof(pcap_header)) { - LOGP(DLLAPD, LOGL_ERROR, "cannot write PCAP header: %s\n", - strerror(errno)); + + rc = osmo_pcap_lapd_set_fd(fd); + if (rc < 0) { close(fd); - return -1; + return rc; } + return fd; } @@ -125,10 +141,13 @@ pcap_rechdr.incl_len = msg->len + sizeof(struct pcap_lapdhdr); pcap_rechdr.orig_len = msg->len + sizeof(struct pcap_lapdhdr); - header.pkttype = 4; + if (direction == OSMO_LAPD_PCAP_OUTPUT) + header.pkttype = htons(LINUX_SLL_OUTGOING); + else + header.pkttype = htons(LINUX_SLL_HOST); header.hatype = 0; header.halen = 0; - header.addr = direction == OSMO_LAPD_PCAP_OUTPUT ? 0x0 : 0x1; + header.addr[0] = 0x01; /* we are the network side */ header.protocol = ntohs(48); gettimeofday(&tv, NULL); diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/misdn.c libosmo-abis-0.4.0/src/input/misdn.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/misdn.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/misdn.c 2017-08-25 14:12:37.000000000 +0000 @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -283,8 +283,7 @@ /* set tx delay timer for next event */ - e1i_ts->sign.tx_timer.cb = timeout_ts1_write; - e1i_ts->sign.tx_timer.data = e1i_ts; + osmo_timer_setup(&e1i_ts->sign.tx_timer, timeout_ts1_write, e1i_ts); osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay); return ret; @@ -391,6 +390,92 @@ return ret; } +/* write to a raw channel TS */ +static int handle_ts_raw_write(struct osmo_fd *bfd, unsigned int len) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg; + struct mISDNhead *hh; + int ret; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, NULL); + if (!msg) + return 0; + + if (msg->len != len) { + /* This might lead to a transmit underrun, as we call tx + * from the rx path, as there's no select/poll on dahdi + * */ + LOGP(DLINP, LOGL_NOTICE, "unexpected msg->len = %u, " + "expected %u\n", msg->len, len); + } + + DEBUGP(DLMIB, "RAW CHAN TX: %s\n", + osmo_hexdump(msg->data, msg->len)); + + hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh)); + hh->prim = PH_DATA_REQ; + hh->id = 0; + + ret = write(bfd->fd, msg->data, msg->len); + if (ret < msg->len) + LOGP(DLINP, LOGL_DEBUG, "send returns %d instead of %d\n", + ret, msg->len); + msgb_free(msg); + + return ret; +} + +static int handle_ts_raw_read(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg = msgb_alloc(TSX_ALLOC_SIZE, "mISDN Tx RAW"); + struct mISDNhead *hh; + int ret; + + if (!msg) + return -ENOMEM; + + hh = (struct mISDNhead *) msg->data; + + ret = recv(bfd->fd, msg->data, TSX_ALLOC_SIZE, 0); + if (ret < 0) { + fprintf(stderr, "recvfrom error %s\n", strerror(errno)); + return ret; + } + + msgb_put(msg, ret); + + if (hh->prim != PH_CONTROL_IND) + DEBUGP(DLMIB, "<= RAW CHAN len = %d, prim(0x%x) id(0x%x): %s\n", + ret, hh->prim, hh->id, + get_value_string(prim_names, hh->prim)); + + switch (hh->prim) { + case PH_DATA_IND: + msg->l2h = msg->data + MISDN_HEADER_LEN; + DEBUGP(DLMIB, "RAW CHAN RX: %s\n", + osmo_hexdump(msgb_l2(msg), ret - MISDN_HEADER_LEN)); + /* the number of bytes received indicates that data to send */ + handle_ts_raw_write(bfd, msgb_l2len(msg)); + return e1inp_rx_ts(e1i_ts, msg, 0, 0); + case PH_ACTIVATE_IND: + case PH_DATA_CNF: + break; + default: + break; + } + /* FIXME: why do we free signalling msgs in the caller, and trau not? */ + msgb_free(msg); + + return ret; +} + /* callback from select.c in case one of the fd's can be read/written */ static int misdn_fd_cb(struct osmo_fd *bfd, unsigned int what) { @@ -414,6 +499,13 @@ * writeset, since it doesn't support poll() based * write flow control */ break; + case E1INP_TS_TYPE_RAW: + if (what & BSC_FD_READ) + rc = handle_ts_raw_read(bfd); + /* We never include the mISDN B-Channel FD into the + * writeset, since it doesn't support poll() based + * write flow control */ + break; default: fprintf(stderr, "unknown E1 TS type %u\n", e1i_ts->type); break; @@ -514,6 +606,11 @@ case E1INP_TS_TYPE_NONE: continue; break; + case E1INP_TS_TYPE_HDLC: + bfd->fd = socket(PF_ISDN, SOCK_DGRAM, + ISDN_P_B_HDLC); + bfd->when = BSC_FD_READ; + break; case E1INP_TS_TYPE_SIGN: if (mline->use_userspace_lapd) bfd->fd = socket(PF_ISDN, SOCK_DGRAM, @@ -524,6 +621,7 @@ bfd->when = BSC_FD_READ; break; case E1INP_TS_TYPE_TRAU: + case E1INP_TS_TYPE_RAW: bfd->fd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW); /* We never include the mISDN B-Channel FD into the * writeset, since it doesn't support poll() based @@ -556,6 +654,7 @@ addr.tei = GROUP_TEI; } break; + case E1INP_TS_TYPE_HDLC: case E1INP_TS_TYPE_TRAU: addr.channel = ts; break; @@ -591,7 +690,7 @@ ret = osmo_fd_register(bfd); if (ret < 0) { fprintf(stderr, "could not register FD: %s\n", - strerror(ret)); + strerror(-ret)); return ret; } } diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/rs232.c libosmo-abis-0.4.0/src/input/rs232.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/rs232.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/rs232.c 2017-08-25 14:12:37.000000000 +0000 @@ -270,7 +270,7 @@ if (rc < 0) { close(bfd->fd); LOGP(DLMI, LOGL_ERROR, "rs232: could not register FD: %s\n", - strerror(rc)); + strerror(-rc)); return rc; } diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/input/unixsocket.c libosmo-abis-0.4.0/src/input/unixsocket.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/input/unixsocket.c 1970-01-01 00:00:00.000000000 +0000 +++ libosmo-abis-0.4.0/src/input/unixsocket.c 2017-08-25 14:12:37.000000000 +0000 @@ -0,0 +1,346 @@ +/* OpenBSC Abis receive lapd over a unix socket */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * + * Author: Alexander Couzens + * Based on other e1_input drivers. + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include "internal.h" + +void *tall_unixsocket_ctx; +#define UNIXSOCKET_ALLOC_SIZE 1600 +#define UNIXSOCKET_SOCK_PATH_DEFAULT "/tmp/osmo_abis_line_" + +struct unixsocket_line { + struct osmo_fd fd; +}; + +static int unixsocket_line_update(struct e1inp_line *line); +static int ts_want_write(struct e1inp_ts *e1i_ts); + +static int unixsocket_exception_cb(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + + LOGP(DLINP, LOGL_ERROR, + "Socket connection failure, reconnecting... (line=%p, fd=%d)\n", + line, bfd->fd); + + /* Unregister faulty file descriptor from select loop */ + if(osmo_fd_is_registered(bfd)) { + LOGP(DLINP, LOGL_DEBUG, + "removing inactive socket from select loop... (line=%p, fd=%d)\n", + line, bfd->fd); + osmo_fd_unregister(bfd); + } + + /* Close faulty file descriptor */ + close(bfd->fd); + + unixsocket_line_update(line); + + return 0; +} + +static int unixsocket_read_cb(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + struct msgb *msg = msgb_alloc(UNIXSOCKET_ALLOC_SIZE, "UNIXSOCKET TS"); + uint8_t version; + uint8_t controldata; + int ret; + + if (!msg) + return -ENOMEM; + + ret = read(bfd->fd, msg->data, UNIXSOCKET_ALLOC_SIZE - 16); + if (ret == 0) { + unixsocket_exception_cb(bfd); + goto fail; + } else if (ret < 0) { + perror("read "); + goto fail; + } else if (ret < 2) { + /* packet must be at least 2 byte long to hold version + control/data header */ + LOGP(DLMI, LOGL_ERROR, "received to small packet: %d < 2", ret); + ret = -1; + goto fail; + } + msgb_put(msg, ret); + + LOGP(DLMI, LOGL_DEBUG, "rx msg: %s (fd=%d)\n", + osmo_hexdump_nospc(msg->data, msg->len), bfd->fd); + + /* check version header */ + version = msgb_pull_u8(msg); + controldata = msgb_pull_u8(msg); + + if (version != UNIXSOCKET_PROTO_VERSION) { + LOGP(DLMI, LOGL_ERROR, "received message with invalid version %d. valid: %d", + ret, UNIXSOCKET_PROTO_VERSION); + ret = -1; + goto fail; + } + + switch (controldata) { + case UNIXSOCKET_PROTO_DATA: + return e1inp_rx_ts_lapd(&line->ts[0], msg); + case UNIXSOCKET_PROTO_CONTROL: + LOGP(DLMI, LOGL_ERROR, "received (invalid) control message."); + ret = -1; + break; + default: + LOGP(DLMI, LOGL_ERROR, "received invalid message."); + ret = -1; + break; + } +fail: + msgb_free(msg); + return ret; +} + +static void timeout_ts1_write(void *data) +{ + struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data; + + /* trigger write of ts1, due to tx delay timer */ + ts_want_write(e1i_ts); +} + +static int unixsocket_write_cb(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + struct e1inp_ts *e1i_ts = &line->ts[0]; + struct msgb *msg; + struct e1inp_sign_link *sign_link; + + bfd->when &= ~BSC_FD_WRITE; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, &sign_link); + if (!msg) { + /* no message after tx delay timer */ + LOGP(DLINP, LOGL_INFO, + "no message available (line=%p)\n", line); + return 0; + } + + /* set tx delay timer for next event */ + osmo_timer_setup(&e1i_ts->sign.tx_timer, timeout_ts1_write, e1i_ts); + + osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay); + + LOGP(DLINP, LOGL_DEBUG, "sending: %s (line=%p)\n", + msgb_hexdump(msg), line); + lapd_transmit(e1i_ts->lapd, sign_link->tei, + sign_link->sapi, msg); + + return 0; +} + +static int unixsocket_cb(struct osmo_fd *bfd, unsigned int what) +{ + int ret = 0; + + if (what & BSC_FD_READ) + ret = unixsocket_read_cb(bfd); + if (what & BSC_FD_WRITE) + ret = unixsocket_write_cb(bfd); + + return ret; +} + +static int ts_want_write(struct e1inp_ts *e1i_ts) +{ + struct unixsocket_line *line = e1i_ts->line->driver_data; + + line->fd.when |= BSC_FD_WRITE; + + return 0; +} + +static void unixsocket_write_msg(struct msgb *msg, struct osmo_fd *bfd) { + int ret; + + LOGP(DLMI, LOGL_DEBUG, "tx msg: %s (fd=%d)\n", + osmo_hexdump_nospc(msg->data, msg->len), bfd->fd); + + ret = write(bfd->fd, msg->data, msg->len); + msgb_free(msg); + if (ret == -1) + unixsocket_exception_cb(bfd); + else if (ret < 0) + LOGP(DLMI, LOGL_NOTICE, "%s write failed %d\n", __func__, ret); +} + +/*! + * \brief unixsocket_write_msg lapd callback for data to unixsocket + * \param msg + * \param cbdata + */ +static void unixsocket_write_msg_lapd_cb(struct msgb *msg, void *cbdata) +{ + struct osmo_fd *bfd = cbdata; + + /* data|control */ + msgb_push_u8(msg, UNIXSOCKET_PROTO_DATA); + /* add version header */ + msgb_push_u8(msg, UNIXSOCKET_PROTO_VERSION); + + unixsocket_write_msg(msg, bfd); +} + +static int unixsocket_line_update(struct e1inp_line *line) +{ + struct unixsocket_line *config; + char sock_path[PATH_MAX]; + int ret = 0; + int i; + + if (line->sock_path) + strcpy(sock_path, line->sock_path); + else + sprintf(sock_path, "%s%d", UNIXSOCKET_SOCK_PATH_DEFAULT, + line->num); + + LOGP(DLINP, LOGL_NOTICE, "line update (line=%p)\n", line); + + if (!line->driver_data) + line->driver_data = talloc_zero(line, struct unixsocket_line); + + if (!line->driver_data) { + LOGP(DLINP, LOGL_ERROR, + "OOM in line update (line=%p)\n", line); + return -ENOMEM; + } + + config = line->driver_data; + config->fd.data = line; + config->fd.when = BSC_FD_READ; + config->fd.cb = unixsocket_cb; + + /* Open unix domain socket */ + ret = osmo_sock_unix_init(SOCK_SEQPACKET, 0, sock_path, + OSMO_SOCK_F_CONNECT); + if (ret < 0) { + /* Note: We will not free the allocated driver_data memory if + * opening the socket fails. The caller may want to call this + * function multiple times using config->fd.data as line + * parameter. Freeing now would destroy that reference. */ + LOGP(DLINP, LOGL_ERROR, + "unable to open socket: %s (line=%p, fd=%d)\n", sock_path, + line, config->fd.fd); + return ret; + } + LOGP(DLINP, LOGL_DEBUG, + "successfully opend (new) socket: %s (line=%p, fd=%d, ret=%d)\n", + sock_path, line, config->fd.fd, ret); + config->fd.fd = ret; + + /* Register socket in select loop */ + if (osmo_fd_register(&config->fd) < 0) { + LOGP(DLINP, LOGL_ERROR, + "error registering new socket (line=%p, fd=%d)\n", + line, config->fd.fd); + close(config->fd.fd); + return -EIO; + } + + /* Set line parameter */ + for (i = 0; i < ARRAY_SIZE(line->ts); i++) { + struct e1inp_ts *e1i_ts = &line->ts[i]; + if (!e1i_ts->lapd) { + e1i_ts->lapd = lapd_instance_alloc(1, + unixsocket_write_msg_lapd_cb, &config->fd, + e1inp_dlsap_up, e1i_ts, &lapd_profile_abis); + } + } + + /* Ensure ericsson-superchannel is turned of when + * a new connection is made */ + e1inp_ericsson_set_altc(line, 0); + + return ret; +} + +struct e1inp_driver unixsocket_driver = { + .name = "unixsocket", + .want_write = ts_want_write, + .line_update = unixsocket_line_update, + .default_delay = 0, +}; + +void e1inp_unixsocket_init(void) +{ + tall_unixsocket_ctx = talloc_named_const(libosmo_abis_ctx, 1, "unixsocket"); + e1inp_driver_register(&unixsocket_driver); +} + +void e1inp_ericsson_set_altc(struct e1inp_line *unixline, int superchannel) +{ + struct unixsocket_line *config; + struct msgb *msg; + + if (!unixline) + return; + + if (unixline->driver != &unixsocket_driver) { + LOGP(DLMI, LOGL_NOTICE, "altc is only supported by unixsocket\n"); + return; + } + + config = unixline->driver_data; + if (!config) { + LOGP(DLMI, LOGL_NOTICE, "e1inp driver not yet initialized.\n"); + return; + } + + + msg = msgb_alloc_headroom(200, 100, "ALTC"); + + /* version header */ + msgb_put_u8(msg, UNIXSOCKET_PROTO_VERSION); + /* data|control */ + msgb_put_u8(msg, UNIXSOCKET_PROTO_CONTROL); + + /* magic */ + msgb_put_u32(msg, 0x23004200); + msgb_put_u8(msg, superchannel ? 1 : 0); + + unixsocket_write_msg(msg, &config->fd); +} + diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/Makefile.am libosmo-abis-0.4.0/src/Makefile.am --- libosmo-abis-0.3.2+20151106git86fc3c8/src/Makefile.am 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/Makefile.am 2017-08-25 14:12:37.000000000 +0000 @@ -1,7 +1,8 @@ # 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 -ABIS_LIBVERSION=5:0:0 -TRAU_LIBVERSION=1:0:0 +# Please read chapter "Library interface versions" of the libtool documentation +# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html +ABIS_LIBVERSION=6:0:0 +TRAU_LIBVERSION=2:0:0 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS= -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS) @@ -24,7 +25,8 @@ input/lapd.c \ input/lapd_pcap.c \ input/misdn.c \ - input/rs232.c + input/rs232.c \ + input/unixsocket.c libosmotrau_la_CFLAGS = $(AM_CFLAGS) $(ORTP_CFLAGS) libosmotrau_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(TRAU_LIBVERSION) diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/subchan_demux.c libosmo-abis-0.4.0/src/subchan_demux.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/subchan_demux.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/subchan_demux.c 2017-08-25 14:12:37.000000000 +0000 @@ -289,17 +289,6 @@ return i; } -static int llist_len(struct llist_head *head) -{ - struct llist_head *entry; - int i = 0; - - llist_for_each(entry, head) - i++; - - return i; -} - /* evict the 'num_evict' number of oldest entries in the queue */ static void tx_queue_evict(struct mux_subch *sch, int num_evict) { @@ -327,7 +316,7 @@ int len) { struct mux_subch *sch = &mx->subch[s_nr]; - int list_len = llist_len(&sch->tx_queue); + unsigned int list_len = llist_count(&sch->tx_queue); struct subch_txq_entry *tqe = talloc_zero_size(tall_tqe_ctx, sizeof(*tqe) + len); if (!tqe) diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/src/trau/osmo_ortp.c libosmo-abis-0.4.0/src/trau/osmo_ortp.c --- libosmo-abis-0.3.2+20151106git86fc3c8/src/trau/osmo_ortp.c 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/src/trau/osmo_ortp.c 2017-08-25 14:12:37.000000000 +0000 @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -93,8 +94,11 @@ return LOGL_ERROR; } -static void my_ortp_logfn(OrtpLogLevel lev, const char *fmt, - va_list args) +static void my_ortp_logfn( +#if HAVE_ORTP_LOG_DOMAIN + const char *domain, +#endif + OrtpLogLevel lev, const char *fmt, va_list args) { osmo_vlogp(DLMIB, ortp_to_osmo_lvl(lev), __FILE__, 0, 0, fmt, args); @@ -105,11 +109,7 @@ static void ortp_sig_cb_ssrc(RtpSession *rs, void *data) { int port = rtp_session_get_local_port(rs); -#if 0 /* post 0.20.0 ORTP has this function */ uint32_t ssrc = rtp_session_get_recv_ssrc(rs); -#else - uint32_t ssrc = rs->rcv.ssrc; -#endif LOGP(DLMIB, LOGL_INFO, "osmo-ortp(%d): ssrc_changed to 0x%08x\n", port, ssrc); @@ -129,7 +129,7 @@ int port = rtp_session_get_local_port(rs); LOGP(DLMIB, LOGL_ERROR, - "osmo-ortp(%d): network_error\n", port); + "osmo-ortp(%d): network_error %s\n", port, (char *)data); } static void ortp_sig_cb_ts(RtpSession *rs, void *data) @@ -138,9 +138,27 @@ uint32_t ts = rtp_session_get_current_recv_ts(rs); LOGP(DLMIB, LOGL_NOTICE, - "osmo-ortp(%d): timestamp_jump, new TS %d\n", port, ts); + "osmo-ortp(%d): timestamp_jump, new TS %d, resyncing\n", port, ts); + rtp_session_resync(rs); } +static inline bool recv_with_cb(struct osmo_rtp_socket *rs) +{ + uint8_t *payload; + mblk_t *mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); + if (!mblk) + return false; + + int plen = rtp_get_payload(mblk, &payload); + /* hand into receiver */ + if (rs->rx_cb && plen > 0) + rs->rx_cb(rs, payload, plen, rtp_get_seqnumber(mblk), + rtp_get_timestamp(mblk), rtp_get_markbit(mblk)); + freemsg(mblk); + if (plen > 0) + return true; + return false; +} /*! \brief poll the socket for incoming data * \param[in] rs the socket to be polled @@ -148,23 +166,15 @@ */ int osmo_rtp_socket_poll(struct osmo_rtp_socket *rs) { - mblk_t *mblk; + if (rs->flags & OSMO_RTP_F_DISABLED) + return 0; - mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); - if (mblk) { - rtp_get_payload(mblk, &mblk->b_rptr); - /* hand into receiver */ - if (rs->rx_cb) - rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr); - //rs->rx_user_ts += 160; - freemsg(mblk); + if (recv_with_cb(rs)) return 1; - } else { - LOGP(DLMIB, LOGL_INFO, "osmo_rtp_poll(%u): ERROR!\n", - rs->rx_user_ts); - return 0; - } + + LOGP(DLMIB, LOGL_INFO, "osmo_rtp_socket_poll(%u): ERROR!\n", + rs->rx_user_ts); + return 0; } /* Osmo FD callbacks */ @@ -172,7 +182,6 @@ static int osmo_rtp_fd_cb(struct osmo_fd *fd, unsigned int what) { struct osmo_rtp_socket *rs = fd->data; - mblk_t *mblk; if (what & BSC_FD_READ) { /* in polling mode, we don't want to be called here */ @@ -180,15 +189,7 @@ fd->when &= ~BSC_FD_READ; return 0; } - mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); - if (mblk) { - rtp_get_payload(mblk, &mblk->b_rptr); - /* hand into receiver */ - if (rs->rx_cb) - rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr); - freemsg(mblk); - } else + if (!recv_with_cb(rs)) LOGP(DLMIB, LOGL_INFO, "recvm_with_ts(%u): ERROR!\n", rs->rx_user_ts); rs->rx_user_ts += 160; @@ -198,6 +199,10 @@ return 0; } +/* Internal API coming from rtpsession_priv.h, used in osmo_rtcp_fd_cb */ +#pragma message ("Using internal ortp API: rtp_session_rtcp_rec") +int rtp_session_rtcp_recv(RtpSession * session); + static int osmo_rtcp_fd_cb(struct osmo_fd *fd, unsigned int what) { struct osmo_rtp_socket *rs = fd->data; @@ -210,16 +215,24 @@ static int osmo_rtp_socket_fdreg(struct osmo_rtp_socket *rs) { + int rc; + rs->rtp_bfd.fd = rtp_session_get_rtp_socket(rs->sess); rs->rtcp_bfd.fd = rtp_session_get_rtcp_socket(rs->sess); rs->rtp_bfd.when = rs->rtcp_bfd.when = BSC_FD_READ; - rs->rtp_bfd.when = rs->rtcp_bfd.when = 0; rs->rtp_bfd.data = rs->rtcp_bfd.data = rs; rs->rtp_bfd.cb = osmo_rtp_fd_cb; rs->rtcp_bfd.cb = osmo_rtcp_fd_cb; - osmo_fd_register(&rs->rtp_bfd); - osmo_fd_register(&rs->rtcp_bfd); + rc = osmo_fd_register(&rs->rtp_bfd); + if (rc < 0) + return rc; + + rc = osmo_fd_register(&rs->rtcp_bfd); + if (rc < 0) { + osmo_fd_unregister(&rs->rtp_bfd); + return rc; + } return 0; } @@ -267,33 +280,45 @@ tall_rtp_ctx = ctx; ortp_set_memory_functions(&osmo_ortp_memfn); ortp_init(); - ortp_set_log_level_mask(0xffff); + ortp_set_log_level_mask( +#if HAVE_ORTP_LOG_DOMAIN + ORTP_LOG_DOMAIN, +#endif + 0xffff); + ortp_set_log_handler(my_ortp_logfn); create_payload_types(); } +/*! \brief Set Osmocom RTP socket parameters + * \param[in] rs OsmoRTP socket + * \param[in] param defined which parameter to set + OSMO_RTP_P_JITBUF - enables regular jitter buffering + OSMO_RTP_P_JIT_ADAP - enables adaptive jitter buffering + * \param[in] val Size of jitter buffer (in ms), 0 means disable buffering + * \returns negative value on error, 0 or 1 otherwise + (depending on whether given jitter buffering is enabled) + */ int osmo_rtp_socket_set_param(struct osmo_rtp_socket *rs, enum osmo_rtp_param param, int val) { - int rc = 0; - switch (param) { + case OSMO_RTP_P_JIT_ADAP: + rtp_session_enable_adaptive_jitter_compensation(rs->sess, + (bool)val); + /* fall-through on-purpose - we have to set val anyway */ case OSMO_RTP_P_JITBUF: rtp_session_enable_jitter_buffer(rs->sess, (val) ? TRUE : FALSE); if (val) rtp_session_set_jitter_compensation(rs->sess, val); break; -#if 0 - case OSMO_RTP_P_JIT_ADAP: - rc = jitter_control_enable_adaptive(rs->sess, val); - break; -#endif default: return -EINVAL; } - - return rc; + if (param == OSMO_RTP_P_JIT_ADAP) + return rtp_session_adaptive_jitter_compensation_enabled(rs->sess); + return rtp_session_jitter_buffer_enabled(rs->sess); } /*! \brief Create a new RTP socket @@ -313,7 +338,7 @@ if (!rs) return NULL; - rs->flags = flags; + rs->flags = OSMO_RTP_F_DISABLED | flags; rs->sess = rtp_session_new(RTP_SESSION_SENDRECV); if (!rs->sess) { talloc_free(rs); @@ -322,25 +347,27 @@ rtp_session_set_data(rs->sess, rs); rtp_session_set_profile(rs->sess, osmo_pt_profile); rtp_session_set_jitter_compensation(rs->sess, 100); - //jitter_control_enable_adaptive(rs->sess, 0); rtp_session_signal_connect(rs->sess, "ssrc_changed", (RtpCallback) ortp_sig_cb_ssrc, - (unsigned long) rs); + RTP_SIGNAL_PTR_CAST(rs)); + rtp_session_signal_connect(rs->sess, "payload_type_changed", (RtpCallback) ortp_sig_cb_pt, - (unsigned long) rs); + RTP_SIGNAL_PTR_CAST(rs)); + rtp_session_signal_connect(rs->sess, "network_error", (RtpCallback) ortp_sig_cb_net, - (unsigned long) rs); + RTP_SIGNAL_PTR_CAST(rs)); + rtp_session_signal_connect(rs->sess, "timestamp_jump", (RtpCallback) ortp_sig_cb_ts, - (unsigned long) rs); + RTP_SIGNAL_PTR_CAST(rs)); /* initialize according to the RFC */ rtp_session_set_seq_number(rs->sess, random()); rs->tx_timestamp = random(); - + return rs; } @@ -353,12 +380,9 @@ */ int osmo_rtp_socket_bind(struct osmo_rtp_socket *rs, const char *ip, int port) { - int rc; -#if HAVE_ORTP_021 - rc = rtp_session_set_local_addr(rs->sess, ip, port, port+1); -#else - rc = rtp_session_set_local_addr(rs->sess, ip, port); -#endif + int rc, rtcp = (-1 != port) ? port + 1 : -1; + rc = rtp_session_set_local_addr(rs->sess, ip, port, rtcp); + if (rc < 0) return rc; @@ -382,22 +406,58 @@ int osmo_rtp_socket_connect(struct osmo_rtp_socket *rs, const char *ip, uint16_t port) { int rc; + if (!port) { + LOGP(DLMIB, LOGL_INFO, "osmo_rtp_socket_connect() refused to " + "set remote %s:%u\n", ip, port); + return 0; + } - /* enable the use of connect() so later getsockname() will - * actually return the IP address that was chosen for the local - * sid of the connection */ - rtp_session_set_connected_mode(rs->sess, 1); + /* We don't want the connected mode enabled during + * rtp_session_set_remote_addr(), because that will already setup a + * connection and updating the remote address will no longer have an + * effect. Contrary to what one may expect, this must be 0 at first, + * and we're setting to 1 further down to establish a connection once + * the first RTP packet is received (OS#1661). */ + rtp_session_set_connected_mode(rs->sess, 0); rc = rtp_session_set_remote_addr(rs->sess, ip, port); if (rc < 0) return rc; + /* enable the use of connect() so later getsockname() will + * actually return the IP address that was chosen for the local + * sid of the connection */ + rtp_session_set_connected_mode(rs->sess, 1); + rs->flags &= ~OSMO_RTP_F_DISABLED; + if (rs->flags & OSMO_RTP_F_POLL) return rc; else return osmo_rtp_socket_fdreg(rs); } +/*! \brief Increment timestamp on a RTP socket without sending any packet + * \param[in] rs OsmoRTP socket + * \param[in] duration duration in number of RTP clock ticks + * + * Useful to keep the RTP internal clock up to date if an RTP frame should be + * send at a given time but no audio content is available. When next packet is + * sent, the receiver will see a different increase on the sequence number and + * the timestamp, and it should then take it as a synchronization point. For + * that same reason, it is advisable to enable the marker bit on the next RTP + * packet to be sent after calling this function. + * + * \returns 0 on success, <0 in case of error. + */ +int osmo_rtp_skipped_frame(struct osmo_rtp_socket *rs, unsigned int duration) +{ + if (rs->flags & OSMO_RTP_F_DISABLED) + return 0; + + rs->tx_timestamp += duration; + return 0; +} + /*! \brief Send one RTP frame via a RTP socket * \param[in] rs OsmoRTP socket * \param[in] payload pointer to buffer with RTP payload data @@ -408,14 +468,34 @@ int osmo_rtp_send_frame(struct osmo_rtp_socket *rs, const uint8_t *payload, unsigned int payload_len, unsigned int duration) { + return osmo_rtp_send_frame_ext(rs, payload, payload_len, duration, + false); +} + +/*! \brief Send one RTP frame via a RTP socket + * \param[in] rs OsmoRTP socket + * \param[in] payload pointer to buffer with RTP payload data + * \param[in] payload_len length of \a payload in bytes + * \param[in] duration duration in number of RTP clock ticks + * \param[in] marker the status of Marker bit in RTP header + * \returns 0 on success, <0 in case of error. + */ +int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload, + unsigned int payload_len, unsigned int duration, + bool marker) +{ mblk_t *mblk; int rc; + if (rs->flags & OSMO_RTP_F_DISABLED) + return 0; + mblk = rtp_session_create_packet(rs->sess, RTP_FIXED_HEADER_SIZE, payload, payload_len); if (!mblk) return -ENOMEM; + rtp_set_markbit(mblk, marker); rc = rtp_session_sendm_with_ts(rs->sess, mblk, rs->tx_timestamp); rs->tx_timestamp += duration; @@ -567,11 +647,9 @@ *recv_lost = stats->cum_packet_loss; } -#if HAVE_ORTP_021 const jitter_stats_t *jitter; jitter = rtp_session_get_jitter_stats(rs->sess); if (jitter) *last_jitter = jitter->jitter; -#endif } diff -Nru libosmo-abis-0.3.2+20151106git86fc3c8/TODO-RELEASE libosmo-abis-0.4.0/TODO-RELEASE --- libosmo-abis-0.3.2+20151106git86fc3c8/TODO-RELEASE 2015-11-07 11:33:40.000000000 +0000 +++ libosmo-abis-0.4.0/TODO-RELEASE 2017-08-25 14:12:37.000000000 +0000 @@ -1 +1,9 @@ +# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install +# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info +# In short: +# LIBVERSION=c:r:a +# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a. +# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0. +# If any interfaces have been added since the last public release: c:r:a + 1. +# If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line