blob: db7148ce805505340d7a13709921dc5f007f08e6 [file] [log] [blame]
Harald Welte750d8312019-08-01 20:05:05 +02001/* Core infrastructure for ECU implementations */
2
3/* (C) 2019 by Harald Welte <laforge@gnumonks.org>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23/* As the developer and copyright holder of the related code, I hereby
24 * state that any ECU implementation using 'struct osmo_ecu_ops' and
25 * registering with the 'osmo_ecu_register()' function shall not be
26 * considered as a derivative work under any applicable copyright law;
27 * the copyleft terms of GPLv2 shall hence not apply to any such ECU
28 * implementation.
29 *
30 * The intent of the above exception is to allow anyone to combine third
31 * party Error Concealment Unit implementations with libosmocodec.
32 * including but not limited to such published by ETSI.
33 *
34 * -- Harald Welte <laforge@gnumonks.org> on August 1, 2019.
35 */
36
37#include <string.h>
38#include <errno.h>
39
40#include <osmocom/codec/ecu.h>
41#include <osmocom/core/talloc.h>
42
43static const struct osmo_ecu_ops *g_ecu_ops[_NUM_OSMO_ECU_CODECS];
44
45/***********************************************************************
46 * high-level API for users
47 ***********************************************************************/
48
49/*! initialize an ECU instance for given codec.
50 * \param[in] ctx talloc context from which to allocate
51 * \parma[in] codec codec for which to initialize/create ECU */
52struct osmo_ecu_state *osmo_ecu_init(void *ctx, enum osmo_ecu_codec codec)
53{
54 if (codec >= ARRAY_SIZE(g_ecu_ops))
55 return NULL;
56 if (!g_ecu_ops[codec] || !g_ecu_ops[codec]->init)
57 return NULL;
58 return g_ecu_ops[codec]->init(ctx, codec);
59}
60
61/*! destroy an ECU instance */
62void osmo_ecu_destroy(struct osmo_ecu_state *st)
63{
64 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
65 return;
66 if (!g_ecu_ops[st->codec])
67 return;
68
69 if (!g_ecu_ops[st->codec]->destroy)
70 talloc_free(st);
71 else
72 g_ecu_ops[st->codec]->destroy(st);
73}
74
75/*! process a received frame a substitute/erroneous frame.
76 * \param[in] st ECU state/instance on which to operate
77 * \param[in] bfi Bad Frame Indication
78 * \param[in] frame received codec frame to be processed
79 * \param[in] frame_bytes number of bytes available in frame */
80int osmo_ecu_frame_in(struct osmo_ecu_state *st, bool bfi,
81 const uint8_t *frame, unsigned int frame_bytes)
82{
83 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
84 return -EINVAL;
85 if (!g_ecu_ops[st->codec])
86 return -EBUSY;
87 return g_ecu_ops[st->codec]->frame_in(st, bfi, frame, frame_bytes);
88}
89
90/*! generate output data for a substitute/erroneous frame.
91 * \param[in] st ECU state/instance on which to operate
92 * \param[out] frame_out buffer for generated output frame
93 * \return number of bytes written to frame_out; negative on error */
94int osmo_ecu_frame_out(struct osmo_ecu_state *st, uint8_t *frame_out)
95{
96 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
97 return -EINVAL;
98 if (!g_ecu_ops[st->codec])
99 return -EBUSY;
100 return g_ecu_ops[st->codec]->frame_out(st, frame_out);
101}
102
103/***********************************************************************
104 * low-level API for ECU implementations
105 ***********************************************************************/
106
107/*! register an ECU implementation for a given codec */
108int osmo_ecu_register(const struct osmo_ecu_ops *ops, enum osmo_ecu_codec codec)
109{
110 if (codec >= ARRAY_SIZE(g_ecu_ops))
111 return -EINVAL;
112 if (g_ecu_ops[codec])
113 return -EBUSY;
114
115 g_ecu_ops[codec] = ops;
116
117 return 0;
118}