blob: cdb3e62ecad61d7d46ac0a1a5c06cb768341862b [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 *
Harald Welte750d8312019-08-01 20:05:05 +020017 */
18
19/* As the developer and copyright holder of the related code, I hereby
20 * state that any ECU implementation using 'struct osmo_ecu_ops' and
21 * registering with the 'osmo_ecu_register()' function shall not be
22 * considered as a derivative work under any applicable copyright law;
23 * the copyleft terms of GPLv2 shall hence not apply to any such ECU
24 * implementation.
25 *
26 * The intent of the above exception is to allow anyone to combine third
27 * party Error Concealment Unit implementations with libosmocodec.
28 * including but not limited to such published by ETSI.
29 *
30 * -- Harald Welte <laforge@gnumonks.org> on August 1, 2019.
31 */
32
33#include <string.h>
34#include <errno.h>
35
36#include <osmocom/codec/ecu.h>
37#include <osmocom/core/talloc.h>
38
39static const struct osmo_ecu_ops *g_ecu_ops[_NUM_OSMO_ECU_CODECS];
40
41/***********************************************************************
42 * high-level API for users
43 ***********************************************************************/
44
45/*! initialize an ECU instance for given codec.
46 * \param[in] ctx talloc context from which to allocate
Vadim Yanitskiy64277a02023-02-28 03:30:27 +070047 * \param[in] codec codec for which to initialize/create ECU */
Harald Welte750d8312019-08-01 20:05:05 +020048struct osmo_ecu_state *osmo_ecu_init(void *ctx, enum osmo_ecu_codec codec)
49{
50 if (codec >= ARRAY_SIZE(g_ecu_ops))
51 return NULL;
52 if (!g_ecu_ops[codec] || !g_ecu_ops[codec]->init)
53 return NULL;
54 return g_ecu_ops[codec]->init(ctx, codec);
55}
56
57/*! destroy an ECU instance */
58void osmo_ecu_destroy(struct osmo_ecu_state *st)
59{
60 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
61 return;
62 if (!g_ecu_ops[st->codec])
63 return;
64
65 if (!g_ecu_ops[st->codec]->destroy)
66 talloc_free(st);
67 else
68 g_ecu_ops[st->codec]->destroy(st);
69}
70
71/*! process a received frame a substitute/erroneous frame.
72 * \param[in] st ECU state/instance on which to operate
73 * \param[in] bfi Bad Frame Indication
74 * \param[in] frame received codec frame to be processed
75 * \param[in] frame_bytes number of bytes available in frame */
76int osmo_ecu_frame_in(struct osmo_ecu_state *st, bool bfi,
77 const uint8_t *frame, unsigned int frame_bytes)
78{
79 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
80 return -EINVAL;
81 if (!g_ecu_ops[st->codec])
82 return -EBUSY;
83 return g_ecu_ops[st->codec]->frame_in(st, bfi, frame, frame_bytes);
84}
85
86/*! generate output data for a substitute/erroneous frame.
87 * \param[in] st ECU state/instance on which to operate
88 * \param[out] frame_out buffer for generated output frame
89 * \return number of bytes written to frame_out; negative on error */
90int osmo_ecu_frame_out(struct osmo_ecu_state *st, uint8_t *frame_out)
91{
92 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
93 return -EINVAL;
94 if (!g_ecu_ops[st->codec])
95 return -EBUSY;
96 return g_ecu_ops[st->codec]->frame_out(st, frame_out);
97}
98
Mychaela N. Falconia315e78a2023-06-23 18:42:11 +000099/*! check if the current state of this ECU is a DTX pause.
100 * \param[in] st ECU state/instance on which to operate
101 * \return true if DTX pause, false otherwise */
102bool osmo_ecu_is_dtx_pause(struct osmo_ecu_state *st)
103{
104 if (st->codec >= ARRAY_SIZE(g_ecu_ops))
105 return false;
106 if (!g_ecu_ops[st->codec])
107 return false;
108 if (!g_ecu_ops[st->codec]->is_dtx_pause)
109 return false;
110 return g_ecu_ops[st->codec]->is_dtx_pause(st);
111}
112
Harald Welte750d8312019-08-01 20:05:05 +0200113/***********************************************************************
114 * low-level API for ECU implementations
115 ***********************************************************************/
116
117/*! register an ECU implementation for a given codec */
118int osmo_ecu_register(const struct osmo_ecu_ops *ops, enum osmo_ecu_codec codec)
119{
120 if (codec >= ARRAY_SIZE(g_ecu_ops))
121 return -EINVAL;
122 if (g_ecu_ops[codec])
123 return -EBUSY;
124
125 g_ecu_ops[codec] = ops;
126
127 return 0;
128}