Codebase list libosmo-netif / dfd4286
Import Upstream version 1.2.0 Thorsten Alteholz 1 year, 6 months ago
19 changed file(s) with 1202 addition(s) and 159 deletion(s). Raw diff Collapse all Expand all
1616
1717 You can clone from the official libosmo-netif.git repository using
1818
19 git clone git://git.osmocom.org/libosmo-netif.git
19 git clone https://gitea.osmocom.org/osmocom/libosmo-netif
2020
21 There is a cgit interface at <http://git.osmocom.org/libosmo-netif/>
21 There is a web interface at <https://gitea.osmocom.org/osmocom/libosmo-netif>
2222
2323 Documentation
2424 -------------
8888 dnl Generate the output
8989 AM_CONFIG_HEADER(config.h)
9090
91 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
92 PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.5.0)
91 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
92 PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
9393
9494 AC_ARG_ENABLE([lapd_examples],
9595 [AS_HELP_STRING(
9898 )],
9999 [lapd_examples=$enableval], [lapd_examples="no"])
100100 AS_IF([test "x$lapd_examples" = "xyes"], [
101 PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0)
101 PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
102102 AC_DEFINE([ENABLE_LAPD], [1], [Enable LAPD examples])
103103 ])
104104 AM_CONDITIONAL(ENABLE_LAPD, test "x$lapd_examples" = "xyes")
2323 BuildRequires: libtool >= 2
2424 BuildRequires: lksctp-tools-devel
2525 BuildRequires: pkgconfig >= 0.20
26 BuildRequires: pkgconfig(libosmocore) >= 1.5.0
27 BuildRequires: pkgconfig(libosmogsm) >= 1.5.0
26 BuildRequires: pkgconfig(libosmocore) >= 1.7.0
27 BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
2828
2929 %description
3030 Network interface demuxer library for OsmoCom projects.
0 libosmo-netif (1.2.0) unstable; urgency=medium
1
2 [ Pau Espin Pedrol ]
3 * Introduce sctp.h to provide SCTP related functionalities
4 * stream: Factor out sctp_recvmg long code chunk
5 * stream: Add support for AF_UNIX sockets
6 * Introduce osmo_prim_srv APIs
7 * prim: Add internal CTL SAPI to negotiate SAP versions
8 * prim: return last error code
9 * amr: Fix FormatType from parsing BWE AMR header
10 * amr: Fix length check in bwe<->iuup converters
11
12 [ Alexander Couzens ]
13 * amr: don't rely on pad bits to be zero
14 * export osmo_amr_bits
15 * amr: Introduce APIs to convert BE to IuUP/IuFP format
16
17 [ Philipp Maier ]
18 * amr: cosmetic: fix grammer in comment
19 * amr_test: increase test coverage for oa / bwe conversation
20
21 [ Harald Welte ]
22 * update git URLs (git -> https; gitea)
23
24 -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 28 Jun 2022 18:09:49 +0200
25
026 libosmo-netif (1.1.0) unstable; urgency=medium
127
228 [ Vadim Yanitskiy ]
1010 libdpkg-perl,
1111 git,
1212 doxygen,
13 libosmocore-dev (>= 1.5.0),
13 libosmocore-dev (>= 1.7.0),
1414 pkg-config,
1515 libpcap0.8-dev,
1616 libsctp-dev
1717 Standards-Version: 3.9.6
18 Vcs-Browser: http://git.osmocom.org/libosmo-netif/
19 Vcs-Git: git://git.osmocom.org/libosmo-netif.git
18 Vcs-Browser: https://gitea.osmocom.org/osmocom/libosmo-netif
19 Vcs-Git: https://gitea.osmocom.org/osmocom/libosmo-netif
2020 Homepage: https://projects.osmocom.org/projects/libosmo-netif
2121
2222 Package: libosmonetif8
00 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
11 Upstream-Name: libosmo-netif
2 Source: git://git.osmocom.org/libosmo-netif.git
2 Source: https://gitea.osmocom.org/osmocom/libosmo-netif
33
44 Files: *
55 Copyright: 2012-2013 On-Waves
33 osmux.h \
44 ipa.h \
55 ipa_unit.h \
6 prim.h \
67 rs232.h \
78 rtp.h \
89 stream.h
910
11 if ENABLE_LIBSCTP
12 osmonetif_HEADERS += sctp.h
13 endif
14
1015 osmonetifdir = $(includedir)/osmocom/netif
108108
109109 int osmo_amr_ft_valid(uint8_t amr_ft);
110110 size_t osmo_amr_bytes(uint8_t amr_cmr);
111 size_t osmo_amr_bits(uint8_t amr_ft);
111112
112113 bool osmo_amr_is_oa(uint8_t *payload, unsigned int payload_len);
113114 int osmo_amr_oa_to_bwe(uint8_t *payload, unsigned int payload_len);
114115 int osmo_amr_bwe_to_oa(uint8_t *payload, unsigned int payload_len,
115116 unsigned int payload_maxlen);
117 int osmo_amr_bwe_to_iuup(uint8_t *payload, unsigned int payload_len);
118 int osmo_amr_iuup_to_bwe(uint8_t *payload, unsigned int payload_len,
119 unsigned int payload_maxlen);
120 int osmo_amr_bytes_to_ft(size_t bytes);
116121
117122 #endif
0 /* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
1 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
2 * All Rights Reserved
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/lienses/>.
16 *
17 */
18 #pragma once
19
20 #include <stdint.h>
21
22 #include <osmocom/core/prim.h>
23 #include <osmocom/core/select.h>
24 #include <osmocom/core/linuxlist.h>
25
26 struct osmo_prim_srv_link;
27 struct osmo_prim_srv;
28
29 typedef int (*osmo_prim_srv_conn_cb)(struct osmo_prim_srv *prim_srv);
30 /*! oph and related msgb is owned by srv and wll be freed after the callback returns. */
31 typedef int (*osmo_prim_srv_rx_cb)(struct osmo_prim_srv *prim_srv, struct osmo_prim_hdr *oph);
32
33 /*! Return value:
34 * RET=rem_version: Accept the version
35 * RET!=rem_version && RET > 0: Reject the requested version but propose another candidate version
36 * In this case, the client can decide whether to request another VER
37 * or close the connection.
38 * RET<0: Reject the proposed version and close the connection.
39 */
40 typedef int (*osmo_prim_srv_rx_sapi_version)(struct osmo_prim_srv *prim_srv, uint32_t sapi, uint16_t rem_version);
41
42 struct osmo_prim_hdr *osmo_prim_msgb_alloc(unsigned int sap, unsigned int primitive,
43 enum osmo_prim_operation operation, size_t alloc_len);
44
45 struct osmo_prim_srv_link *osmo_prim_srv_link_alloc(void *ctx);
46 void osmo_prim_srv_link_free(struct osmo_prim_srv_link *prim_link);
47 int osmo_prim_srv_link_set_addr(struct osmo_prim_srv_link *prim_link, const char *path);
48 const char *osmo_prim_srv_link_get_addr(struct osmo_prim_srv_link *prim_link);
49 void osmo_prim_srv_link_set_priv(struct osmo_prim_srv_link *prim_link, void *priv);
50 void *osmo_prim_srv_link_get_priv(const struct osmo_prim_srv_link *prim_link);
51 void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat);
52 void osmo_prim_srv_link_set_opened_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb opened_conn_cb);
53 void osmo_prim_srv_link_set_closed_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb closed_conn_cb);
54 void osmo_prim_srv_link_set_rx_sapi_version_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_sapi_version rx_sapi_version_cb);
55 void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb);
56 void osmo_prim_srv_link_set_rx_msgb_alloc_len(struct osmo_prim_srv_link *prim_link, size_t alloc_len);
57 int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link);
58
59 int osmo_prim_srv_send(struct osmo_prim_srv *prim_srv, struct msgb *msg);
60 struct osmo_prim_srv_link *osmo_prim_srv_get_link(struct osmo_prim_srv *prims_srv);
61 void osmo_prim_srv_set_priv(struct osmo_prim_srv *prim_srv, void *priv);
62 void *osmo_prim_srv_get_priv(const struct osmo_prim_srv *prim_srv);
63 void osmo_prim_srv_close(struct osmo_prim_srv *prim_srv);
0 #pragma once
1
2 #include <osmocom/core/utils.h>
3
4 enum sctp_sac_state;
5 extern const struct value_string osmo_sctp_assoc_chg_strs[];
6 static inline const char *osmo_sctp_assoc_chg_str(enum sctp_sac_state val)
7 { return get_value_string(osmo_sctp_assoc_chg_strs, val); }
8
9 enum sctp_sn_type;
10 extern const struct value_string osmo_sctp_sn_type_strs[];
11 static inline const char *osmo_sctp_sn_type_str(enum sctp_sn_type val)
12 { return get_value_string(osmo_sctp_sn_type_strs, val); }
2424 int osmo_stream_srv_link_set_addrs(struct osmo_stream_srv_link *link, const char **addr, size_t addrcnt);
2525 void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port);
2626 void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto);
27 int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type);
28 int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain);
2729 void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)(struct osmo_stream_srv_link *link, int fd));
2830 void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data);
2931 void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link);
5658 void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr);
5759 int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt);
5860 void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port);
61 int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type);
62 int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain);
5963 void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto);
6064 void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr);
6165 int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt);
00 # This is _NOT_ the library release version, it's an API version.
11 # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
2 LIBVERSION=9:1:1
2 LIBVERSION=10:0:2
33
44 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)
55 AM_CFLAGS= -fPIC -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSCTP_CFLAGS)
1616 ipa_unit.c \
1717 jibuf.c \
1818 osmux.c \
19 prim.c \
1920 rs232.c \
2021 rtp.c \
2122 stream.c
23
24 if ENABLE_LIBSCTP
25 libosmonetif_la_SOURCES += sctp.c
26 endif
6060 size_t osmo_amr_bytes(uint8_t amr_ft)
6161 {
6262 return amr_ft_to_bytes[amr_ft];
63 }
64
65 int osmo_amr_bytes_to_ft(size_t bytes)
66 {
67 int ft;
68
69 for (ft = 0; ft < AMR_FT_MAX; ft++) {
70 if (amr_ft_to_bytes[ft] == bytes)
71 return ft;
72 }
73 return -1;
6374 }
6475
6576 int osmo_amr_ft_valid(uint8_t amr_ft)
91102 * mode normally relys on out of band methods that explicitly select
92103 * one of the two modes. (See also RFC 3267, chapter 3.8). However the
93104 * A interface in GSM does not provide ways to communicate which mode
94 * is used exactly used. The following functions uses some heuristics
95 * to check if an AMR payload is octet aligned or not. */
105 * is exactly used. The following functions uses some heuristics to
106 * check if an AMR payload is octet aligned or not. */
96107
97108 struct amr_hdr *oa_hdr = (struct amr_hdr *)payload;
98109 unsigned int frame_len;
151162 return -1;
152163
153164 /* Move TOC close to CMR */
154 payload[0] |= (payload[1] >> 4) & 0x0f;
165 payload[0] = (payload[0] & 0xf0) | ((payload[1] >> 4) & 0x0f);
155166 payload[1] = (payload[1] << 4) & 0xf0;
156167
157168 for (i = 0; i < frame_len; i++) {
206217 memcpy(payload, buf, oa_payload_len);
207218 return oa_payload_len;
208219 }
220
221 /*! Convert an AMR frame from bandwith-efficient mode to IuuP/IuFP payload.
222 * The IuuP/IuPF payload only contains the class a, b, c bits. No header.
223 * \param[inout] payload user provided memory containing the AMR payload.
224 * \param[in] payload_len overall length of the AMR payload.
225 * \param[in] payload_maxlen maximum length of the user provided memory.
226 * \returns resulting payload length, negative on error. */
227 int osmo_amr_bwe_to_iuup(uint8_t *payload, unsigned int payload_len)
228 {
229 /* The header is only valid after shifting first two bytes to OA mode */
230 unsigned int i, required_len_bits;
231 unsigned int amr_speech_len_bytes, amr_speech_len_bits;
232 uint8_t ft;
233
234 if (payload_len < 2)
235 return -1;
236
237 /* Calculate new payload length */
238 ft = ((payload[0] & 0x07) << 1) | ((payload[1] & 0x80) >> 7);
239 if (!osmo_amr_ft_valid(ft))
240 return -1;
241
242 amr_speech_len_bits = osmo_amr_bits(ft);
243 amr_speech_len_bytes = osmo_amr_bytes(ft);
244
245 required_len_bits = amr_speech_len_bits + 10; /* shift of 10 bits */
246 if (payload_len < (required_len_bits + 7)/8)
247 return -1;
248
249 for (i = 0; i < amr_speech_len_bytes; i++) {
250 /* we have to shift the payload by 10 bits to get only the Class A, B, C bits */
251 payload[i] = (payload[i + 1] << 2) | ((payload[i + 2]) >> 6);
252 }
253
254 return amr_speech_len_bytes;
255 }
256
257 /*! Convert an AMR frame from IuuP/IuFP payload to bandwith-efficient mode.
258 * The IuuP/IuPF payload only contains the class a, b, c bits. No header.
259 * The resulting buffer has space at the start prepared to be filled by CMR, TOC.
260 * \param[inout] payload user provided memory containing the AMR payload.
261 * \param[in] payload_len overall length of the AMR payload.
262 * \param[in] payload_maxlen maximum length of the user provided memory (payload_len + 2 required).
263 * \returns resulting payload length, negative on error. */
264 int osmo_amr_iuup_to_bwe(uint8_t *payload, unsigned int payload_len,
265 unsigned int payload_maxlen)
266 {
267 /* shift all bits by 10 */
268 unsigned int i, required_len_bits, required_len_bytes;
269
270 int ft = osmo_amr_bytes_to_ft(payload_len);
271 if (ft < 0)
272 return ft;
273
274 required_len_bits = osmo_amr_bits(ft) + 10;
275 required_len_bytes = (required_len_bits + 7)/8;
276 if (payload_maxlen < required_len_bytes)
277 return -1;
278
279 i = payload_len + 1;
280 payload[i] = (payload[i - 2] << 6);
281 for (i = payload_len; i >= 2; i--) {
282 /* we have to shift the payload by 10 bits to get only the Class A, B, C bits */
283 payload[i] = (payload[i - 1] >> 2) | (payload[i - 2] << 6);
284 }
285 payload[i] = (payload[i - 1] >> 2);
286 payload[0] = 0;
287 return required_len_bytes;
288 }
0 /* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
1 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
2 * All Rights Reserved
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <inttypes.h>
30
31 #include <osmocom/core/talloc.h>
32 #include <osmocom/core/select.h>
33 #include <osmocom/core/socket.h>
34 #include <osmocom/core/logging.h>
35
36 #include <osmocom/netif/prim.h>
37 #include <osmocom/netif/stream.h>
38
39 struct osmo_prim_pkt_hdr {
40 uint32_t sap; /*!< Service Access Point Identifier */
41 uint16_t primitive; /*!< Primitive number */
42 uint16_t operation; /*! Primitive Operation (enum osmo_prim_operation) */
43 } __attribute__ ((packed));
44
45 /* Here we take advantage of the fact that sizeof(struct
46 * osmo_prim_pkt_hdr) <= sizeof(struct osmo_prim_hdr), so we don't need
47 * to allocate headroom when serializing later.
48 */
49 osmo_static_assert(sizeof(struct osmo_prim_pkt_hdr) <= sizeof(struct osmo_prim_hdr),
50 osmo_prim_msgb_alloc_validate_headroom);
51
52 /*! Allocate a primitive of given type and its associated msgb.
53 * \param[in] sap Service Access Point
54 * \param[in] primitive Primitive Number
55 * \param[in] operation Primitive Operation (REQ/RESP/IND/CONF)
56 * \param[in] alloc_len Total length (including struct osmo_prim_hdr) to allocate for the primitive
57 * \returns Pointer to allocated prim_hdr inisde its own msgb. The osmo_prim_hdr
58 * is pre-alocated & pre-filled.
59 */
60 struct osmo_prim_hdr *osmo_prim_msgb_alloc(unsigned int sap, unsigned int primitive,
61 enum osmo_prim_operation operation, size_t alloc_len)
62 {
63 struct msgb *msg;
64 struct osmo_prim_hdr *oph;
65
66 if (alloc_len < sizeof(*oph))
67 return NULL;
68
69 msg = msgb_alloc(alloc_len, "osmo_prim_msgb_alloc");
70 oph = (struct osmo_prim_hdr *)msgb_put(msg, sizeof(*oph));
71 osmo_prim_init(oph, sap, primitive, operation, msg);
72 msg->l2h = msg->tail;
73
74 return oph;
75 }
76
77 struct osmo_prim_srv_link {
78 void *priv;
79 char *addr;
80 int log_cat; /* Defaults to DLGLOBAL */
81 struct osmo_stream_srv_link *stream;
82 osmo_prim_srv_conn_cb opened_conn_cb;
83 osmo_prim_srv_conn_cb closed_conn_cb;
84 osmo_prim_srv_rx_sapi_version rx_sapi_version_cb;
85 osmo_prim_srv_rx_cb rx_cb;
86 size_t rx_msgb_alloc_len;
87 };
88
89 struct osmo_prim_srv {
90 void *priv;
91 struct osmo_prim_srv_link *link; /* backpointer */
92 struct osmo_stream_srv *stream;
93 };
94
95 /******************************
96 * CONTROL SAP
97 ******************************/
98 #define OSMO_PRIM_CTL_SAPI 0xffffffff
99 #define OSMO_PRIM_CTL_API_VERSION 0
100
101 enum sap_ctl_prim_type {
102 SAP_CTL_PRIM_HELLO,
103 _SAP_CTL_PRIM_MAX
104 };
105
106 const struct value_string sap_ctl_prim_type_names[] = {
107 OSMO_VALUE_STRING(SAP_CTL_PRIM_HELLO),
108 { 0, NULL }
109 };
110
111 /* HNB_CTL_PRIM_HELLO.ind, UL */
112 struct sap_ctl_hello_param {
113 uint32_t sapi; /* SAPI for which we negotiate version */
114 uint16_t api_version; /* The intended version */
115 } __attribute__ ((packed));
116
117 struct sap_ctl_prim {
118 struct osmo_prim_hdr hdr;
119 union {
120 struct sap_ctl_hello_param hello_req;
121 struct sap_ctl_hello_param hello_cnf;
122 } u;
123 } __attribute__ ((packed));
124
125 static struct sap_ctl_prim *_sap_ctl_makeprim_hello_cnf(uint32_t sapi, uint16_t api_version)
126 {
127 struct sap_ctl_prim *ctl_prim;
128
129 ctl_prim = (struct sap_ctl_prim *)osmo_prim_msgb_alloc(
130 OSMO_PRIM_CTL_SAPI, SAP_CTL_PRIM_HELLO, PRIM_OP_CONFIRM,
131 sizeof(struct osmo_prim_hdr) + sizeof(struct sap_ctl_hello_param));
132 msgb_put(ctl_prim->hdr.msg, sizeof(struct sap_ctl_hello_param));
133 ctl_prim->u.hello_cnf.sapi = sapi;
134 ctl_prim->u.hello_cnf.api_version = api_version;
135
136 return ctl_prim;
137 }
138
139 /******************************
140 * osmo_prim_srv
141 ******************************/
142 #define LOGSRV(srv, lvl, fmt, args...) LOGP((srv)->link->log_cat, lvl, fmt, ## args)
143
144 static int _srv_sap_ctl_rx_hello_req(struct osmo_prim_srv *prim_srv, struct sap_ctl_hello_param *hello_ind)
145 {
146 struct sap_ctl_prim *prim_resp;
147 int rc;
148
149 LOGSRV(prim_srv, LOGL_INFO, "Rx CTL-HELLO.req SAPI=%u API_VERSION=%u\n", hello_ind->sapi, hello_ind->api_version);
150
151 if (hello_ind->sapi == OSMO_PRIM_CTL_SAPI)
152 rc = hello_ind->api_version == OSMO_PRIM_CTL_API_VERSION ? OSMO_PRIM_CTL_API_VERSION : -1;
153 else if (prim_srv->link->rx_sapi_version_cb)
154 rc = prim_srv->link->rx_sapi_version_cb(prim_srv, hello_ind->sapi, hello_ind->api_version);
155 else /* Accept whatever version by default: */
156 rc = hello_ind->api_version;
157
158 if (rc < 0) {
159 LOGSRV(prim_srv, LOGL_ERROR,
160 "SAPI=%u API_VERSION=%u not supported! destroying connection\n",
161 hello_ind->sapi, hello_ind->api_version);
162 osmo_stream_srv_set_flush_and_destroy(prim_srv->stream);
163 return rc;
164 }
165 prim_resp = _sap_ctl_makeprim_hello_cnf(hello_ind->sapi, (uint16_t)rc);
166 LOGSRV(prim_srv, LOGL_INFO, "Tx CTL-HELLO.cnf SAPI=%u API_VERSION=%u\n",
167 hello_ind->sapi, prim_resp->u.hello_cnf.api_version);
168 rc = osmo_prim_srv_send(prim_srv, prim_resp->hdr.msg);
169 return rc;
170 }
171
172 static int _srv_sap_ctl_rx(struct osmo_prim_srv *prim_srv, struct osmo_prim_hdr *oph)
173 {
174 switch (oph->operation) {
175 case PRIM_OP_REQUEST:
176 switch (oph->primitive) {
177 case SAP_CTL_PRIM_HELLO:
178 return _srv_sap_ctl_rx_hello_req(prim_srv, (struct sap_ctl_hello_param *)msgb_data(oph->msg));
179 default:
180 LOGSRV(prim_srv, LOGL_ERROR, "Rx unknown CTL SAP primitive %u (len=%u)\n",
181 oph->primitive, msgb_length(oph->msg));
182 return -EINVAL;
183 }
184 break;
185 case PRIM_OP_RESPONSE:
186 case PRIM_OP_INDICATION:
187 case PRIM_OP_CONFIRM:
188 default:
189 LOGSRV(prim_srv, LOGL_ERROR, "Rx CTL SAP unexpected primitive operation %s-%s (len=%u)\n",
190 get_value_string(sap_ctl_prim_type_names, oph->primitive),
191 get_value_string(osmo_prim_op_names, oph->operation),
192 msgb_length(oph->msg));
193 return -EINVAL;
194 }
195 }
196
197 static int _osmo_prim_srv_read_cb(struct osmo_stream_srv *srv)
198 {
199 struct osmo_prim_srv *prim_srv = osmo_stream_srv_get_data(srv);
200 struct osmo_prim_pkt_hdr *pkth;
201 struct msgb *msg;
202 struct osmo_prim_hdr oph;
203 int rc;
204
205 msg = msgb_alloc_c(prim_srv, sizeof(*pkth) + prim_srv->link->rx_msgb_alloc_len,
206 "osmo_prim_srv_link_rx");
207 if (!msg)
208 return -ENOMEM;
209 rc = osmo_stream_srv_recv(srv, msg);
210 if (rc == 0)
211 goto close;
212
213 if (rc < 0) {
214 if (errno == EAGAIN) {
215 msgb_free(msg);
216 return 0;
217 }
218 goto close;
219 }
220
221 if (rc < sizeof(*pkth)) {
222 LOGSRV(prim_srv, LOGL_ERROR, "Received %d bytes on UD Socket, but primitive hdr size "
223 "is %zu, discarding\n", rc, sizeof(*pkth));
224 msgb_free(msg);
225 return 0;
226 }
227 pkth = (struct osmo_prim_pkt_hdr *)msgb_data(msg);
228
229 /* De-serialize message: */
230 osmo_prim_init(&oph, pkth->sap, pkth->primitive, pkth->operation, msg);
231 msgb_pull(msg, sizeof(*pkth));
232
233 switch (oph.sap) {
234 case OSMO_PRIM_CTL_SAPI:
235 rc = _srv_sap_ctl_rx(prim_srv, &oph);
236 break;
237 default:
238 if (prim_srv->link->rx_cb)
239 rc = prim_srv->link->rx_cb(prim_srv, &oph);
240 break;
241 }
242 /* as we always synchronously process the message in _osmo_prim_srv_link_rx() and
243 * its callbacks, we can free the message here. */
244 msgb_free(msg);
245
246 return rc;
247
248 close:
249 msgb_free(msg);
250 osmo_prim_srv_close(prim_srv);
251 return -1;
252 }
253
254 static void osmo_prim_srv_free(struct osmo_prim_srv *prim_srv);
255 static int _osmo_prim_srv_closed_cb(struct osmo_stream_srv *srv)
256 {
257 struct osmo_prim_srv *prim_srv = osmo_stream_srv_get_data(srv);
258 struct osmo_prim_srv_link *prim_link = prim_srv->link;
259 if (prim_link->closed_conn_cb)
260 return prim_link->closed_conn_cb(prim_srv);
261 osmo_prim_srv_free(prim_srv);
262 return 0;
263 }
264
265 /*! Allocate a primitive of given type and its associated msgb.
266 * \param[in] srv The osmo_prim_srv_link instance where message is to be sent through
267 * \param[in] msg msgb containing osmo_prim_hdr plus extra content, allocated through \ref osmo_prim_msgb_alloc()
268 * \returns zero on success, negative on error */
269 int osmo_prim_srv_send(struct osmo_prim_srv *prim_srv, struct msgb *msg)
270 {
271 struct osmo_prim_hdr *oph;
272 struct osmo_prim_pkt_hdr *pkth;
273 unsigned int sap;
274 unsigned int primitive;
275 enum osmo_prim_operation operation;
276
277 /* Serialize the oph: */
278 oph = (struct osmo_prim_hdr *)msgb_data(msg);
279 OSMO_ASSERT(oph && msgb_length(msg) >= sizeof(*oph));
280 sap = oph->sap;
281 primitive = oph->primitive;
282 operation = oph->operation;
283 msgb_pull(msg, sizeof(*oph));
284 pkth = (struct osmo_prim_pkt_hdr *)msgb_push(msg, sizeof(*pkth));
285 pkth->sap = sap;
286 pkth->primitive = primitive;
287 pkth->operation = operation;
288
289 /* Finally enqueue the msg */
290 osmo_stream_srv_send(prim_srv->stream, msg);
291
292 return 0;
293 }
294
295 static struct osmo_prim_srv *osmo_prim_srv_alloc(struct osmo_prim_srv_link *prim_link, int fd)
296 {
297 struct osmo_prim_srv *prim_srv;
298 prim_srv = talloc_zero(prim_link, struct osmo_prim_srv);
299 if (!prim_srv)
300 return NULL;
301 prim_srv->link = prim_link;
302 prim_srv->stream = osmo_stream_srv_create(prim_link, prim_link->stream, fd,
303 _osmo_prim_srv_read_cb,
304 _osmo_prim_srv_closed_cb,
305 prim_srv);
306 if (!prim_srv->stream) {
307 talloc_free(prim_srv);
308 return NULL;
309 }
310 /* Inherit link priv pointer by default, user can later set it through API: */
311 prim_srv->priv = prim_link->priv;
312 return prim_srv;
313 }
314
315 static void osmo_prim_srv_free(struct osmo_prim_srv *prim_srv)
316 {
317 talloc_free(prim_srv);
318 }
319
320 struct osmo_prim_srv_link *osmo_prim_srv_get_link(struct osmo_prim_srv *prim_srv)
321 {
322 return prim_srv->link;
323 }
324
325 void osmo_prim_srv_set_priv(struct osmo_prim_srv *prim_srv, void *priv)
326 {
327 prim_srv->priv = priv;
328 }
329
330 void *osmo_prim_srv_get_priv(const struct osmo_prim_srv *prim_srv)
331 {
332 return prim_srv->priv;
333 }
334
335 void osmo_prim_srv_close(struct osmo_prim_srv *prim_srv)
336 {
337 osmo_stream_srv_destroy(prim_srv->stream);
338 /* we free prim_srv in _osmo_prim_srv_closed_cb() */
339 }
340
341 /******************************
342 * osmo_prim_srv_link
343 ******************************/
344
345 #define LOGSRVLINK(srv, lvl, fmt, args...) LOGP((srv)->log_cat, lvl, fmt, ## args)
346
347 /* accept connection coming from PCU */
348 static int _osmo_prim_srv_link_accept(struct osmo_stream_srv_link *link, int fd)
349 {
350 struct osmo_prim_srv *prim_srv;
351 struct osmo_prim_srv_link *prim_link = osmo_stream_srv_link_get_data(link);
352
353 prim_srv = osmo_prim_srv_alloc(prim_link, fd);
354
355 if (prim_link->opened_conn_cb)
356 return prim_link->opened_conn_cb(prim_srv);
357
358 return 0;
359 }
360
361 struct osmo_prim_srv_link *osmo_prim_srv_link_alloc(void *ctx)
362 {
363 struct osmo_prim_srv_link *prim_link;
364 prim_link = talloc_zero(ctx, struct osmo_prim_srv_link);
365 if (!prim_link)
366 return NULL;
367 prim_link->stream = osmo_stream_srv_link_create(prim_link);
368 if (!prim_link->stream) {
369 talloc_free(prim_link);
370 return NULL;
371 }
372 osmo_stream_srv_link_set_data(prim_link->stream, prim_link);
373 osmo_stream_srv_link_set_domain(prim_link->stream, AF_UNIX);
374 osmo_stream_srv_link_set_type(prim_link->stream, SOCK_SEQPACKET);
375 osmo_stream_srv_link_set_accept_cb(prim_link->stream, _osmo_prim_srv_link_accept);
376
377 prim_link->log_cat = DLGLOBAL;
378 prim_link->rx_msgb_alloc_len = 1600 - sizeof(struct osmo_prim_pkt_hdr);
379 return prim_link;
380 }
381
382 void osmo_prim_srv_link_free(struct osmo_prim_srv_link *prim_link)
383 {
384 if (!prim_link)
385 return;
386
387 if (prim_link->stream) {
388 osmo_stream_srv_link_close(prim_link->stream);
389 osmo_stream_srv_link_destroy(prim_link->stream);
390 prim_link->stream = NULL;
391 }
392 talloc_free(prim_link);
393 }
394
395 int osmo_prim_srv_link_set_addr(struct osmo_prim_srv_link *prim_link, const char *path)
396 {
397 osmo_talloc_replace_string(prim_link, &prim_link->addr, path);
398 osmo_stream_srv_link_set_addr(prim_link->stream, path);
399 return 0;
400 }
401
402 const char *osmo_prim_srv_link_get_addr(struct osmo_prim_srv_link *prim_link)
403 {
404 return prim_link->addr;
405 }
406
407 void osmo_prim_srv_link_set_priv(struct osmo_prim_srv_link *prim_link, void *priv)
408 {
409 prim_link->priv = priv;
410 }
411
412 void *osmo_prim_srv_link_get_priv(const struct osmo_prim_srv_link *prim_link)
413 {
414 return prim_link->priv;
415 }
416
417 void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat)
418 {
419 prim_link->log_cat = log_cat;
420 }
421
422 void osmo_prim_srv_link_set_opened_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb opened_conn_cb)
423 {
424 prim_link->opened_conn_cb = opened_conn_cb;
425 }
426 void osmo_prim_srv_link_set_closed_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb closed_conn_cb)
427 {
428 prim_link->closed_conn_cb = closed_conn_cb;
429 }
430
431 void osmo_prim_srv_link_set_rx_sapi_version_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_sapi_version rx_sapi_version_cb)
432 {
433 prim_link->rx_sapi_version_cb = rx_sapi_version_cb;
434 }
435
436 void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb)
437 {
438 prim_link->rx_cb = rx_cb;
439 }
440
441 void osmo_prim_srv_link_set_rx_msgb_alloc_len(struct osmo_prim_srv_link *prim_link, size_t alloc_len)
442 {
443 prim_link->rx_msgb_alloc_len = alloc_len;
444 }
445
446 int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link)
447 {
448 int rc;
449
450 if (!prim_link->addr) {
451 LOGSRVLINK(prim_link, LOGL_ERROR, "Cannot open, Address not configured\n");
452 return -1;
453 }
454
455 rc = osmo_stream_srv_link_open(prim_link->stream);
456
457 LOGSRVLINK(prim_link, LOGL_INFO, "Started listening on Lower Layer Unix Domain Socket: %s\n", prim_link->addr);
458
459 return rc;
460 }
0 #include <netinet/sctp.h>
1 #include <osmocom/netif/sctp.h>
2
3 const struct value_string osmo_sctp_assoc_chg_strs[] = {
4 { SCTP_COMM_UP, "COMM_UP" },
5 { SCTP_COMM_LOST, "COMM_LOST" },
6 { SCTP_RESTART, "RESTART" },
7 { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" },
8 { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" },
9 { 0, NULL }
10 };
11
12 const struct value_string osmo_sctp_sn_type_strs[] = {
13 { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" },
14 { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" },
15 { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" },
16 { SCTP_SEND_FAILED, "SEND_FAILED" },
17 { SCTP_REMOTE_ERROR, "REMOTE_ERROR" },
18 { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" },
19 { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" },
20 #ifdef SCTP_AUTHENTICATION_INDICATION
21 { SCTP_AUTHENTICATION_INDICATION, "AUTHENTICATION_INDICATION" },
22 #endif
23 #ifdef SCTP_SENDER_DRY_EVENT
24 { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" },
25 #endif
26 { 0, NULL }
27 };
255255 char *local_addr[OSMO_STREAM_MAX_ADDRS];
256256 uint8_t local_addrcnt;
257257 uint16_t local_port;
258 int sk_domain;
259 int sk_type;
258260 uint16_t proto;
259261 int (*connect_cb)(struct osmo_stream_cli *srv);
260262 int (*disconnect_cb)(struct osmo_stream_cli *srv);
348350
349351 LOGSCLI(cli, LOGL_DEBUG, "sending %u bytes of data\n", msgb_length(msg));
350352
351 switch (cli->proto) {
353 switch (cli->sk_domain) {
354 case AF_UNIX:
355 ret = send(cli->ofd.fd, msg->data, msg->len, 0);
356 break;
357 case AF_UNSPEC:
358 case AF_INET:
359 case AF_INET6:
360 switch (cli->proto) {
352361 #ifdef HAVE_LIBSCTP
353 case IPPROTO_SCTP:
354 memset(&sinfo, 0, sizeof(sinfo));
355 sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
356 sinfo.sinfo_stream = msgb_sctp_stream(msg);
357 ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg),
358 &sinfo, MSG_NOSIGNAL);
359 break;
362 case IPPROTO_SCTP:
363 memset(&sinfo, 0, sizeof(sinfo));
364 sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
365 sinfo.sinfo_stream = msgb_sctp_stream(msg);
366 ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg),
367 &sinfo, MSG_NOSIGNAL);
368 break;
360369 #endif
361 case IPPROTO_TCP:
370 case IPPROTO_TCP:
371 default:
372 ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0);
373 break;
374 }
375 break;
362376 default:
363 ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0);
364 break;
377 ret = -ENOTSUP;
365378 }
366379 if (ret < 0) {
367380 if (errno == EPIPE || errno == ENOTCONN) {
371384 }
372385 msgb_free(msg);
373386 return 0;
387 }
388
389 static int _setsockopt_nosigpipe(struct osmo_stream_cli *cli)
390 {
391 #ifdef SO_NOSIGPIPE
392 int ret;
393 int val = 1;
394 ret = setsockopt(cli->ofd.fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&val, sizeof(val));
395 if (ret < 0)
396 LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno));
397 return ret;
398 #else
399 return 0;
400 #endif
374401 }
375402
376403 static int osmo_stream_cli_fd_cb(struct osmo_fd *ofd, unsigned int what)
394421
395422 LOGSCLI(cli, LOGL_DEBUG, "connection done.\n");
396423 cli->state = STREAM_CLI_STATE_CONNECTED;
397 if (cli->proto == IPPROTO_SCTP) {
398 #ifdef SO_NOSIGPIPE
399 int val = 1;
400
401 ret = setsockopt(ofd->fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val));
402 if (ret < 0)
403 LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno));
404 #endif
405 sctp_sock_activate_events(ofd->fd);
424 switch (cli->sk_domain) {
425 case AF_UNIX:
426 _setsockopt_nosigpipe(cli);
427 break;
428 case AF_UNSPEC:
429 case AF_INET:
430 case AF_INET6:
431 if (cli->proto == IPPROTO_SCTP) {
432 _setsockopt_nosigpipe(cli);
433 sctp_sock_activate_events(ofd->fd);
434 }
435 break;
436 default:
437 break;
406438 }
407439 if (cli->connect_cb)
408440 cli->connect_cb(cli);
440472 if (!cli)
441473 return NULL;
442474
475 cli->sk_domain = AF_UNSPEC;
476 cli->sk_type = SOCK_STREAM;
443477 cli->proto = IPPROTO_TCP;
444478 cli->ofd.fd = -1;
445479 cli->ofd.priv_nr = 0; /* XXX */
556590 cli->flags |= OSMO_STREAM_CLI_F_RECONF;
557591 }
558592
593 /*! \brief Set the socket type for the stream server link
594 * \param[in] cli Stream Client to modify
595 * \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...)
596 * \returns zero on success, negative on error.
597 */
598 int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type)
599 {
600 switch (type) {
601 case SOCK_STREAM:
602 case SOCK_SEQPACKET:
603 break;
604 default:
605 return -ENOTSUP;
606 }
607 cli->sk_type = type;
608 cli->flags |= OSMO_STREAM_CLI_F_RECONF;
609 return 0;
610 }
611
612 /*! \brief Set the socket type for the stream server link
613 * \param[in] cli Stream Client to modify
614 * \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...)
615 * \returns zero on success, negative on error.
616 */
617 int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain)
618 {
619 switch (domain) {
620 case AF_UNSPEC:
621 case AF_INET:
622 case AF_INET6:
623 case AF_UNIX:
624 break;
625 default:
626 return -ENOTSUP;
627 }
628 cli->sk_domain = domain;
629 cli->flags |= OSMO_STREAM_CLI_F_RECONF;
630 return 0;
631 }
632
559633 /*! \brief Set the reconnect time of the stream client socket
560634 * \param[in] cli Stream Client to modify
561635 * \param[in] timeout Re-connect timeout in seconds or negative value to disable auto-reconnection */
730804
731805 cli->flags &= ~OSMO_STREAM_CLI_F_RECONF;
732806
733
734 switch (cli->proto) {
807 switch (cli->sk_domain) {
808 case AF_UNIX:
809 ret = osmo_sock_unix_init(cli->sk_type, 0, cli->addr[0], OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
810 break;
811 case AF_INET:
812 case AF_INET6:
813 case AF_UNSPEC:
814 switch (cli->proto) {
735815 #ifdef HAVE_LIBSCTP
736 case IPPROTO_SCTP:
737 ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, cli->proto,
738 (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port,
739 (const char **)cli->addr, cli->addrcnt, cli->port,
740 OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
741 break;
816 case IPPROTO_SCTP:
817 ret = osmo_sock_init2_multiaddr(cli->sk_domain, cli->sk_type, cli->proto,
818 (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port,
819 (const char **)cli->addr, cli->addrcnt, cli->port,
820 OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
821 break;
742822 #endif
823 default:
824 ret = osmo_sock_init2(cli->sk_domain, cli->sk_type, cli->proto,
825 cli->local_addr[0], cli->local_port,
826 cli->addr[0], cli->port,
827 OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
828 }
829 break;
743830 default:
744 ret = osmo_sock_init2(AF_UNSPEC, SOCK_STREAM, cli->proto,
745 cli->local_addr[0], cli->local_port,
746 cli->addr[0], cli->port,
747 OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
831 return -ENOTSUP;
748832 }
749833
750834 if (ret < 0) {
826910 char *addr[OSMO_STREAM_MAX_ADDRS];
827911 uint8_t addrcnt;
828912 uint16_t port;
913 int sk_domain;
914 int sk_type;
829915 uint16_t proto;
830916 int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd);
831917 void *data;
837923 int ret;
838924 int sock_fd;
839925 char addrstr[128];
840 bool is_ipv6;
926 bool is_ipv6 = false;
841927 struct sockaddr_storage sa;
842928 socklen_t sa_len = sizeof(sa);
843929 struct osmo_stream_srv_link *link = ofd->data;
848934 "peer, reason=`%s'\n", strerror(errno));
849935 return ret;
850936 }
851 is_ipv6 = ((struct sockaddr *)&sa)->sa_family == AF_INET6;
852 LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n",
853 inet_ntop(is_ipv6 ? AF_INET6 : AF_INET,
854 is_ipv6 ? (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr) :
855 (void*)&(((struct sockaddr_in *)&sa)->sin_addr),
856 addrstr, sizeof(addrstr)),
857 link->port);
858937 sock_fd = ret;
859938
860 if (link->proto == IPPROTO_SCTP) {
861 ret = sctp_sock_activate_events(sock_fd);
862 if (ret < 0)
863 goto error_close_socket;
939 is_ipv6 = false;
940 switch (((struct sockaddr *)&sa)->sa_family) {
941 case AF_UNIX:
942 LOGP(DLINP, LOGL_DEBUG, "accept()ed new link on fd %d\n",
943 sock_fd);
944 break;
945 case AF_INET6:
946 is_ipv6 = true;
947 /* fall through */
948 case AF_INET:
949 LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n",
950 inet_ntop(is_ipv6 ? AF_INET6 : AF_INET,
951 is_ipv6 ? (void *)&(((struct sockaddr_in6 *)&sa)->sin6_addr) :
952 (void *)&(((struct sockaddr_in *)&sa)->sin_addr),
953 addrstr, sizeof(addrstr)),
954 link->port);
955
956 if (link->proto == IPPROTO_SCTP) {
957 ret = sctp_sock_activate_events(sock_fd);
958 if (ret < 0)
959 goto error_close_socket;
960 }
961 break;
962 default:
963 LOGP(DLINP, LOGL_DEBUG, "accept()ed unexpected address family %d\n",
964 ((struct sockaddr *)&sa)->sa_family);
965 goto error_close_socket;
864966 }
865967
866968 if (link->flags & OSMO_STREAM_SRV_F_NODELAY) {
8981000 if (!link)
8991001 return NULL;
9001002
1003 link->sk_domain = AF_UNSPEC;
1004 link->sk_type = SOCK_STREAM;
9011005 link->proto = IPPROTO_TCP;
9021006 osmo_fd_setup(&link->ofd, -1, OSMO_FD_READ | OSMO_FD_WRITE, osmo_stream_srv_fd_cb, link, 0);
9031007
9771081 link->flags |= OSMO_STREAM_SRV_F_RECONF;
9781082 }
9791083
1084
1085 /*! \brief Set the socket type for the stream server link
1086 * \param[in] link Stream Server Link to modify
1087 * \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...)
1088 * \returns zero on success, negative on error.
1089 */
1090 int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type)
1091 {
1092 switch (type) {
1093 case SOCK_STREAM:
1094 case SOCK_SEQPACKET:
1095 break;
1096 default:
1097 return -ENOTSUP;
1098 }
1099 link->sk_type = type;
1100 link->flags |= OSMO_STREAM_SRV_F_RECONF;
1101 return 0;
1102 }
1103
1104 /*! \brief Set the socket type for the stream server link
1105 * \param[in] link Stream Server Link to modify
1106 * \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...)
1107 * \returns zero on success, negative on error.
1108 */
1109 int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain)
1110 {
1111 switch (domain) {
1112 case AF_UNSPEC:
1113 case AF_INET:
1114 case AF_INET6:
1115 case AF_UNIX:
1116 break;
1117 default:
1118 return -ENOTSUP;
1119 }
1120 link->sk_domain = domain;
1121 link->flags |= OSMO_STREAM_SRV_F_RECONF;
1122 return 0;
1123 }
1124
9801125 /*! \brief Set application private data of the stream server link
9811126 * \param[in] link Stream Server Link to modify
9821127 * \param[in] data User-specific data (available in call-back functions) */
10591204
10601205 link->flags &= ~OSMO_STREAM_SRV_F_RECONF;
10611206
1062 switch (link->proto) {
1207 switch (link->sk_domain) {
1208 case AF_UNIX:
1209 ret = osmo_sock_unix_init(link->sk_type, 0, link->addr[0], OSMO_SOCK_F_BIND);
1210 break;
1211 case AF_UNSPEC:
1212 case AF_INET:
1213 case AF_INET6:
1214 switch (link->proto) {
10631215 #ifdef HAVE_LIBSCTP
1064 case IPPROTO_SCTP:
1065 ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, link->proto,
1066 (const char **)link->addr, link->addrcnt, link->port,
1067 NULL, 0, 0, OSMO_SOCK_F_BIND);
1068 break;
1216 case IPPROTO_SCTP:
1217 ret = osmo_sock_init2_multiaddr(link->sk_domain, link->sk_type, link->proto,
1218 (const char **)link->addr, link->addrcnt, link->port,
1219 NULL, 0, 0, OSMO_SOCK_F_BIND);
1220 break;
10691221 #endif
1222 default:
1223 ret = osmo_sock_init(link->sk_domain, link->sk_type, link->proto,
1224 link->addr[0], link->port, OSMO_SOCK_F_BIND);
1225 }
1226 break;
10701227 default:
1071 ret = osmo_sock_init(AF_UNSPEC, SOCK_STREAM, link->proto,
1072 link->addr[0], link->port, OSMO_SOCK_F_BIND);
1228 ret = -ENOTSUP;
10731229 }
10741230 if (ret < 0)
10751231 return ret;
11431299 llist_del(lh);
11441300 msg = llist_entry(lh, struct msgb, list);
11451301
1146 switch (conn->srv->proto) {
1302 switch (conn->srv->sk_domain) {
1303 case AF_UNIX:
1304 ret = send(conn->ofd.fd, msg->data, msg->len, 0);
1305 break;
1306 case AF_INET:
1307 case AF_INET6:
1308 case AF_UNSPEC:
1309 switch (conn->srv->proto) {
11471310 #ifdef HAVE_LIBSCTP
1148 case IPPROTO_SCTP:
1149 memset(&sinfo, 0, sizeof(sinfo));
1150 sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
1151 sinfo.sinfo_stream = msgb_sctp_stream(msg);
1152 ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg),
1153 &sinfo, MSG_NOSIGNAL);
1154 break;
1311 case IPPROTO_SCTP:
1312 memset(&sinfo, 0, sizeof(sinfo));
1313 sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
1314 sinfo.sinfo_stream = msgb_sctp_stream(msg);
1315 ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg),
1316 &sinfo, MSG_NOSIGNAL);
1317 break;
11551318 #endif
1156 case IPPROTO_TCP:
1319 case IPPROTO_TCP:
1320 default:
1321 ret = send(conn->ofd.fd, msg->data, msg->len, 0);
1322 break;
1323 }
1324 break;
11571325 default:
1158 ret = send(conn->ofd.fd, msg->data, msg->len, 0);
1159 break;
1326 ret = -ENOTSUP;
11601327 }
11611328 if (ret < 0) {
11621329 LOGP(DLINP, LOGL_ERROR, "error to send\n");
12891456 osmo_fd_write_enable(&conn->ofd);
12901457 }
12911458
1459 #ifdef HAVE_LIBSCTP
1460 static int _sctp_recvmsg_wrapper(int fd, struct msgb *msg)
1461 {
1462 struct sctp_sndrcvinfo sinfo;
1463 int flags = 0;
1464 int ret;
1465
1466 ret = sctp_recvmsg(fd, msgb_data(msg), msgb_tailroom(msg),
1467 NULL, NULL, &sinfo, &flags);
1468 if (flags & MSG_NOTIFICATION) {
1469 union sctp_notification *notif = (union sctp_notification *)msgb_data(msg);
1470 LOGP(DLINP, LOGL_DEBUG, "NOTIFICATION %u flags=0x%x\n", notif->sn_header.sn_type, notif->sn_header.sn_flags);
1471 switch (notif->sn_header.sn_type) {
1472 case SCTP_ASSOC_CHANGE:
1473 LOGP(DLINP, LOGL_DEBUG, "===> ASSOC CHANGE:");
1474 switch (notif->sn_assoc_change.sac_state) {
1475 case SCTP_COMM_UP:
1476 LOGPC(DLINP, LOGL_DEBUG, " UP\n");
1477 break;
1478 case SCTP_COMM_LOST:
1479 LOGPC(DLINP, LOGL_DEBUG, " LOST\n");
1480 break;
1481 case SCTP_RESTART:
1482 LOGPC(DLINP, LOGL_DEBUG, " RESTART\n");
1483 break;
1484 case SCTP_SHUTDOWN_COMP:
1485 LOGPC(DLINP, LOGL_DEBUG, " SHUTDOWN COMP\n");
1486 break;
1487 case SCTP_CANT_STR_ASSOC:
1488 LOGPC(DLINP, LOGL_DEBUG, " CANT STR ASSOC\n");
1489 break;
1490 }
1491 break;
1492 case SCTP_PEER_ADDR_CHANGE:
1493 LOGP(DLINP, LOGL_DEBUG, "===> PEER ADDR CHANGE\n");
1494 break;
1495 case SCTP_SHUTDOWN_EVENT:
1496 LOGP(DLINP, LOGL_DEBUG, "===> SHUTDOWN EVT\n");
1497 /* Handle this like a regular disconnect */
1498 return 0;
1499 break;
1500 }
1501 return -EAGAIN;
1502 }
1503 msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid);
1504 msgb_sctp_stream(msg) = sinfo.sinfo_stream;
1505 return ret;
1506 }
1507 #endif
1508
12921509 /*! \brief Receive data via Osmocom stream server
12931510 * \param[in] conn Stream Server from which to receive
12941511 * \param msg pre-allocate message buffer to which received data is appended
12961513 */
12971514 int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg)
12981515 {
1299 #ifdef HAVE_LIBSCTP
1300 struct sctp_sndrcvinfo sinfo;
1301 int flags = 0;
1302 #endif
13031516 int ret;
13041517
13051518 if (!msg)
13061519 return -EINVAL;
13071520
1308 switch (conn->srv->proto) {
1521 switch (conn->srv->sk_domain) {
1522 case AF_UNIX:
1523 ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0);
1524 break;
1525 case AF_INET:
1526 case AF_INET6:
1527 case AF_UNSPEC:
1528 switch (conn->srv->proto) {
13091529 #ifdef HAVE_LIBSCTP
1310 case IPPROTO_SCTP:
1311 ret = sctp_recvmsg(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg),
1312 NULL, NULL, &sinfo, &flags);
1313 if (flags & MSG_NOTIFICATION) {
1314 union sctp_notification *notif = (union sctp_notification *) msgb_data(msg);
1315 LOGP(DLINP, LOGL_DEBUG, "NOTIFICATION %u flags=0x%x\n", notif->sn_header.sn_type, notif->sn_header.sn_flags);
1316 switch (notif->sn_header.sn_type) {
1317 case SCTP_ASSOC_CHANGE:
1318 LOGP(DLINP, LOGL_DEBUG, "===> ASSOC CHANGE:");
1319 switch (notif->sn_assoc_change.sac_state) {
1320 case SCTP_COMM_UP:
1321 LOGPC(DLINP, LOGL_DEBUG, " UP\n");
1322 break;
1323 case SCTP_COMM_LOST:
1324 LOGPC(DLINP, LOGL_DEBUG, " LOST\n");
1325 break;
1326 case SCTP_RESTART:
1327 LOGPC(DLINP, LOGL_DEBUG, " RESTART\n");
1328 break;
1329 case SCTP_SHUTDOWN_COMP:
1330 LOGPC(DLINP, LOGL_DEBUG, " SHUTDOWN COMP\n");
1331 break;
1332 case SCTP_CANT_STR_ASSOC:
1333 LOGPC(DLINP, LOGL_DEBUG, " CANT STR ASSOC\n");
1334 break;
1335 }
1336 break;
1337 case SCTP_PEER_ADDR_CHANGE:
1338 LOGP(DLINP, LOGL_DEBUG, "===> PEER ADDR CHANGE\n");
1339 break;
1340 case SCTP_SHUTDOWN_EVENT:
1341 LOGP(DLINP, LOGL_DEBUG, "===> SHUTDOWN EVT\n");
1342 /* Handle this like a regular disconnect */
1343 return 0;
1344 break;
1345 }
1346 return -EAGAIN;
1530 case IPPROTO_SCTP:
1531 ret = _sctp_recvmsg_wrapper(conn->ofd.fd, msg);
1532 break;
1533 #endif
1534 case IPPROTO_TCP:
1535 default:
1536 ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0);
1537 break;
13471538 }
1348 msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid);
1349 msgb_sctp_stream(msg) = sinfo.sinfo_stream;
1350 break;
1351 #endif
1352 case IPPROTO_TCP:
1539 break;
13531540 default:
1354 ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0);
1355 break;
1541 ret = -ENOTSUP;
13561542 }
13571543
13581544 if (ret < 0) {
2828 "703c22f979890338540179209572624a0f8535871c2f7039cbf926b7e4425b6ef0",
2929 "703c2e671f3b1b0810412d5adae61e2b2a319885c6ced4e909b4eeaa2ea0f0cd80",
3030 "703cf8fc77356c948141686cda34d35220db719e36a359d86b64420dc64b563850",
31 "703c3eec9c37dfb201c093c57a1235a02af55ccc22f1c9593a6e058c368b4d7f50",
3132 "60344e300c0e6251342c2ae51fd8a698a945488d16c98922726f3e50",
3233 "60341fc722c7880328a9c280030bc9755c3ef519f80000295323e000",
3334 "60342c338655c00008efba03592419adf62478a79278b3e2d68ab0f0",
4647 "0004f89d67f1160935bde1996840",
4748 "0004633cc7f0630439ffe0000000",
4849 "0004eb81fc0758973b9edc782550",
49 "a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc", /* sample with invalid FT */
50 "a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc", /* sample with invalid FT, will be detected as bandwith-efficient */
5051 "END",
5152 };
5253
5455 char *bwe_amr_samples[] = {
5556 "f4495c7cda8f80",
5657 "f44aaa6c969780",
58 "7449c1e32c6780",
59 "74400000000380",
60 "703c493323b0bf68028086d15a00",
61 "703c59171697c53c01801fb6aa80",
62 "703c55029bb2e23a0020172e8b00",
63 "703c48f52442f08884a8050b8500",
64 "7038000000000000000000000000",
65 "7151434e01292c40c4735e4412204077",
66 "714eadbe13ac4694f4726f71985d64cd",
5767 "f3d09c20e32da600c025a72e0a9b360386e40f87e19282094adc1a11e397d1d4",
5868 "f3d39a49a09e7a802852e297e8c9246aadf5a45928bfc27177fed8404d97d3b8",
5969 "f3c2155b65131c68682079fab4810911200003b360ae0446000025f11e539dd0",
6070 "f3c381bc7061c9f8507f6029de6115c16e5fa470c243b21b6e35dbb48bd84c00",
71 "73c901b7a2004be7f85284b6ab7142acfe6872b1ae1c107d0588b551de7be650",
6172 "a7bfc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03f", /* sample with invalid FT */
6273 "END",
6374 };
75
76 /* Some IuUP payload containg AMR */
77 char *iuup_amr_samples[] = {
78 "7a687b8b29ba02013d3cb863a5af4206869618fb5336d504968d7541663210",
79 "4482803977dc1880b56aab097728a6bbbb48a57e3affe41125838a5ce65fc0",
80 "2683c1d26e",
81 "END",
82 };
83
6484
6585 void dump_bits(uint8_t *buf, int len)
6686 {
184204 }
185205 }
186206
207 void osmo_amr_iuup_to_bwe_and_inverse_test(void)
208 {
209 uint8_t buf[256];
210 uint8_t buf_chk[256];
211 unsigned int ft;
212
213 unsigned int i = 0;
214 int len;
215 int rc;
216
217 printf("\n\n");
218 printf
219 ("Testing conversion from IuUP to bw-efficient and inverse:\n");
220
221 while (1) {
222 if (strcmp(iuup_amr_samples[i], "END") == 0)
223 return;
224 printf("Sample No.: %d...", i);
225
226 len = osmo_hexparse(iuup_amr_samples[i], buf, sizeof(buf));
227 OSMO_ASSERT(len > 0);
228 i++;
229
230 ft = osmo_amr_bytes_to_ft(len);
231 if (ft < 0) {
232 printf(" skipping a sample with a wrong FT\n");
233 continue;
234 }
235 printf(" AMR mode: %d, IuUP: %d bytes,", ft, len);
236 memcpy(buf_chk, buf, sizeof(buf));
237
238 rc = osmo_amr_iuup_to_bwe(buf, len, sizeof(buf));
239 OSMO_ASSERT(rc > 0);
240 OSMO_ASSERT((rc == len + 1) || (rc == len + 2));
241 printf(" BE: %d bytes (%s),", rc, osmo_hexdump(buf, rc));
242
243 buf[0] = (ft >> 1) & 0x07;
244 buf[1] = ((ft & 0x01) << 7) | (buf[1] & 0x3f);
245 rc = osmo_amr_bwe_to_iuup(buf, rc);
246 printf(" IuUP: %d bytes\n", rc);
247 OSMO_ASSERT(rc > 0);
248 OSMO_ASSERT(len == rc);
249 if (memcmp(buf, buf_chk, len) != 0) {
250 printf("Got: %s\n", osmo_hexdump(buf, len));
251 printf("Expected:%s\n", osmo_hexdump(buf_chk, len));
252 }
253 OSMO_ASSERT(memcmp(buf, buf_chk, len) == 0);
254 }
255 }
256
187257 void osmo_amr_is_oa_test(void)
188258 {
189259 uint8_t buf[256];
238308 osmo_amr_oa_to_bwe_test();
239309 osmo_amr_bwe_to_oa_test();
240310 osmo_amr_oa_to_bwe_and_inverse_test();
311 osmo_amr_iuup_to_bwe_and_inverse_test();
241312 osmo_amr_is_oa_test();
242313
243314 fprintf(stdout, "OK: Test passed\n");
2323 rc: 32
2424
2525 Sample No.: 3
26 octet aligned: 703c3eec9c37dfb201c093c57a1235a02af55ccc22f1c9593a6e058c368b4d7f50
27 011100000011110000111110111011001001110000110111110111111011001000000001110000001001001111000101011110100001001000110101101000000010101011110101010111001100110000100010111100011100100101011001001110100110111000000101100011000011011010001011010011010111111101010000
28 bw-efficient: 73cfbb270df7ec807024f15e848d680abd573308bc72564e9b81630da2d35fd4
29 0111001111001111101110110010011100001101111101111110110010000000011100000010010011110001010111101000010010001101011010000000101010111101010101110011001100001000101111000111001001010110010011101001101110000001011000110000110110100010110100110101111111010100
30 rc: 32
31
32 Sample No.: 4
2633 octet aligned: 60344e300c0e6251342c2ae51fd8a698a945488d16c98922726f3e50
2734 01100000001101000100111000110000000011000000111001100010010100010011010000101100001010101110010100011111110110001010011010011000101010010100010101001000100011010001011011001001100010010010001001110010011011110011111001010000
2835 bw-efficient: 63538c030398944d0b0ab947f629a62a51522345b262489c9bcf94
2936 011000110101001110001100000000110000001110011000100101000100110100001011000010101011100101000111111101100010100110100110001010100101000101010010001000110100010110110010011000100100100010011100100110111100111110010100
3037 rc: 27
3138
32 Sample No.: 4
39 Sample No.: 5
3340 octet aligned: 60341fc722c7880328a9c280030bc9755c3ef519f80000295323e000
3441 01100000001101000001111111000111001000101100011110001000000000110010100010101001110000101000000000000011000010111100100101110101010111000011111011110101000110011111100000000000000000000010100101010011001000111110000000000000
3542 bw-efficient: 6347f1c8b1e200ca2a70a000c2f25d570fbd467e00000a54c8f800
3643 011000110100011111110001110010001011000111100010000000001100101000101010011100001010000000000000110000101111001001011101010101110000111110111101010001100111111000000000000000000000101001010100110010001111100000000000
3744 rc: 27
3845
39 Sample No.: 5
46 Sample No.: 6
4047 octet aligned: 60342c338655c00008efba03592419adf62478a79278b3e2d68ab0f0
4148 01100000001101000010110000110011100001100101010111000000000000000000100011101111101110100000001101011001001001000001100110101101111101100010010001111000101001111001001001111000101100111110001011010110100010101011000011110000
4249 bw-efficient: 634b0ce1957000023bee80d649066b7d891e29e49e2cf8b5a2ac3c
4350 011000110100101100001100111000011001010101110000000000000000001000111011111011101000000011010110010010010000011001101011011111011000100100011110001010011110010010011110001011001111100010110101101000101010110000111100
4451 rc: 27
4552
46 Sample No.: 6
53 Sample No.: 7
4754 octet aligned: 502c98ab841e491ff7a1a555016a32a3c7f913210630
4855 01010000001011001001100010101011100001000001111001001001000111111111011110100001101001010101010100000001011010100011001010100011110001111111100100010011001000010000011000110000
4956 bw-efficient: 52e62ae1079247fde86955405a8ca8f1fe44c8418c00
5057 01010010111001100010101011100001000001111001001001000111111111011110100001101001010101010100000001011010100011001010100011110001111111100100010011001000010000011000110000000000
5158 rc: 22
5259
53 Sample No.: 7
60 Sample No.: 8
5461 octet aligned: 502cc5459a0d200e7097c4dfe86ec8d27f1756d776f0
5562 01010000001011001100010101000101100110100000110100100000000011100111000010010111110001001101111111101000011011101100100011010010011111110001011101010110110101110111011011110000
5663 bw-efficient: 52f151668348039c25f137fa1bb2349fc5d5b5ddbc00
5764 01010010111100010101000101100110100000110100100000000011100111000010010111110001001101111111101000011011101100100011010010011111110001011101010110110101110111011011110000000000
5865 rc: 22
5966
60 Sample No.: 8
67 Sample No.: 9
6168 octet aligned: 502c42b332081813d7e916e7aa5e80d7fde812b8c080
6269 01010000001011000100001010110011001100100000100000011000000100111101011111101001000101101110011110101010010111101000000011010111111111011110100000010010101110001100000010000000
6370 bw-efficient: 52d0accc820604f5fa45b9ea97a035ff7a04ae302000
6471 01010010110100001010110011001100100000100000011000000100111101011111101001000101101110011110101010010111101000000011010111111111011110100000010010101110001100000010000000000000
6572 rc: 22
6673
67 Sample No.: 9
74 Sample No.: 10
6875 octet aligned: 40240343e959c79bacd20c77501054880a718db200
6976 010000000010010000000011010000111110100101011001110001111001101110101100110100100000110001110111010100000001000001010100100010000000101001110001100011011011001000000000
7077 bw-efficient: 4240d0fa5671e6eb34831dd4041522029c636c80
7178 0100001001000000110100001111101001010110011100011110011011101011001101001000001100011101110101000000010000010101001000100000001010011100011000110110110010000000
7279 rc: 20
7380
74 Sample No.: 10
81 Sample No.: 11
7582 octet aligned: 4024172c53401e39115ceecd12606df5689bdd0ca0
7683 010000000010010000010111001011000101001101000000000111100011100100010001010111001110111011001101000100100110000001101101111101010110100010011011110111010000110010100000
7784 bw-efficient: 4245cb14d0078e44573bb344981b7d5a26f74328
7885 0100001001000101110010110001010011010000000001111000111001000100010101110011101110110011010001001001100000011011011111010101101000100110111101110100001100101000
7986 rc: 20
8087
81 Sample No.: 11
88 Sample No.: 12
8289 octet aligned: 4024f871cf48801ec427f0fc3f7318898622062200
8390 010000000010010011111000011100011100111101001000100000000001111011000100001001111111000011111100001111110111001100011000100010011000011000100010000001100010001000000000
8491 bw-efficient: 427e1c73d22007b109fc3f0fdcc6226188818880
8592 0100001001111110000111000111001111010010001000000000011110110001000010011111110000111111000011111101110011000110001000100110000110001000100000011000100010000000
8693 rc: 20
8794
88 Sample No.: 12
95 Sample No.: 13
8996 octet aligned: 20141fd4c02667c742b164aef659ffe708
9097 0010000000010100000111111101010011000000001001100110011111000111010000101011000101100100101011101111011001011001111111111110011100001000
9198 bw-efficient: 2147f5300999f1d0ac592bbd967ff9c2
9299 00100001010001111111010100110000000010011001100111110001110100001010110001011001001010111011110110010110011111111111100111000010
93100 rc: 16
94101
95 Sample No.: 13
102 Sample No.: 14
96103 octet aligned: 2014197e10ead7b250bccbbf3b81887c64
97104 0010000000010100000110010111111000010000111010101101011110110010010100001011110011001011101111110011101110000001100010000111110001100100
98105 bw-efficient: 21465f843ab5ec942f32efcee0621f19
99106 00100001010001100101111110000100001110101011010111101100100101000010111100110010111011111100111011100000011000100001111100011001
100107 rc: 16
101108
102 Sample No.: 14
109 Sample No.: 15
103110 octet aligned: 2014e959f35fdfe5e9667ffbc088818088
104111 0010000000010100111010010101100111110011010111111101111111100101111010010110011001111111111110111100000010001000100000011000000010001000
105112 bw-efficient: 217a567cd7f7f97a599ffef022206022
106113 00100001011110100101011001111100110101111111011111111001011110100101100110011111111111101111000000100010001000000110000000100010
107114 rc: 16
108115
109 Sample No.: 15
116 Sample No.: 16
110117 octet aligned: 100c4e9ba850e30d5d53d04de41e7c
111118 000100000000110001001110100110111010100001010000111000110000110101011101010100111101000001001101111001000001111001111100
112119 bw-efficient: 10d3a6ea1438c35754f41379079f00
113120 000100001101001110100110111010100001010000111000110000110101011101010100111101000001001101111001000001111001111100000000
114121 rc: 15
115122
116 Sample No.: 16
123 Sample No.: 17
117124 octet aligned: 100c6c18e7b7fff53aeb055e7d1c54
118125 000100000000110001101100000110001110011110110111111111111111010100111010111010110000010101011110011111010001110001010100
119126 bw-efficient: 10db0639edfffd4ebac1579f471500
120127 000100001101101100000110001110011110110111111111111111010100111010111010110000010101011110011111010001110001010100000000
121128 rc: 15
122129
123 Sample No.: 17
130 Sample No.: 18
124131 octet aligned: 100c1fb967f7f1fdf547bf2e61c060
125132 000100000000110000011111101110010110011111110111111100011111110111110101010001111011111100101110011000011100000001100000
126133 bw-efficient: 10c7ee59fdfc7f7d51efcb98701800
127134 000100001100011111101110010110011111110111111100011111110111110101010001111011111100101110011000011100000001100000000000
128135 rc: 15
129136
130 Sample No.: 18
137 Sample No.: 19
131138 octet aligned: 0004f89d67f1160935bde1996840
132139 0000000000000100111110001001110101100111111100010001011000001001001101011011110111100001100110010110100001000000
133140 bw-efficient: 007e2759fc45824d6f78665a1000
134141 0000000001111110001001110101100111111100010001011000001001001101011011110111100001100110010110100001000000000000
135142 rc: 14
136143
137 Sample No.: 19
144 Sample No.: 20
138145 octet aligned: 0004633cc7f0630439ffe0000000
139146 0000000000000100011000110011110011000111111100000110001100000100001110011111111111100000000000000000000000000000
140147 bw-efficient: 0058cf31fc18c10e7ff800000000
141148 0000000001011000110011110011000111111100000110001100000100001110011111111111100000000000000000000000000000000000
142149 rc: 14
143150
144 Sample No.: 20
151 Sample No.: 21
145152 octet aligned: 0004eb81fc0758973b9edc782550
146153 0000000000000100111010111000000111111100000001110101100010010111001110111001111011011100011110000010010101010000
147154 bw-efficient: 007ae07f01d625cee7b71e095400
148155 0000000001111010111000000111111100000001110101100010010111001110111001111011011100011110000010010101010000000000
149156 rc: 14
150157
151 Sample No.: 21
158 Sample No.: 22
152159 octet aligned: a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc
153160 101000000111100011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111100
154161 bw-efficient:
173180 rc: 7
174181
175182 Sample No.: 2
183 bw-efficient: 7449c1e32c6780
184 01110100010010011100000111100011001011000110011110000000
185 octet aligned: 704427078cb19c
186 01110000010001000010011100000111100011001011000110011100
187 rc: 7
188
189 Sample No.: 3
190 bw-efficient: 74400000000380
191 01110100010000000000000000000000000000000000001110000000
192 octet aligned: 7044000000000c
193 01110000010001000000000000000000000000000000000000001100
194 rc: 7
195
196 Sample No.: 4
197 bw-efficient: 703c493323b0bf68028086d15a00
198 0111000000111100010010010011001100100011101100001011111101101000000000101000000010000110110100010101101000000000
199 octet aligned: 7000f124cc8ec2fda00a021b4568
200 0111000000000000111100010010010011001100100011101100001011111101101000000000101000000010000110110100010101101000
201 rc: 14
202
203 Sample No.: 5
204 bw-efficient: 703c59171697c53c01801fb6aa80
205 0111000000111100010110010001011100010110100101111100010100111100000000011000000000011111101101101010101010000000
206 octet aligned: 7000f1645c5a5f14f006007edaa8
207 0111000000000000111100010110010001011100010110100101111100010100111100000000011000000000011111101101101010101000
208 rc: 14
209
210 Sample No.: 6
211 bw-efficient: 703c55029bb2e23a0020172e8b00
212 0111000000111100010101010000001010011011101100101110001000111010000000000010000000010111001011101000101100000000
213 octet aligned: 7000f1540a6ecb88e800805cba2c
214 0111000000000000111100010101010000001010011011101100101110001000111010000000000010000000010111001011101000101100
215 rc: 14
216
217 Sample No.: 7
218 bw-efficient: 703c48f52442f08884a8050b8500
219 0111000000111100010010001111010100100100010000101111000010001000100001001010100000000101000010111000010100000000
220 octet aligned: 7000f123d4910bc22212a0142e14
221 0111000000000000111100010010001111010100100100010000101111000010001000100001001010100000000101000010111000010100
222 rc: 14
223
224 Sample No.: 8
225 bw-efficient: 7038000000000000000000000000
226 0111000000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
227 octet aligned: 7000e00000000000000000000000
228 0111000000000000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
229 rc: 14
230
231 Sample No.: 9
232 bw-efficient: 7151434e01292c40c4735e4412204077
233 01110001010100010100001101001110000000010010100100101100010000001100010001110011010111100100010000010010001000000100000001110111
234 octet aligned: 7014450d3804a4b10311cd7910488101dc
235 0111000000010100010001010000110100111000000001001010010010110001000000110001000111001101011110010001000001001000100000010000000111011100
236 rc: 17
237
238 Sample No.: 10
239 bw-efficient: 714eadbe13ac4694f4726f71985d64cd
240 01110001010011101010110110111110000100111010110001000110100101001111010001110010011011110111000110011000010111010110010011001101
241 octet aligned: 70143ab6f84eb11a53d1c9bdc661759334
242 0111000000010100001110101011011011111000010011101011000100011010010100111101000111001001101111011100011001100001011101011001001100110100
243 rc: 17
244
245 Sample No.: 11
176246 bw-efficient: f3d09c20e32da600c025a72e0a9b360386e40f87e19282094adc1a11e397d1d4
177247 1111001111010000100111000010000011100011001011011010011000000000110000000010010110100111001011100000101010011011001101100000001110000110111001000000111110000111111000011001001010000010000010010100101011011100000110100001000111100011100101111101000111010100
178248 octet aligned: f03c4270838cb6980300969cb82a6cd80e1b903e1f864a08252b7068478e5f4750
179249 111100000011110001000010011100001000001110001100101101101001100000000011000000001001011010011100101110000010101001101100110110000000111000011011100100000011111000011111100001100100101000001000001001010010101101110000011010000100011110001110010111110100011101010000
180250 rc: 33
181251
182 Sample No.: 3
252 Sample No.: 12
183253 bw-efficient: f3d39a49a09e7a802852e297e8c9246aadf5a45928bfc27177fed8404d97d3b8
184254 1111001111010011100110100100100110100000100111100111101010000000001010000101001011100010100101111110100011001001001001000110101010101101111101011010010001011001001010001011111111000010011100010111011111111110110110000100000001001101100101111101001110111000
185255 octet aligned: f03c4e69268279ea00a14b8a5fa32491aab7d69164a2ff09c5dffb6101365f4ee0
186256 111100000011110001001110011010010010011010000010011110011110101000000000101000010100101110001010010111111010001100100100100100011010101010110111110101101001000101100100101000101111111100001001110001011101111111111011011000010000000100110110010111110100111011100000
187257 rc: 33
188258
189 Sample No.: 4
259 Sample No.: 13
190260 bw-efficient: f3c2155b65131c68682079fab4810911200003b360ae0446000025f11e539dd0
191261 1111001111000010000101010101101101100101000100110001110001101000011010000010000001111001111110101011010010000001000010010001000100100000000000000000001110110011011000001010111000000100010001100000000000000000001001011111000100011110010100111001110111010000
192262 octet aligned: f03c08556d944c71a1a081e7ead204244480000ecd82b81118000097c4794e7740
193263 111100000011110000001000010101010110110110010100010011000111000110100001101000001000000111100111111010101101001000000100001001000100010010000000000000000000111011001101100000101011100000010001000110000000000000000000100101111100010001111001010011100111011101000000
194264 rc: 33
195265
196 Sample No.: 5
266 Sample No.: 14
197267 bw-efficient: f3c381bc7061c9f8507f6029de6115c16e5fa470c243b21b6e35dbb48bd84c00
198268 1111001111000011100000011011110001110000011000011100100111111000010100000111111101100000001010011101111001100001000101011100000101101110010111111010010001110000110000100100001110110010000110110110111000110101110110111011010010001011110110000100110000000000
199269 octet aligned: f03c0e06f1c18727e141fd80a779845705b97e91c3090ec86db8d76ed22f613000
200270 111100000011110000001110000001101111000111000001100001110010011111100001010000011111110110000000101001110111100110000100010101110000010110111001011111101001000111000011000010010000111011001000011011011011100011010111011011101101001000101111011000010011000000000000
201271 rc: 33
202272
203 Sample No.: 6
273 Sample No.: 15
274 bw-efficient: 73c901b7a2004be7f85284b6ab7142acfe6872b1ae1c107d0588b551de7be650
275 0111001111001001000000011011011110100010000000000100101111100111111110000101001010000100101101101010101101110001010000101010110011111110011010000111001010110001101011100001110000010000011111010000010110001000101101010101000111011110011110111110011001010000
276 octet aligned: 703c2406de88012f9fe14a12daadc50ab3f9a1cac6b87041f41622d54779ef9940
277 011100000011110000100100000001101101111010001000000000010010111110011111111000010100101000010010110110101010110111000101000010101011001111111001101000011100101011000110101110000111000001000001111101000001011000100010110101010100011101111001111011111001100101000000
278 rc: 33
279
280 Sample No.: 16
204281 bw-efficient: a7bfc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03f
205282 1010011110111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111
206283 octet aligned:
212289 Sample No.: 0... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes
213290 Sample No.: 1... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes
214291 Sample No.: 2... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes
215 Sample No.: 3... AMR mode: 6, OA: 28 bytes, BE: 27 bytes, OA: 28 bytes
292 Sample No.: 3... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes
216293 Sample No.: 4... AMR mode: 6, OA: 28 bytes, BE: 27 bytes, OA: 28 bytes
217294 Sample No.: 5... AMR mode: 6, OA: 28 bytes, BE: 27 bytes, OA: 28 bytes
218 Sample No.: 6... AMR mode: 5, OA: 22 bytes, BE: 22 bytes, OA: 22 bytes
295 Sample No.: 6... AMR mode: 6, OA: 28 bytes, BE: 27 bytes, OA: 28 bytes
219296 Sample No.: 7... AMR mode: 5, OA: 22 bytes, BE: 22 bytes, OA: 22 bytes
220297 Sample No.: 8... AMR mode: 5, OA: 22 bytes, BE: 22 bytes, OA: 22 bytes
221 Sample No.: 9... AMR mode: 4, OA: 21 bytes, BE: 20 bytes, OA: 21 bytes
298 Sample No.: 9... AMR mode: 5, OA: 22 bytes, BE: 22 bytes, OA: 22 bytes
222299 Sample No.: 10... AMR mode: 4, OA: 21 bytes, BE: 20 bytes, OA: 21 bytes
223300 Sample No.: 11... AMR mode: 4, OA: 21 bytes, BE: 20 bytes, OA: 21 bytes
224 Sample No.: 12... AMR mode: 2, OA: 17 bytes, BE: 16 bytes, OA: 17 bytes
301 Sample No.: 12... AMR mode: 4, OA: 21 bytes, BE: 20 bytes, OA: 21 bytes
225302 Sample No.: 13... AMR mode: 2, OA: 17 bytes, BE: 16 bytes, OA: 17 bytes
226303 Sample No.: 14... AMR mode: 2, OA: 17 bytes, BE: 16 bytes, OA: 17 bytes
227 Sample No.: 15... AMR mode: 1, OA: 15 bytes, BE: 15 bytes, OA: 15 bytes
304 Sample No.: 15... AMR mode: 2, OA: 17 bytes, BE: 16 bytes, OA: 17 bytes
228305 Sample No.: 16... AMR mode: 1, OA: 15 bytes, BE: 15 bytes, OA: 15 bytes
229306 Sample No.: 17... AMR mode: 1, OA: 15 bytes, BE: 15 bytes, OA: 15 bytes
230 Sample No.: 18... AMR mode: 0, OA: 14 bytes, BE: 14 bytes, OA: 14 bytes
307 Sample No.: 18... AMR mode: 1, OA: 15 bytes, BE: 15 bytes, OA: 15 bytes
231308 Sample No.: 19... AMR mode: 0, OA: 14 bytes, BE: 14 bytes, OA: 14 bytes
232309 Sample No.: 20... AMR mode: 0, OA: 14 bytes, BE: 14 bytes, OA: 14 bytes
233 Sample No.: 21... skipping a sample with a wrong FT
310 Sample No.: 21... AMR mode: 0, OA: 14 bytes, BE: 14 bytes, OA: 14 bytes
311 Sample No.: 22... skipping a sample with a wrong FT
312
313
314 Testing conversion from IuUP to bw-efficient and inverse:
315 Sample No.: 0... AMR mode: 7, IuUP: 31 bytes, BE: 32 bytes (00 1e 9a 1e e2 ca 6e 80 80 4f 4f 2e 18 e9 6b d0 81 a1 a5 86 3e d4 cd b5 41 25 a3 5d 50 59 8c 84 ), IuUP: 31 bytes
316 Sample No.: 1... AMR mode: 7, IuUP: 31 bytes, BE: 32 bytes (00 11 20 a0 0e 5d f7 06 20 2d 5a aa c2 5d ca 29 ae ee d2 29 5f 8e bf f9 04 49 60 e2 97 39 97 f0 ), IuUP: 31 bytes
317 Sample No.: 2... AMR mode: 8, IuUP: 5 bytes, BE: 7 bytes (00 09 a0 f0 74 9b 80 ), IuUP: 5 bytes
234318
235319
236320 Testing detection of octet-aligned mode payloads:
255339 Sample No.: 18 ==>octet aligned
256340 Sample No.: 19 ==>octet aligned
257341 Sample No.: 20 ==>octet aligned
258 Sample No.: 21 ==>bandwith efficient
342 Sample No.: 21 ==>octet aligned
343 Sample No.: 22 ==>bandwith efficient
259344 Sample No.: 0 ==>bandwith efficient
260345 Sample No.: 1 ==>bandwith efficient
261346 Sample No.: 2 ==>bandwith efficient
263348 Sample No.: 4 ==>bandwith efficient
264349 Sample No.: 5 ==>bandwith efficient
265350 Sample No.: 6 ==>bandwith efficient
351 Sample No.: 7 ==>bandwith efficient
352 Sample No.: 8 ==>bandwith efficient
353 Sample No.: 9 ==>bandwith efficient
354 Sample No.: 10 ==>bandwith efficient
355 Sample No.: 11 ==>bandwith efficient
356 Sample No.: 12 ==>bandwith efficient
357 Sample No.: 13 ==>bandwith efficient
358 Sample No.: 14 ==>bandwith efficient
359 Sample No.: 15 ==>bandwith efficient
360 Sample No.: 16 ==>bandwith efficient
266361 OK: Test passed
1515 dnl kernel style compile messages
1616 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
1717
18 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
18 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
1919
2020 AC_PROG_CC
2121 AC_DISABLE_STATIC