summaryrefslogtreecommitdiff
path: root/include/asterisk/bridge_technology.h
blob: 12fd49917690cb387a9e4dee0619cd4b47d920ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/*
 * Asterisk -- An open source telephony toolkit.
 *
 * Copyright (C) 2009, Digium, Inc.
 *
 * Joshua Colp <jcolp@digium.com>
 *
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*! \file
 * \brief Channel Bridging API
 * \author Joshua Colp <jcolp@digium.com>
 */

#ifndef _ASTERISK_BRIDGING_TECHNOLOGY_H
#define _ASTERISK_BRIDGING_TECHNOLOGY_H

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

/*!
 * \brief Base preference values for choosing a bridge technology.
 *
 * \note Higher is more preference.
 */
enum ast_bridge_preference {
	AST_BRIDGE_PREFERENCE_BASE_HOLDING  = 50,
	AST_BRIDGE_PREFERENCE_BASE_EARLY    = 100,
	AST_BRIDGE_PREFERENCE_BASE_NATIVE   = 90,
	AST_BRIDGE_PREFERENCE_BASE_1TO1MIX  = 50,
	AST_BRIDGE_PREFERENCE_BASE_MULTIMIX = 10,
};

/*!
 * \brief Structure specific to bridge technologies capable of
 * performing talking optimizations.
 */
struct ast_bridge_tech_optimizations {
	/*! Minimum average magnitude threshold to determine talking by the DSP. */
	unsigned int talking_threshold;
	/*! Time in ms of silence necessary to declare talking stopped by the bridge. */
	unsigned int silence_threshold;
	/*! Whether or not the bridging technology should drop audio
	 *  detected as silence from the mix. */
	unsigned int drop_silence:1;
};

/*!
 * \brief Structure that is the essence of a bridge technology
 */
struct ast_bridge_technology {
	/*! Unique name to this bridge technology */
	const char *name;
	/*! The capabilities that this bridge technology is capable of.  This has nothing to do with
	 * format capabilities. */
	uint32_t capabilities;
	/*! Preference level that should be used when determining whether to use this bridge technology or not */
	enum ast_bridge_preference preference;
	/*!
	 * \brief Create a bridge technology instance for a bridge.
	 *
	 * \retval 0 on success
	 * \retval -1 on failure
	 *
	 * \note On entry, bridge may or may not already be locked.
	 * However, it can be accessed as if it were locked.
	 */
	int (*create)(struct ast_bridge *bridge);
	/*!
	 * \brief Request a bridge technology instance start operations.
	 *
	 * \retval 0 on success
	 * \retval -1 on failure
	 *
	 * \note On entry, bridge may or may not already be locked.
	 * However, it can be accessed as if it were locked.
	 */
	int (*start)(struct ast_bridge *bridge);
	/*!
	 * \brief Request a bridge technology instance stop in preparation for being destroyed.
	 *
	 * \note On entry, bridge is already locked.
	 */
	void (*stop)(struct ast_bridge *bridge);
	/*!
	 * \brief Destroy a bridging technology instance for a bridge.
	 *
	 * \note On entry, bridge must NOT be locked.
	 */
	void (*destroy)(struct ast_bridge *bridge);
	/*!
	 * \brief Add a channel to a bridging technology instance for a bridge.
	 *
	 * \retval 0 on success
	 * \retval -1 on failure
	 *
	 * \note On entry, bridge is already locked.
	 *
	 * \note The bridge technology must tolerate a failed to join channel
	 * until it can be kicked from the bridge.
	 *
	 * \note A channel may be in a suspended state already when joining a bridge
	 * technology. The technology must handle this case.
	 *
	 * \note A channel may not be answered when joining a bridge technology.
	 */
	int (*join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*!
	 * \brief Remove a channel from a bridging technology instance for a bridge.
	 *
	 * \note On entry, bridge is already locked.
	 * \note Do not make assumptions about the number of channels in the bridge when
	 * this callback is called. When a channel is swapped into a bridge for another
	 * channel, the leave callback is called after the new channel has been added to
	 * the bridge.
	 */
	void (*leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*!
	 * \brief Suspend a channel on a bridging technology instance for a bridge.
	 *
	 * \note On entry, bridge is already locked.
	 */
	void (*suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*!
	 * \brief Unsuspend a channel on a bridging technology instance for a bridge.
	 *
	 * \note On entry, bridge is already locked.
	 */
	void (*unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*!
	 * \brief Check if a bridge is compatible with the bridging technology.
	 *
	 * \retval 0 if not compatible
	 * \retval non-zero if compatible
	 *
	 * \note On entry, bridge may or may not already be locked.
	 * However, it can be accessed as if it were locked.
	 */
	int (*compatible)(struct ast_bridge *bridge);
	/*!
	 * \brief Write a frame into the bridging technology instance for a bridge.
	 *
	 * \note The bridge must be tolerant of bridge_channel being NULL.
	 *
	 * \retval 0 Frame accepted into the bridge.
	 * \retval -1 Frame needs to be deferred.
	 *
	 * \note On entry, bridge is already locked.
	 *
	 * \note Deferred frames will be automatically queued onto the channel when another
	 * channel joins the bridge.
	 */
	int (*write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame);
	/*!
	 * \brief Callback for when a request has been made to change a stream topology on a channel
	 *
	 * \details
	 * This is called when a bridge receives a request to change the
	 * topology on the channel.  A bridge technology should define a
	 * handler for this callback if it needs to update internals or
	 * intercept the request and not pass it on to other channels.
	 * This can be done by returning a nonzero value.
	 *
	 * \retval 0 Frame can pass to the bridge technology.
	 * \retval non-zero Frame intercepted by the bridge technology.
	 *
	 * \note On entry, bridge is already locked.
	 */
	int (*stream_topology_request_change)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*!
	 * \brief Callback for when a stream topology changes on the channel
	 *
	 * \details
	 * This is called when a bridge receives an indication that a
	 * topology has been changed on a channel and the new topology has
	 * been mapped to the bridge.  A bridge technology should define a
	 * handler for this callback if it needs to update internals due
	 * to a channel's topology changing.
	 *
	 * \note On entry, bridge is already locked.
	 */
	void (*stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
	/*! TRUE if the bridge technology is currently suspended. */
	unsigned int suspended:1;
	/*! Module this bridge technology belongs to. It is used for reference counting bridges using the technology. */
	struct ast_module *mod;
	/*! Linked list information */
	AST_RWLIST_ENTRY(ast_bridge_technology) entry;
};

/*!
 * \brief Register a bridge technology for use
 *
 * \param technology The bridge technology to register
 * \param mod The module that is registering the bridge technology
 *
 * \retval 0 on success
 * \retval -1 on failure
 *
 * Example usage:
 *
 * \code
 * ast_bridge_technology_register(&simple_bridge_tech);
 * \endcode
 *
 * This registers a bridge technology declared as the structure
 * simple_bridge_tech with the bridging core and makes it available for
 * use when creating bridges.
 */
int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *mod);

/*! \brief See \ref __ast_bridge_technology_register() */
#define ast_bridge_technology_register(technology) __ast_bridge_technology_register(technology, AST_MODULE_SELF)

/*!
 * \brief Unregister a bridge technology from use
 *
 * \param technology The bridge technology to unregister
 *
 * \retval 0 on success
 * \retval -1 on failure
 *
 * Example usage:
 *
 * \code
 * ast_bridge_technology_unregister(&simple_bridge_tech);
 * \endcode
 *
 * This unregisters a bridge technlogy declared as the structure
 * simple_bridge_tech with the bridging core. It will no longer be
 * considered when creating a new bridge.
 */
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology);

/*!
 * \brief Suspend a bridge technology from consideration
 *
 * \param technology The bridge technology to suspend
 *
 * Example usage:
 *
 * \code
 * ast_bridge_technology_suspend(&simple_bridge_tech);
 * \endcode
 *
 * This suspends the bridge technology simple_bridge_tech from being considered
 * when creating a new bridge. Existing bridges using the bridge technology
 * are not affected.
 */
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology);

/*!
 * \brief Unsuspend a bridge technology
 *
 * \param technology The bridge technology to unsuspend
 *
 * Example usage:
 *
 * \code
 * ast_bridge_technology_unsuspend(&simple_bridge_tech);
 * \endcode
 *
 * This makes the bridge technology simple_bridge_tech considered when
 * creating a new bridge again.
 */
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology);

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#endif /* _ASTERISK_BRIDGING_TECHNOLOGY_H */