Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
refer.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2023, Commend International
5 *
6 * Maximilian Fridrich <m.fridrich@commend.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Out-of-call refer support
22 *
23 * \author Maximilian Fridrich <m.fridrich@commend.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include "asterisk/_private.h"
33
34#include "asterisk/module.h"
35#include "asterisk/datastore.h"
36#include "asterisk/pbx.h"
37#include "asterisk/manager.h"
40#include "asterisk/strings.h"
41#include "asterisk/astobj2.h"
42#include "asterisk/vector.h"
43#include "asterisk/app.h"
45#include "asterisk/refer.h"
46
47struct refer_data {
48 /* Stored in stuff[] at struct end */
49 char *name;
50 /* Stored separately */
51 char *value;
52 /* Holds name */
53 char stuff[0];
54};
55
56/*!
57 * \brief A refer.
58 */
59struct ast_refer {
61 /*! Where the refer is going */
63 /*! Where we "say" the refer came from */
65 /*! Where to refer to */
67 /*! An endpoint associated with this refer */
69 /*! The technology of the endpoint associated with this refer */
71 );
72 /* Whether to refer to Asterisk itself, if refer_to is an Asterisk endpoint. */
74 /*! Technology/dialplan specific variables associated with the refer */
76};
77
78/*! \brief Lock for \c refer_techs vector */
80
81/*! \brief Vector of refer technologies */
83
84static int refer_data_cmp_fn(void *obj, void *arg, int flags)
85{
86 const struct refer_data *object_left = obj;
87 const struct refer_data *object_right = arg;
88 const char *right_key = arg;
89 int cmp;
90
91 switch (flags & OBJ_SEARCH_MASK) {
93 right_key = object_right->name;
94 case OBJ_SEARCH_KEY:
95 cmp = strcasecmp(object_left->name, right_key);
96 break;
98 cmp = strncasecmp(object_left->name, right_key, strlen(right_key));
99 break;
100 default:
101 cmp = 0;
102 break;
103 }
104 if (cmp) {
105 return 0;
106 }
107 return CMP_MATCH;
108}
109
110static void refer_data_destructor(void *obj)
111{
112 struct refer_data *data = obj;
113 ast_free(data->value);
114}
115
116static void refer_destructor(void *obj)
117{
118 struct ast_refer *refer = obj;
119
121 ao2_cleanup(refer->vars);
122}
123
125{
126 struct ast_refer *refer;
127
128 if (!(refer = ao2_alloc_options(sizeof(*refer), refer_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
129 return NULL;
130 }
131
132 if (ast_string_field_init(refer, 128)) {
133 ao2_ref(refer, -1);
134 return NULL;
135 }
136
139 if (!refer->vars) {
140 ao2_ref(refer, -1);
141 return NULL;
142 }
143 refer->to_self = 0;
144
145 return refer;
146}
147
148struct ast_refer *ast_refer_ref(struct ast_refer *refer)
149{
150 ao2_ref(refer, 1);
151 return refer;
152}
153
155{
156 ao2_ref(refer, -1);
157 return NULL;
158}
159
160int ast_refer_set_to(struct ast_refer *refer, const char *fmt, ...)
161{
162 va_list ap;
163
164 va_start(ap, fmt);
165 ast_string_field_build_va(refer, to, fmt, ap);
166 va_end(ap);
167
168 return 0;
169}
170
171int ast_refer_set_from(struct ast_refer *refer, const char *fmt, ...)
172{
173 va_list ap;
174
175 va_start(ap, fmt);
176 ast_string_field_build_va(refer, from, fmt, ap);
177 va_end(ap);
178
179 return 0;
180}
181
182int ast_refer_set_refer_to(struct ast_refer *refer, const char *fmt, ...)
183{
184 va_list ap;
185
186 va_start(ap, fmt);
187 ast_string_field_build_va(refer, refer_to, fmt, ap);
188 va_end(ap);
189
190 return 0;
191}
192
193int ast_refer_set_to_self(struct ast_refer *refer, int val)
194{
195 refer->to_self = val;
196 return 0;
197}
198
199int ast_refer_set_tech(struct ast_refer *refer, const char *fmt, ...)
200{
201 va_list ap;
202
203 va_start(ap, fmt);
204 ast_string_field_build_va(refer, tech, fmt, ap);
205 va_end(ap);
206
207 return 0;
208}
209
210int ast_refer_set_endpoint(struct ast_refer *refer, const char *fmt, ...)
211{
212 va_list ap;
213
214 va_start(ap, fmt);
215 ast_string_field_build_va(refer, endpoint, fmt, ap);
216 va_end(ap);
217
218 return 0;
219}
220
221const char *ast_refer_get_refer_to(const struct ast_refer *refer)
222{
223 return refer->refer_to;
224}
225
226const char *ast_refer_get_from(const struct ast_refer *refer)
227{
228 return refer->from;
229}
230
231const char *ast_refer_get_to(const struct ast_refer *refer)
232{
233 return refer->to;
234}
235
236int ast_refer_get_to_self(const struct ast_refer *refer)
237{
238 return refer->to_self;
239}
240
241const char *ast_refer_get_tech(const struct ast_refer *refer)
242{
243 return refer->tech;
244}
245
246const char *ast_refer_get_endpoint(const struct ast_refer *refer)
247{
248 return refer->endpoint;
249}
250
251static struct refer_data *refer_data_new(const char *name)
252{
253 struct refer_data *data;
254 int name_len = strlen(name) + 1;
255
256 if ((data = ao2_alloc_options(name_len + sizeof(*data), refer_data_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
257 data->name = data->stuff;
258 strcpy(data->name, name);
259 }
260
261 return data;
262}
263
264static struct refer_data *refer_data_find(struct ao2_container *vars, const char *name)
265{
266 return ao2_find(vars, name, OBJ_SEARCH_KEY);
267}
268
270{
271 struct refer_data *data;
272 char *val = NULL;
273
274 if (!(data = ao2_find(refer->vars, name, OBJ_SEARCH_KEY | OBJ_UNLINK))) {
275 return NULL;
276 }
277
278 val = ast_strdup(data->value);
279 ao2_ref(data, -1);
280
281 return val;
282}
283
284static int refer_set_var_full(struct ast_refer *refer, const char *name, const char *value)
285{
286 struct refer_data *data;
287
288 if (!(data = refer_data_find(refer->vars, name))) {
289 if (ast_strlen_zero(value)) {
290 return 0;
291 }
292 if (!(data = refer_data_new(name))) {
293 return -1;
294 };
295 data->value = ast_strdup(value);
296
297 ao2_link(refer->vars, data);
298 } else {
299 if (ast_strlen_zero(value)) {
300 ao2_unlink(refer->vars, data);
301 } else {
302 ast_free(data->value);
303 data->value = ast_strdup(value);
304 }
305 }
306
307 ao2_ref(data, -1);
308
309 return 0;
310}
311
312int ast_refer_set_var_outbound(struct ast_refer *refer, const char *name, const char *value)
313{
315}
316
317const char *ast_refer_get_var(struct ast_refer *refer, const char *name)
318{
319 struct refer_data *data;
320 const char *val = NULL;
321
322 if (!(data = refer_data_find(refer->vars, name))) {
323 return NULL;
324 }
325
326 val = data->value;
327 ao2_ref(data, -1);
328
329 return val;
330}
331
335};
336
338{
340
341 iter = ast_calloc(1, sizeof(*iter));
342 if (!iter) {
343 return NULL;
344 }
345
346 iter->iter = ao2_iterator_init(refer->vars, 0);
347
348 return iter;
349}
350
351int ast_refer_var_iterator_next(struct ast_refer_var_iterator *iter, const char **name, const char **value)
352{
353 struct refer_data *data;
354
355 if (!iter) {
356 return 0;
357 }
358
359 data = ao2_iterator_next(&iter->iter);
360 if (!data) {
361 return 0;
362 }
363
364 *name = data->name;
365 *value = data->value;
366
367 iter->current_used = data;
368
369 return 1;
370}
371
373{
375 iter->current_used = NULL;
376}
377
379{
380 if (iter) {
383 ast_free(iter);
384 }
385}
386
387/*!
388 * \internal \brief Find a \c ast_refer_tech by its technology name
389 *
390 * \param tech_name The name of the refer technology
391 *
392 * \note \c refer_techs should be locked via \c refer_techs_lock prior to
393 * calling this function
394 *
395 * \retval NULL if no \ref ast_refer_tech has been registered
396 * \return \ref ast_refer_tech if registered
397 */
398static const struct ast_refer_tech *refer_find_by_tech_name(const char *tech_name)
399{
400 const struct ast_refer_tech *current;
401 int i;
402
403 for (i = 0; i < AST_VECTOR_SIZE(&refer_techs); i++) {
405 if (!strcmp(current->name, tech_name)) {
406 return current;
407 }
408 }
409
410 return NULL;
411}
412
413int ast_refer_send(struct ast_refer *refer)
414{
415 char *tech_name = NULL;
416 const struct ast_refer_tech *refer_tech;
417 int res = -1;
418
419 if (ast_strlen_zero(refer->to)) {
420 ao2_ref(refer, -1);
421 return -1;
422 }
423
424 tech_name = ast_strdupa(refer->to);
425 tech_name = strsep(&tech_name, ":");
426
429
430 if (!refer_tech) {
431 ast_log(LOG_ERROR, "Unknown refer tech: %s\n", tech_name);
433 ao2_ref(refer, -1);
434 return -1;
435 }
436
437 ao2_lock(refer);
438 res = refer_tech->refer_send(refer);
439 ao2_unlock(refer);
440
442
443 ao2_ref(refer, -1);
444
445 return res;
446}
447
449{
450 const struct ast_refer_tech *match;
451
453
455 if (match) {
456 ast_log(LOG_ERROR, "Refer technology already registered for '%s'\n",
457 tech->name);
459 return -1;
460 }
461
462 if (AST_VECTOR_APPEND(&refer_techs, tech)) {
463 ast_log(LOG_ERROR, "Failed to register refer technology for '%s'\n",
464 tech->name);
466 return -1;
467 }
468 ast_verb(5, "Refer technology '%s' registered.\n", tech->name);
469
471
472 return 0;
473}
474
475/*!
476 * \brief Comparison callback for \c ast_refer_tech vector removal
477 *
478 * \param vec_elem The element in the vector being compared
479 * \param srch The element being looked up
480 *
481 * \retval non-zero The items are equal
482 * \retval 0 The items are not equal
483 */
484static int refer_tech_cmp(const struct ast_refer_tech *vec_elem, const struct ast_refer_tech *srch)
485{
486 if (!vec_elem->name || !srch->name) {
487 return (vec_elem->name == srch->name) ? 1 : 0;
488 }
489 return !strcmp(vec_elem->name, srch->name);
490}
491
493{
494 int match;
495
500
501 if (match) {
502 ast_log(LOG_ERROR, "No '%s' refer technology found.\n", tech->name);
503 return -1;
504 }
505
506 ast_verb(5, "Refer technology '%s' unregistered.\n", tech->name);
507
508 return 0;
509}
510
511/*!
512 * \internal
513 * \brief Clean up other resources on Asterisk shutdown
514 */
515static void refer_shutdown(void)
516{
519}
520
521/*!
522 * \internal
523 * \brief Initialize stuff during Asterisk startup.
524 *
525 * Cleanup isn't a big deal in this function. If we return non-zero,
526 * Asterisk is going to exit.
527 *
528 * \retval 0 success
529 * \retval non-zero failure
530 */
532{
534 if (AST_VECTOR_INIT(&refer_techs, 8)) {
535 return -1;
536 }
538 return 0;
539}
540
541int ast_refer_notify_transfer_request(struct ast_channel *source, const char *referred_by,
542 const char *exten, const char *protocol_id,
543 struct ast_channel *dest, struct ast_refer_params *params,
545{
546 RAII_VAR(struct ast_ari_transfer_message *, transfer_message, NULL, ao2_cleanup);
547 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
548 RAII_VAR(struct ast_bridge *, source_bridge, NULL, ao2_cleanup);
549 RAII_VAR(struct ast_bridge *, dest_bridge, NULL, ao2_cleanup);
550
551 transfer_message = ast_ari_transfer_message_create(source, referred_by, exten, protocol_id, dest, params, state);
552 if (!transfer_message) {
553 return -1;
554 }
555 source_bridge = ast_bridge_transfer_acquire_bridge(source);
556 if (source_bridge) {
558
559 ast_bridge_lock(source_bridge);
560 transfer_message->source_bridge = ast_bridge_get_snapshot(source_bridge);
561 peer = ast_bridge_peer_nolock(source_bridge, source);
562 if (peer) {
563 ast_channel_lock(peer);
564 transfer_message->source_peer = ao2_bump(ast_channel_snapshot(peer));
565 ast_channel_unlock(peer);
566 }
567 ast_bridge_unlock(source_bridge);
568 }
569
570 if (dest) {
571 dest_bridge = ast_bridge_transfer_acquire_bridge(dest);
572 if (dest_bridge) {
574
575 ast_bridge_lock(dest_bridge);
576 transfer_message->dest_bridge = ast_bridge_get_snapshot(dest_bridge);
577 peer = ast_bridge_peer_nolock(dest_bridge, dest);
578 if (peer) {
579 ast_channel_lock(peer);
580 transfer_message->dest_peer = ao2_bump(ast_channel_snapshot(peer));
581 ast_channel_unlock(peer);
582 }
583 ast_bridge_unlock(dest_bridge);
584 }
585 }
586
588 if (msg) {
589 ast_channel_lock(source);
590 stasis_publish(ast_channel_topic(source), msg);
591 ast_channel_unlock(source);
592 }
593
594 return 0;
595}
Prototypes for public functions only of internal interest,.
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ CMP_MATCH
Definition: astobj2.h:1027
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
@ OBJ_UNLINK
Definition: astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4116
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition: bridge.c:4477
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:474
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2387
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
#define ast_channel_lock(chan)
Definition: channel.h:2970
struct ast_channel_snapshot * ast_channel_snapshot(const struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3017
#define ast_channel_unlock(chan)
Definition: channel.h:2971
Asterisk datastore objects.
static const char name[]
Definition: format_mp3.c:68
struct stasis_message_type * ast_channel_transfer_request_type(void)
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
ast_control_transfer
#define LOG_ERROR
#define ast_verb(level,...)
#define ast_rwlock_wrlock(a)
Definition: lock.h:240
#define ast_rwlock_rdlock(a)
Definition: lock.h:239
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:228
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:237
#define ast_rwlock_unlock(a)
Definition: lock.h:238
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Asterisk module definitions.
Core PBX routines and definitions.
static int refer_data_cmp_fn(void *obj, void *arg, int flags)
Definition: refer.c:84
void ast_refer_var_unref_current(struct ast_refer_var_iterator *iter)
Unref a refer var from inside an iterator loop.
Definition: refer.c:372
int ast_refer_tech_unregister(const struct ast_refer_tech *tech)
Unregister a refer technology.
Definition: refer.c:492
const char * ast_refer_get_to(const struct ast_refer *refer)
Retrieve the destination of this refer.
Definition: refer.c:231
int ast_refer_notify_transfer_request(struct ast_channel *source, const char *referred_by, const char *exten, const char *protocol_id, struct ast_channel *dest, struct ast_refer_params *params, enum ast_control_transfer state)
Notify a transfer request.
Definition: refer.c:541
int ast_refer_var_iterator_next(struct ast_refer_var_iterator *iter, const char **name, const char **value)
Get the next variable name and value.
Definition: refer.c:351
static void refer_shutdown(void)
Definition: refer.c:515
static int refer_set_var_full(struct ast_refer *refer, const char *name, const char *value)
Definition: refer.c:284
size_t current
Definition: refer.c:82
struct @384 refer_techs
Vector of refer technologies.
struct ast_refer_var_iterator * ast_refer_var_iterator_init(const struct ast_refer *refer)
Create a new refer variable iterator.
Definition: refer.c:337
struct ast_refer * ast_refer_alloc(void)
Allocate a refer.
Definition: refer.c:124
const char * ast_refer_get_from(const struct ast_refer *refer)
Retrieve the source of this refer.
Definition: refer.c:226
static int refer_tech_cmp(const struct ast_refer_tech *vec_elem, const struct ast_refer_tech *srch)
Comparison callback for ast_refer_tech vector removal.
Definition: refer.c:484
const char * ast_refer_get_var(struct ast_refer *refer, const char *name)
Get the specified variable on the refer.
Definition: refer.c:317
static ast_rwlock_t refer_techs_lock
Lock for refer_techs vector.
Definition: refer.c:79
int ast_refer_set_var_outbound(struct ast_refer *refer, const char *name, const char *value)
Set a variable on the refer being sent to a refer tech directly.
Definition: refer.c:312
const char * ast_refer_get_endpoint(const struct ast_refer *refer)
Retrieve the endpoint associated with this refer.
Definition: refer.c:246
char * ast_refer_get_var_and_unlink(struct ast_refer *refer, const char *name)
Get the specified variable on the refer and unlink it from the container of variables.
Definition: refer.c:269
int ast_refer_set_endpoint(struct ast_refer *refer, const char *fmt,...)
Set the technology's endpoint associated with this refer.
Definition: refer.c:210
static void refer_destructor(void *obj)
Definition: refer.c:116
int ast_refer_set_from(struct ast_refer *refer, const char *fmt,...)
Set the 'from' URI of a refer.
Definition: refer.c:171
struct ast_refer * ast_refer_destroy(struct ast_refer *refer)
Destroy an ast_refer.
Definition: refer.c:154
int ast_refer_set_refer_to(struct ast_refer *refer, const char *fmt,...)
Set the 'refer_to' URI of a refer.
Definition: refer.c:182
const char * ast_refer_get_refer_to(const struct ast_refer *refer)
Get the "refer-to" value of a refer.
Definition: refer.c:221
int ast_refer_set_tech(struct ast_refer *refer, const char *fmt,...)
Set the technology associated with this refer.
Definition: refer.c:199
static void refer_data_destructor(void *obj)
Definition: refer.c:110
int ast_refer_tech_register(const struct ast_refer_tech *tech)
Register a refer technology.
Definition: refer.c:448
int ast_refer_set_to_self(struct ast_refer *refer, int val)
Set the 'to_self' value of a refer.
Definition: refer.c:193
int ast_refer_send(struct ast_refer *refer)
Send a refer directly to an endpoint.
Definition: refer.c:413
static struct refer_data * refer_data_find(struct ao2_container *vars, const char *name)
Definition: refer.c:264
struct ast_refer * ast_refer_ref(struct ast_refer *refer)
Bump a refer's ref count.
Definition: refer.c:148
int ast_refer_set_to(struct ast_refer *refer, const char *fmt,...)
Set the 'to' URI of a refer.
Definition: refer.c:160
int ast_refer_init(void)
Definition: refer.c:531
int ast_refer_get_to_self(const struct ast_refer *refer)
Retrieve the "to_self" value of this refer.
Definition: refer.c:236
void ast_refer_var_iterator_destroy(struct ast_refer_var_iterator *iter)
Destroy a refer variable iterator.
Definition: refer.c:378
static const struct ast_refer_tech * refer_find_by_tech_name(const char *tech_name)
Definition: refer.c:398
const char * ast_refer_get_tech(const struct ast_refer *refer)
Retrieve the technology associated with this refer.
Definition: refer.c:241
static struct refer_data * refer_data_new(const char *name)
Definition: refer.c:251
Out-of-call refer support.
static const struct ast_refer_tech refer_tech
#define NULL
Definition: resample.c:96
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1538
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
struct ast_ari_transfer_message * ast_ari_transfer_message_create(struct ast_channel *originating_chan, const char *referred_by, const char *exten, const char *protocol_id, struct ast_channel *dest, struct ast_refer_params *params, enum ast_control_transfer)
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:591
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
String manipulation functions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Message published during an "ARI" transfer.
Structure that contains information about a bridge.
Definition: bridge.h:353
Main Channel structure associated with a channel.
A refer technology.
Definition: refer.h:57
int(*const refer_send)(const struct ast_refer *refer)
Send a refer.
Definition: refer.h:78
const char *const name
Name of this refer technology.
Definition: refer.h:66
struct ao2_iterator iter
Definition: refer.c:333
struct refer_data * current_used
Definition: refer.c:334
A refer.
Definition: refer.c:59
struct ao2_container * vars
Definition: refer.c:75
int to_self
Definition: refer.c:73
const ast_string_field tech
Definition: refer.c:71
const ast_string_field from
Definition: refer.c:71
const ast_string_field refer_to
Definition: refer.c:71
const ast_string_field endpoint
Definition: refer.c:71
const ast_string_field to
Definition: refer.c:71
Structure for rwlock and tracking information.
Definition: lock.h:161
char * value
Definition: refer.c:51
char * name
Definition: refer.c:49
char stuff[0]
Definition: refer.c:53
struct ast_refer * refer
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37
An API for managing task processing threads that can be shared across modules.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
Vector container support.
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680