Import Upstream version 1.2.0
Thorsten Alteholz
1 year, 6 months ago
16 | 16 | |
17 | 17 | You can clone from the official libosmo-netif.git repository using |
18 | 18 | |
19 | git clone git://git.osmocom.org/libosmo-netif.git | |
19 | git clone https://gitea.osmocom.org/osmocom/libosmo-netif | |
20 | 20 | |
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> | |
22 | 22 | |
23 | 23 | Documentation |
24 | 24 | ------------- |
88 | 88 | dnl Generate the output |
89 | 89 | AM_CONFIG_HEADER(config.h) |
90 | 90 | |
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) | |
93 | 93 | |
94 | 94 | AC_ARG_ENABLE([lapd_examples], |
95 | 95 | [AS_HELP_STRING( |
98 | 98 | )], |
99 | 99 | [lapd_examples=$enableval], [lapd_examples="no"]) |
100 | 100 | 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) | |
102 | 102 | AC_DEFINE([ENABLE_LAPD], [1], [Enable LAPD examples]) |
103 | 103 | ]) |
104 | 104 | AM_CONDITIONAL(ENABLE_LAPD, test "x$lapd_examples" = "xyes") |
23 | 23 | BuildRequires: libtool >= 2 |
24 | 24 | BuildRequires: lksctp-tools-devel |
25 | 25 | 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 | |
28 | 28 | |
29 | 29 | %description |
30 | 30 | 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 | ||
0 | 26 | libosmo-netif (1.1.0) unstable; urgency=medium |
1 | 27 | |
2 | 28 | [ Vadim Yanitskiy ] |
10 | 10 | libdpkg-perl, |
11 | 11 | git, |
12 | 12 | doxygen, |
13 | libosmocore-dev (>= 1.5.0), | |
13 | libosmocore-dev (>= 1.7.0), | |
14 | 14 | pkg-config, |
15 | 15 | libpcap0.8-dev, |
16 | 16 | libsctp-dev |
17 | 17 | 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 | |
20 | 20 | Homepage: https://projects.osmocom.org/projects/libosmo-netif |
21 | 21 | |
22 | 22 | Package: libosmonetif8 |
0 | 0 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ |
1 | 1 | Upstream-Name: libosmo-netif |
2 | Source: git://git.osmocom.org/libosmo-netif.git | |
2 | Source: https://gitea.osmocom.org/osmocom/libosmo-netif | |
3 | 3 | |
4 | 4 | Files: * |
5 | 5 | Copyright: 2012-2013 On-Waves |
3 | 3 | osmux.h \ |
4 | 4 | ipa.h \ |
5 | 5 | ipa_unit.h \ |
6 | prim.h \ | |
6 | 7 | rs232.h \ |
7 | 8 | rtp.h \ |
8 | 9 | stream.h |
9 | 10 | |
11 | if ENABLE_LIBSCTP | |
12 | osmonetif_HEADERS += sctp.h | |
13 | endif | |
14 | ||
10 | 15 | osmonetifdir = $(includedir)/osmocom/netif |
108 | 108 | |
109 | 109 | int osmo_amr_ft_valid(uint8_t amr_ft); |
110 | 110 | size_t osmo_amr_bytes(uint8_t amr_cmr); |
111 | size_t osmo_amr_bits(uint8_t amr_ft); | |
111 | 112 | |
112 | 113 | bool osmo_amr_is_oa(uint8_t *payload, unsigned int payload_len); |
113 | 114 | int osmo_amr_oa_to_bwe(uint8_t *payload, unsigned int payload_len); |
114 | 115 | int osmo_amr_bwe_to_oa(uint8_t *payload, unsigned int payload_len, |
115 | 116 | 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); | |
116 | 121 | |
117 | 122 | #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); } |
24 | 24 | int osmo_stream_srv_link_set_addrs(struct osmo_stream_srv_link *link, const char **addr, size_t addrcnt); |
25 | 25 | void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); |
26 | 26 | 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); | |
27 | 29 | 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)); |
28 | 30 | void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data); |
29 | 31 | void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link); |
56 | 58 | void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); |
57 | 59 | int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt); |
58 | 60 | 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); | |
59 | 63 | void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); |
60 | 64 | void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr); |
61 | 65 | int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt); |
0 | 0 | # This is _NOT_ the library release version, it's an API version. |
1 | 1 | # 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 | |
3 | 3 | |
4 | 4 | AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir) |
5 | 5 | AM_CFLAGS= -fPIC -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSCTP_CFLAGS) |
16 | 16 | ipa_unit.c \ |
17 | 17 | jibuf.c \ |
18 | 18 | osmux.c \ |
19 | prim.c \ | |
19 | 20 | rs232.c \ |
20 | 21 | rtp.c \ |
21 | 22 | stream.c |
23 | ||
24 | if ENABLE_LIBSCTP | |
25 | libosmonetif_la_SOURCES += sctp.c | |
26 | endif |
60 | 60 | size_t osmo_amr_bytes(uint8_t amr_ft) |
61 | 61 | { |
62 | 62 | 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; | |
63 | 74 | } |
64 | 75 | |
65 | 76 | int osmo_amr_ft_valid(uint8_t amr_ft) |
91 | 102 | * mode normally relys on out of band methods that explicitly select |
92 | 103 | * one of the two modes. (See also RFC 3267, chapter 3.8). However the |
93 | 104 | * 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. */ | |
96 | 107 | |
97 | 108 | struct amr_hdr *oa_hdr = (struct amr_hdr *)payload; |
98 | 109 | unsigned int frame_len; |
151 | 162 | return -1; |
152 | 163 | |
153 | 164 | /* Move TOC close to CMR */ |
154 | payload[0] |= (payload[1] >> 4) & 0x0f; | |
165 | payload[0] = (payload[0] & 0xf0) | ((payload[1] >> 4) & 0x0f); | |
155 | 166 | payload[1] = (payload[1] << 4) & 0xf0; |
156 | 167 | |
157 | 168 | for (i = 0; i < frame_len; i++) { |
206 | 217 | memcpy(payload, buf, oa_payload_len); |
207 | 218 | return oa_payload_len; |
208 | 219 | } |
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 | }; |
255 | 255 | char *local_addr[OSMO_STREAM_MAX_ADDRS]; |
256 | 256 | uint8_t local_addrcnt; |
257 | 257 | uint16_t local_port; |
258 | int sk_domain; | |
259 | int sk_type; | |
258 | 260 | uint16_t proto; |
259 | 261 | int (*connect_cb)(struct osmo_stream_cli *srv); |
260 | 262 | int (*disconnect_cb)(struct osmo_stream_cli *srv); |
348 | 350 | |
349 | 351 | LOGSCLI(cli, LOGL_DEBUG, "sending %u bytes of data\n", msgb_length(msg)); |
350 | 352 | |
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) { | |
352 | 361 | #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; | |
360 | 369 | #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; | |
362 | 376 | default: |
363 | ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0); | |
364 | break; | |
377 | ret = -ENOTSUP; | |
365 | 378 | } |
366 | 379 | if (ret < 0) { |
367 | 380 | if (errno == EPIPE || errno == ENOTCONN) { |
371 | 384 | } |
372 | 385 | msgb_free(msg); |
373 | 386 | 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 | |
374 | 401 | } |
375 | 402 | |
376 | 403 | static int osmo_stream_cli_fd_cb(struct osmo_fd *ofd, unsigned int what) |
394 | 421 | |
395 | 422 | LOGSCLI(cli, LOGL_DEBUG, "connection done.\n"); |
396 | 423 | 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; | |
406 | 438 | } |
407 | 439 | if (cli->connect_cb) |
408 | 440 | cli->connect_cb(cli); |
440 | 472 | if (!cli) |
441 | 473 | return NULL; |
442 | 474 | |
475 | cli->sk_domain = AF_UNSPEC; | |
476 | cli->sk_type = SOCK_STREAM; | |
443 | 477 | cli->proto = IPPROTO_TCP; |
444 | 478 | cli->ofd.fd = -1; |
445 | 479 | cli->ofd.priv_nr = 0; /* XXX */ |
556 | 590 | cli->flags |= OSMO_STREAM_CLI_F_RECONF; |
557 | 591 | } |
558 | 592 | |
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 | ||
559 | 633 | /*! \brief Set the reconnect time of the stream client socket |
560 | 634 | * \param[in] cli Stream Client to modify |
561 | 635 | * \param[in] timeout Re-connect timeout in seconds or negative value to disable auto-reconnection */ |
730 | 804 | |
731 | 805 | cli->flags &= ~OSMO_STREAM_CLI_F_RECONF; |
732 | 806 | |
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) { | |
735 | 815 | #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; | |
742 | 822 | #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; | |
743 | 830 | 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; | |
748 | 832 | } |
749 | 833 | |
750 | 834 | if (ret < 0) { |
826 | 910 | char *addr[OSMO_STREAM_MAX_ADDRS]; |
827 | 911 | uint8_t addrcnt; |
828 | 912 | uint16_t port; |
913 | int sk_domain; | |
914 | int sk_type; | |
829 | 915 | uint16_t proto; |
830 | 916 | int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd); |
831 | 917 | void *data; |
837 | 923 | int ret; |
838 | 924 | int sock_fd; |
839 | 925 | char addrstr[128]; |
840 | bool is_ipv6; | |
926 | bool is_ipv6 = false; | |
841 | 927 | struct sockaddr_storage sa; |
842 | 928 | socklen_t sa_len = sizeof(sa); |
843 | 929 | struct osmo_stream_srv_link *link = ofd->data; |
848 | 934 | "peer, reason=`%s'\n", strerror(errno)); |
849 | 935 | return ret; |
850 | 936 | } |
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); | |
858 | 937 | sock_fd = ret; |
859 | 938 | |
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; | |
864 | 966 | } |
865 | 967 | |
866 | 968 | if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { |
898 | 1000 | if (!link) |
899 | 1001 | return NULL; |
900 | 1002 | |
1003 | link->sk_domain = AF_UNSPEC; | |
1004 | link->sk_type = SOCK_STREAM; | |
901 | 1005 | link->proto = IPPROTO_TCP; |
902 | 1006 | osmo_fd_setup(&link->ofd, -1, OSMO_FD_READ | OSMO_FD_WRITE, osmo_stream_srv_fd_cb, link, 0); |
903 | 1007 | |
977 | 1081 | link->flags |= OSMO_STREAM_SRV_F_RECONF; |
978 | 1082 | } |
979 | 1083 | |
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 | ||
980 | 1125 | /*! \brief Set application private data of the stream server link |
981 | 1126 | * \param[in] link Stream Server Link to modify |
982 | 1127 | * \param[in] data User-specific data (available in call-back functions) */ |
1059 | 1204 | |
1060 | 1205 | link->flags &= ~OSMO_STREAM_SRV_F_RECONF; |
1061 | 1206 | |
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) { | |
1063 | 1215 | #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; | |
1069 | 1221 | #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; | |
1070 | 1227 | 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; | |
1073 | 1229 | } |
1074 | 1230 | if (ret < 0) |
1075 | 1231 | return ret; |
1143 | 1299 | llist_del(lh); |
1144 | 1300 | msg = llist_entry(lh, struct msgb, list); |
1145 | 1301 | |
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) { | |
1147 | 1310 | #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; | |
1155 | 1318 | #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; | |
1157 | 1325 | default: |
1158 | ret = send(conn->ofd.fd, msg->data, msg->len, 0); | |
1159 | break; | |
1326 | ret = -ENOTSUP; | |
1160 | 1327 | } |
1161 | 1328 | if (ret < 0) { |
1162 | 1329 | LOGP(DLINP, LOGL_ERROR, "error to send\n"); |
1289 | 1456 | osmo_fd_write_enable(&conn->ofd); |
1290 | 1457 | } |
1291 | 1458 | |
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 | ||
1292 | 1509 | /*! \brief Receive data via Osmocom stream server |
1293 | 1510 | * \param[in] conn Stream Server from which to receive |
1294 | 1511 | * \param msg pre-allocate message buffer to which received data is appended |
1296 | 1513 | */ |
1297 | 1514 | int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg) |
1298 | 1515 | { |
1299 | #ifdef HAVE_LIBSCTP | |
1300 | struct sctp_sndrcvinfo sinfo; | |
1301 | int flags = 0; | |
1302 | #endif | |
1303 | 1516 | int ret; |
1304 | 1517 | |
1305 | 1518 | if (!msg) |
1306 | 1519 | return -EINVAL; |
1307 | 1520 | |
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) { | |
1309 | 1529 | #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; | |
1347 | 1538 | } |
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; | |
1353 | 1540 | default: |
1354 | ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0); | |
1355 | break; | |
1541 | ret = -ENOTSUP; | |
1356 | 1542 | } |
1357 | 1543 | |
1358 | 1544 | if (ret < 0) { |
28 | 28 | "703c22f979890338540179209572624a0f8535871c2f7039cbf926b7e4425b6ef0", |
29 | 29 | "703c2e671f3b1b0810412d5adae61e2b2a319885c6ced4e909b4eeaa2ea0f0cd80", |
30 | 30 | "703cf8fc77356c948141686cda34d35220db719e36a359d86b64420dc64b563850", |
31 | "703c3eec9c37dfb201c093c57a1235a02af55ccc22f1c9593a6e058c368b4d7f50", | |
31 | 32 | "60344e300c0e6251342c2ae51fd8a698a945488d16c98922726f3e50", |
32 | 33 | "60341fc722c7880328a9c280030bc9755c3ef519f80000295323e000", |
33 | 34 | "60342c338655c00008efba03592419adf62478a79278b3e2d68ab0f0", |
46 | 47 | "0004f89d67f1160935bde1996840", |
47 | 48 | "0004633cc7f0630439ffe0000000", |
48 | 49 | "0004eb81fc0758973b9edc782550", |
49 | "a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc", /* sample with invalid FT */ | |
50 | "a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc", /* sample with invalid FT, will be detected as bandwith-efficient */ | |
50 | 51 | "END", |
51 | 52 | }; |
52 | 53 | |
54 | 55 | char *bwe_amr_samples[] = { |
55 | 56 | "f4495c7cda8f80", |
56 | 57 | "f44aaa6c969780", |
58 | "7449c1e32c6780", | |
59 | "74400000000380", | |
60 | "703c493323b0bf68028086d15a00", | |
61 | "703c59171697c53c01801fb6aa80", | |
62 | "703c55029bb2e23a0020172e8b00", | |
63 | "703c48f52442f08884a8050b8500", | |
64 | "7038000000000000000000000000", | |
65 | "7151434e01292c40c4735e4412204077", | |
66 | "714eadbe13ac4694f4726f71985d64cd", | |
57 | 67 | "f3d09c20e32da600c025a72e0a9b360386e40f87e19282094adc1a11e397d1d4", |
58 | 68 | "f3d39a49a09e7a802852e297e8c9246aadf5a45928bfc27177fed8404d97d3b8", |
59 | 69 | "f3c2155b65131c68682079fab4810911200003b360ae0446000025f11e539dd0", |
60 | 70 | "f3c381bc7061c9f8507f6029de6115c16e5fa470c243b21b6e35dbb48bd84c00", |
71 | "73c901b7a2004be7f85284b6ab7142acfe6872b1ae1c107d0588b551de7be650", | |
61 | 72 | "a7bfc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03f", /* sample with invalid FT */ |
62 | 73 | "END", |
63 | 74 | }; |
75 | ||
76 | /* Some IuUP payload containg AMR */ | |
77 | char *iuup_amr_samples[] = { | |
78 | "7a687b8b29ba02013d3cb863a5af4206869618fb5336d504968d7541663210", | |
79 | "4482803977dc1880b56aab097728a6bbbb48a57e3affe41125838a5ce65fc0", | |
80 | "2683c1d26e", | |
81 | "END", | |
82 | }; | |
83 | ||
64 | 84 | |
65 | 85 | void dump_bits(uint8_t *buf, int len) |
66 | 86 | { |
184 | 204 | } |
185 | 205 | } |
186 | 206 | |
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 | ||
187 | 257 | void osmo_amr_is_oa_test(void) |
188 | 258 | { |
189 | 259 | uint8_t buf[256]; |
238 | 308 | osmo_amr_oa_to_bwe_test(); |
239 | 309 | osmo_amr_bwe_to_oa_test(); |
240 | 310 | osmo_amr_oa_to_bwe_and_inverse_test(); |
311 | osmo_amr_iuup_to_bwe_and_inverse_test(); | |
241 | 312 | osmo_amr_is_oa_test(); |
242 | 313 | |
243 | 314 | fprintf(stdout, "OK: Test passed\n"); |
23 | 23 | rc: 32 |
24 | 24 | |
25 | 25 | Sample No.: 3 |
26 | octet aligned: 703c3eec9c37dfb201c093c57a1235a02af55ccc22f1c9593a6e058c368b4d7f50 | |
27 | 011100000011110000111110111011001001110000110111110111111011001000000001110000001001001111000101011110100001001000110101101000000010101011110101010111001100110000100010111100011100100101011001001110100110111000000101100011000011011010001011010011010111111101010000 | |
28 | bw-efficient: 73cfbb270df7ec807024f15e848d680abd573308bc72564e9b81630da2d35fd4 | |
29 | 0111001111001111101110110010011100001101111101111110110010000000011100000010010011110001010111101000010010001101011010000000101010111101010101110011001100001000101111000111001001010110010011101001101110000001011000110000110110100010110100110101111111010100 | |
30 | rc: 32 | |
31 | ||
32 | Sample No.: 4 | |
26 | 33 | octet aligned: 60344e300c0e6251342c2ae51fd8a698a945488d16c98922726f3e50 |
27 | 34 | 01100000001101000100111000110000000011000000111001100010010100010011010000101100001010101110010100011111110110001010011010011000101010010100010101001000100011010001011011001001100010010010001001110010011011110011111001010000 |
28 | 35 | bw-efficient: 63538c030398944d0b0ab947f629a62a51522345b262489c9bcf94 |
29 | 36 | 011000110101001110001100000000110000001110011000100101000100110100001011000010101011100101000111111101100010100110100110001010100101000101010010001000110100010110110010011000100100100010011100100110111100111110010100 |
30 | 37 | rc: 27 |
31 | 38 | |
32 | Sample No.: 4 | |
39 | Sample No.: 5 | |
33 | 40 | octet aligned: 60341fc722c7880328a9c280030bc9755c3ef519f80000295323e000 |
34 | 41 | 01100000001101000001111111000111001000101100011110001000000000110010100010101001110000101000000000000011000010111100100101110101010111000011111011110101000110011111100000000000000000000010100101010011001000111110000000000000 |
35 | 42 | bw-efficient: 6347f1c8b1e200ca2a70a000c2f25d570fbd467e00000a54c8f800 |
36 | 43 | 011000110100011111110001110010001011000111100010000000001100101000101010011100001010000000000000110000101111001001011101010101110000111110111101010001100111111000000000000000000000101001010100110010001111100000000000 |
37 | 44 | rc: 27 |
38 | 45 | |
39 | Sample No.: 5 | |
46 | Sample No.: 6 | |
40 | 47 | octet aligned: 60342c338655c00008efba03592419adf62478a79278b3e2d68ab0f0 |
41 | 48 | 01100000001101000010110000110011100001100101010111000000000000000000100011101111101110100000001101011001001001000001100110101101111101100010010001111000101001111001001001111000101100111110001011010110100010101011000011110000 |
42 | 49 | bw-efficient: 634b0ce1957000023bee80d649066b7d891e29e49e2cf8b5a2ac3c |
43 | 50 | 011000110100101100001100111000011001010101110000000000000000001000111011111011101000000011010110010010010000011001101011011111011000100100011110001010011110010010011110001011001111100010110101101000101010110000111100 |
44 | 51 | rc: 27 |
45 | 52 | |
46 | Sample No.: 6 | |
53 | Sample No.: 7 | |
47 | 54 | octet aligned: 502c98ab841e491ff7a1a555016a32a3c7f913210630 |
48 | 55 | 01010000001011001001100010101011100001000001111001001001000111111111011110100001101001010101010100000001011010100011001010100011110001111111100100010011001000010000011000110000 |
49 | 56 | bw-efficient: 52e62ae1079247fde86955405a8ca8f1fe44c8418c00 |
50 | 57 | 01010010111001100010101011100001000001111001001001000111111111011110100001101001010101010100000001011010100011001010100011110001111111100100010011001000010000011000110000000000 |
51 | 58 | rc: 22 |
52 | 59 | |
53 | Sample No.: 7 | |
60 | Sample No.: 8 | |
54 | 61 | octet aligned: 502cc5459a0d200e7097c4dfe86ec8d27f1756d776f0 |
55 | 62 | 01010000001011001100010101000101100110100000110100100000000011100111000010010111110001001101111111101000011011101100100011010010011111110001011101010110110101110111011011110000 |
56 | 63 | bw-efficient: 52f151668348039c25f137fa1bb2349fc5d5b5ddbc00 |
57 | 64 | 01010010111100010101000101100110100000110100100000000011100111000010010111110001001101111111101000011011101100100011010010011111110001011101010110110101110111011011110000000000 |
58 | 65 | rc: 22 |
59 | 66 | |
60 | Sample No.: 8 | |
67 | Sample No.: 9 | |
61 | 68 | octet aligned: 502c42b332081813d7e916e7aa5e80d7fde812b8c080 |
62 | 69 | 01010000001011000100001010110011001100100000100000011000000100111101011111101001000101101110011110101010010111101000000011010111111111011110100000010010101110001100000010000000 |
63 | 70 | bw-efficient: 52d0accc820604f5fa45b9ea97a035ff7a04ae302000 |
64 | 71 | 01010010110100001010110011001100100000100000011000000100111101011111101001000101101110011110101010010111101000000011010111111111011110100000010010101110001100000010000000000000 |
65 | 72 | rc: 22 |
66 | 73 | |
67 | Sample No.: 9 | |
74 | Sample No.: 10 | |
68 | 75 | octet aligned: 40240343e959c79bacd20c77501054880a718db200 |
69 | 76 | 010000000010010000000011010000111110100101011001110001111001101110101100110100100000110001110111010100000001000001010100100010000000101001110001100011011011001000000000 |
70 | 77 | bw-efficient: 4240d0fa5671e6eb34831dd4041522029c636c80 |
71 | 78 | 0100001001000000110100001111101001010110011100011110011011101011001101001000001100011101110101000000010000010101001000100000001010011100011000110110110010000000 |
72 | 79 | rc: 20 |
73 | 80 | |
74 | Sample No.: 10 | |
81 | Sample No.: 11 | |
75 | 82 | octet aligned: 4024172c53401e39115ceecd12606df5689bdd0ca0 |
76 | 83 | 010000000010010000010111001011000101001101000000000111100011100100010001010111001110111011001101000100100110000001101101111101010110100010011011110111010000110010100000 |
77 | 84 | bw-efficient: 4245cb14d0078e44573bb344981b7d5a26f74328 |
78 | 85 | 0100001001000101110010110001010011010000000001111000111001000100010101110011101110110011010001001001100000011011011111010101101000100110111101110100001100101000 |
79 | 86 | rc: 20 |
80 | 87 | |
81 | Sample No.: 11 | |
88 | Sample No.: 12 | |
82 | 89 | octet aligned: 4024f871cf48801ec427f0fc3f7318898622062200 |
83 | 90 | 010000000010010011111000011100011100111101001000100000000001111011000100001001111111000011111100001111110111001100011000100010011000011000100010000001100010001000000000 |
84 | 91 | bw-efficient: 427e1c73d22007b109fc3f0fdcc6226188818880 |
85 | 92 | 0100001001111110000111000111001111010010001000000000011110110001000010011111110000111111000011111101110011000110001000100110000110001000100000011000100010000000 |
86 | 93 | rc: 20 |
87 | 94 | |
88 | Sample No.: 12 | |
95 | Sample No.: 13 | |
89 | 96 | octet aligned: 20141fd4c02667c742b164aef659ffe708 |
90 | 97 | 0010000000010100000111111101010011000000001001100110011111000111010000101011000101100100101011101111011001011001111111111110011100001000 |
91 | 98 | bw-efficient: 2147f5300999f1d0ac592bbd967ff9c2 |
92 | 99 | 00100001010001111111010100110000000010011001100111110001110100001010110001011001001010111011110110010110011111111111100111000010 |
93 | 100 | rc: 16 |
94 | 101 | |
95 | Sample No.: 13 | |
102 | Sample No.: 14 | |
96 | 103 | octet aligned: 2014197e10ead7b250bccbbf3b81887c64 |
97 | 104 | 0010000000010100000110010111111000010000111010101101011110110010010100001011110011001011101111110011101110000001100010000111110001100100 |
98 | 105 | bw-efficient: 21465f843ab5ec942f32efcee0621f19 |
99 | 106 | 00100001010001100101111110000100001110101011010111101100100101000010111100110010111011111100111011100000011000100001111100011001 |
100 | 107 | rc: 16 |
101 | 108 | |
102 | Sample No.: 14 | |
109 | Sample No.: 15 | |
103 | 110 | octet aligned: 2014e959f35fdfe5e9667ffbc088818088 |
104 | 111 | 0010000000010100111010010101100111110011010111111101111111100101111010010110011001111111111110111100000010001000100000011000000010001000 |
105 | 112 | bw-efficient: 217a567cd7f7f97a599ffef022206022 |
106 | 113 | 00100001011110100101011001111100110101111111011111111001011110100101100110011111111111101111000000100010001000000110000000100010 |
107 | 114 | rc: 16 |
108 | 115 | |
109 | Sample No.: 15 | |
116 | Sample No.: 16 | |
110 | 117 | octet aligned: 100c4e9ba850e30d5d53d04de41e7c |
111 | 118 | 000100000000110001001110100110111010100001010000111000110000110101011101010100111101000001001101111001000001111001111100 |
112 | 119 | bw-efficient: 10d3a6ea1438c35754f41379079f00 |
113 | 120 | 000100001101001110100110111010100001010000111000110000110101011101010100111101000001001101111001000001111001111100000000 |
114 | 121 | rc: 15 |
115 | 122 | |
116 | Sample No.: 16 | |
123 | Sample No.: 17 | |
117 | 124 | octet aligned: 100c6c18e7b7fff53aeb055e7d1c54 |
118 | 125 | 000100000000110001101100000110001110011110110111111111111111010100111010111010110000010101011110011111010001110001010100 |
119 | 126 | bw-efficient: 10db0639edfffd4ebac1579f471500 |
120 | 127 | 000100001101101100000110001110011110110111111111111111010100111010111010110000010101011110011111010001110001010100000000 |
121 | 128 | rc: 15 |
122 | 129 | |
123 | Sample No.: 17 | |
130 | Sample No.: 18 | |
124 | 131 | octet aligned: 100c1fb967f7f1fdf547bf2e61c060 |
125 | 132 | 000100000000110000011111101110010110011111110111111100011111110111110101010001111011111100101110011000011100000001100000 |
126 | 133 | bw-efficient: 10c7ee59fdfc7f7d51efcb98701800 |
127 | 134 | 000100001100011111101110010110011111110111111100011111110111110101010001111011111100101110011000011100000001100000000000 |
128 | 135 | rc: 15 |
129 | 136 | |
130 | Sample No.: 18 | |
137 | Sample No.: 19 | |
131 | 138 | octet aligned: 0004f89d67f1160935bde1996840 |
132 | 139 | 0000000000000100111110001001110101100111111100010001011000001001001101011011110111100001100110010110100001000000 |
133 | 140 | bw-efficient: 007e2759fc45824d6f78665a1000 |
134 | 141 | 0000000001111110001001110101100111111100010001011000001001001101011011110111100001100110010110100001000000000000 |
135 | 142 | rc: 14 |
136 | 143 | |
137 | Sample No.: 19 | |
144 | Sample No.: 20 | |
138 | 145 | octet aligned: 0004633cc7f0630439ffe0000000 |
139 | 146 | 0000000000000100011000110011110011000111111100000110001100000100001110011111111111100000000000000000000000000000 |
140 | 147 | bw-efficient: 0058cf31fc18c10e7ff800000000 |
141 | 148 | 0000000001011000110011110011000111111100000110001100000100001110011111111111100000000000000000000000000000000000 |
142 | 149 | rc: 14 |
143 | 150 | |
144 | Sample No.: 20 | |
151 | Sample No.: 21 | |
145 | 152 | octet aligned: 0004eb81fc0758973b9edc782550 |
146 | 153 | 0000000000000100111010111000000111111100000001110101100010010111001110111001111011011100011110000010010101010000 |
147 | 154 | bw-efficient: 007ae07f01d625cee7b71e095400 |
148 | 155 | 0000000001111010111000000111111100000001110101100010010111001110111001111011011100011110000010010101010000000000 |
149 | 156 | rc: 14 |
150 | 157 | |
151 | Sample No.: 21 | |
158 | Sample No.: 22 | |
152 | 159 | octet aligned: a078ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00fc |
153 | 160 | 101000000111100011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111100 |
154 | 161 | bw-efficient: |
173 | 180 | rc: 7 |
174 | 181 | |
175 | 182 | 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 | |
176 | 246 | bw-efficient: f3d09c20e32da600c025a72e0a9b360386e40f87e19282094adc1a11e397d1d4 |
177 | 247 | 1111001111010000100111000010000011100011001011011010011000000000110000000010010110100111001011100000101010011011001101100000001110000110111001000000111110000111111000011001001010000010000010010100101011011100000110100001000111100011100101111101000111010100 |
178 | 248 | octet aligned: f03c4270838cb6980300969cb82a6cd80e1b903e1f864a08252b7068478e5f4750 |
179 | 249 | 111100000011110001000010011100001000001110001100101101101001100000000011000000001001011010011100101110000010101001101100110110000000111000011011100100000011111000011111100001100100101000001000001001010010101101110000011010000100011110001110010111110100011101010000 |
180 | 250 | rc: 33 |
181 | 251 | |
182 | Sample No.: 3 | |
252 | Sample No.: 12 | |
183 | 253 | bw-efficient: f3d39a49a09e7a802852e297e8c9246aadf5a45928bfc27177fed8404d97d3b8 |
184 | 254 | 1111001111010011100110100100100110100000100111100111101010000000001010000101001011100010100101111110100011001001001001000110101010101101111101011010010001011001001010001011111111000010011100010111011111111110110110000100000001001101100101111101001110111000 |
185 | 255 | octet aligned: f03c4e69268279ea00a14b8a5fa32491aab7d69164a2ff09c5dffb6101365f4ee0 |
186 | 256 | 111100000011110001001110011010010010011010000010011110011110101000000000101000010100101110001010010111111010001100100100100100011010101010110111110101101001000101100100101000101111111100001001110001011101111111111011011000010000000100110110010111110100111011100000 |
187 | 257 | rc: 33 |
188 | 258 | |
189 | Sample No.: 4 | |
259 | Sample No.: 13 | |
190 | 260 | bw-efficient: f3c2155b65131c68682079fab4810911200003b360ae0446000025f11e539dd0 |
191 | 261 | 1111001111000010000101010101101101100101000100110001110001101000011010000010000001111001111110101011010010000001000010010001000100100000000000000000001110110011011000001010111000000100010001100000000000000000001001011111000100011110010100111001110111010000 |
192 | 262 | octet aligned: f03c08556d944c71a1a081e7ead204244480000ecd82b81118000097c4794e7740 |
193 | 263 | 111100000011110000001000010101010110110110010100010011000111000110100001101000001000000111100111111010101101001000000100001001000100010010000000000000000000111011001101100000101011100000010001000110000000000000000000100101111100010001111001010011100111011101000000 |
194 | 264 | rc: 33 |
195 | 265 | |
196 | Sample No.: 5 | |
266 | Sample No.: 14 | |
197 | 267 | bw-efficient: f3c381bc7061c9f8507f6029de6115c16e5fa470c243b21b6e35dbb48bd84c00 |
198 | 268 | 1111001111000011100000011011110001110000011000011100100111111000010100000111111101100000001010011101111001100001000101011100000101101110010111111010010001110000110000100100001110110010000110110110111000110101110110111011010010001011110110000100110000000000 |
199 | 269 | octet aligned: f03c0e06f1c18727e141fd80a779845705b97e91c3090ec86db8d76ed22f613000 |
200 | 270 | 111100000011110000001110000001101111000111000001100001110010011111100001010000011111110110000000101001110111100110000100010101110000010110111001011111101001000111000011000010010000111011001000011011011011100011010111011011101101001000101111011000010011000000000000 |
201 | 271 | rc: 33 |
202 | 272 | |
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 | |
204 | 281 | bw-efficient: a7bfc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03fc03f |
205 | 282 | 1010011110111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111 |
206 | 283 | octet aligned: |
212 | 289 | Sample No.: 0... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes |
213 | 290 | Sample No.: 1... AMR mode: 7, OA: 33 bytes, BE: 32 bytes, OA: 33 bytes |
214 | 291 | 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 | |
216 | 293 | Sample No.: 4... AMR mode: 6, OA: 28 bytes, BE: 27 bytes, OA: 28 bytes |
217 | 294 | 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 | |
219 | 296 | Sample No.: 7... AMR mode: 5, OA: 22 bytes, BE: 22 bytes, OA: 22 bytes |
220 | 297 | 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 | |
222 | 299 | Sample No.: 10... AMR mode: 4, OA: 21 bytes, BE: 20 bytes, OA: 21 bytes |
223 | 300 | 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 | |
225 | 302 | Sample No.: 13... AMR mode: 2, OA: 17 bytes, BE: 16 bytes, OA: 17 bytes |
226 | 303 | 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 | |
228 | 305 | Sample No.: 16... AMR mode: 1, OA: 15 bytes, BE: 15 bytes, OA: 15 bytes |
229 | 306 | 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 | |
231 | 308 | Sample No.: 19... AMR mode: 0, OA: 14 bytes, BE: 14 bytes, OA: 14 bytes |
232 | 309 | 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 | |
234 | 318 | |
235 | 319 | |
236 | 320 | Testing detection of octet-aligned mode payloads: |
255 | 339 | Sample No.: 18 ==>octet aligned |
256 | 340 | Sample No.: 19 ==>octet aligned |
257 | 341 | Sample No.: 20 ==>octet aligned |
258 | Sample No.: 21 ==>bandwith efficient | |
342 | Sample No.: 21 ==>octet aligned | |
343 | Sample No.: 22 ==>bandwith efficient | |
259 | 344 | Sample No.: 0 ==>bandwith efficient |
260 | 345 | Sample No.: 1 ==>bandwith efficient |
261 | 346 | Sample No.: 2 ==>bandwith efficient |
263 | 348 | Sample No.: 4 ==>bandwith efficient |
264 | 349 | Sample No.: 5 ==>bandwith efficient |
265 | 350 | 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 | |
266 | 361 | OK: Test passed |