Asterisk - The Open Source Telephony Project  21.4.1
features.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2012, Digium, Inc.
5  * Copyright (C) 2012, Russell Bryant
6  *
7  * Mark Spencer <markster@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \brief Routines implementing call features as call pickup, parking and transfer
23  *
24  * \author Mark Spencer <markster@digium.com>
25  */
26 
27 /*! \li \ref features.c uses the configuration file \ref features.conf
28  * \addtogroup configuration_file Configuration Files
29  */
30 
31 /*!
32  * \page features.conf features.conf
33  * \verbinclude features.conf.sample
34  */
35 
36 /*** MODULEINFO
37  <support_level>core</support_level>
38  ***/
39 
40 #include "asterisk.h"
41 
42 #include "asterisk/_private.h"
43 #include "features_config.h"
44 
45 #include <pthread.h>
46 #include <signal.h>
47 #include <sys/time.h>
48 #include <signal.h>
49 #include <netinet/in.h>
50 
51 #include "asterisk/lock.h"
52 #include "asterisk/file.h"
53 #include "asterisk/channel.h"
54 #include "asterisk/pbx.h"
55 #include "asterisk/causes.h"
56 #include "asterisk/module.h"
57 #include "asterisk/translate.h"
58 #include "asterisk/app.h"
59 #include "asterisk/say.h"
60 #include "asterisk/features.h"
61 #include "asterisk/musiconhold.h"
62 #include "asterisk/config.h"
63 #include "asterisk/cli.h"
64 #include "asterisk/manager.h"
65 #include "asterisk/utils.h"
66 #include "asterisk/devicestate.h"
67 #include "asterisk/audiohook.h"
69 #include "asterisk/astobj2.h"
70 #include "asterisk/test.h"
71 #include "asterisk/bridge.h"
73 #include "asterisk/bridge_basic.h"
74 #include "asterisk/bridge_after.h"
75 #include "asterisk/stasis.h"
76 #include "asterisk/stasis_channels.h"
77 #include "asterisk/features_config.h"
78 #include "asterisk/max_forwards.h"
79 #include "asterisk/stream.h"
80 
81 /*** DOCUMENTATION
82  <application name="Bridge" language="en_US">
83  <synopsis>
84  Bridge two channels.
85  </synopsis>
86  <syntax>
87  <parameter name="channel" required="true">
88  <para>The current channel is bridged to the channel
89  identified by the channel name, channel name prefix, or channel
90  uniqueid.</para>
91  </parameter>
92  <parameter name="options">
93  <optionlist>
94  <option name="p">
95  <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
96  </option>
97  <option name="F" argsep="^">
98  <argument name="context" required="false" />
99  <argument name="exten" required="false" />
100  <argument name="priority" required="true" />
101  <para>When the bridger hangs up, transfer the <emphasis>bridged</emphasis> party
102  to the specified destination and <emphasis>start</emphasis> execution at that location.</para>
103  <note>
104  <para>Any channel variables you want the called channel to inherit from the caller channel must be
105  prefixed with one or two underbars ('_').</para>
106  </note>
107  <note>
108  <para>This option will override the 'x' option</para>
109  </note>
110  </option>
111  <option name="F">
112  <para>When the bridger hangs up, transfer the <emphasis>bridged</emphasis> party
113  to the next priority of the current extension and <emphasis>start</emphasis> execution
114  at that location.</para>
115  <note>
116  <para>Any channel variables you want the called channel to inherit from the caller channel must be
117  prefixed with one or two underbars ('_').</para>
118  </note>
119  <note>
120  <para>Using this option from a or GoSub() might not make sense as there would be no return points.</para>
121  </note>
122  <note>
123  <para>This option will override the 'x' option</para>
124  </note>
125  </option>
126 
127  <option name="h">
128  <para>Allow the called party to hang up by sending the
129  <replaceable>*</replaceable> DTMF digit.</para>
130  </option>
131  <option name="H">
132  <para>Allow the calling party to hang up by pressing the
133  <replaceable>*</replaceable> DTMF digit.</para>
134  </option>
135  <option name="k">
136  <para>Allow the called party to enable parking of the call by sending
137  the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
138  </option>
139  <option name="K">
140  <para>Allow the calling party to enable parking of the call by sending
141  the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
142  </option>
143  <option name="L(x[:y][:z])">
144  <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
145  when <replaceable>y</replaceable> ms are left. Repeat the warning every
146  <replaceable>z</replaceable> ms. The following special variables can be
147  used with this option:</para>
148  <variablelist>
149  <variable name="LIMIT_PLAYAUDIO_CALLER">
150  <para>Play sounds to the caller. yes|no (default yes)</para>
151  </variable>
152  <variable name="LIMIT_PLAYAUDIO_CALLEE">
153  <para>Play sounds to the callee. yes|no</para>
154  </variable>
155  <variable name="LIMIT_TIMEOUT_FILE">
156  <para>File to play when time is up.</para>
157  </variable>
158  <variable name="LIMIT_CONNECT_FILE">
159  <para>File to play when call begins.</para>
160  </variable>
161  <variable name="LIMIT_WARNING_FILE">
162  <para>File to play as warning if <replaceable>y</replaceable> is
163  defined. The default is to say the time remaining.</para>
164  </variable>
165  </variablelist>
166  </option>
167  <option name="n">
168  <para>Do not answer the channel automatically before bridging.</para>
169  <para>Additionally, to prevent a bridged channel (the target of the Bridge application)
170  from answering, the <literal>BRIDGE_NOANSWER</literal> variable can be set to inhibit
171  answering.</para>
172  </option>
173  <option name="S(x)">
174  <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
175  </option>
176  <option name="t">
177  <para>Allow the called party to transfer the calling party by sending the
178  DTMF sequence defined in <filename>features.conf</filename>.</para>
179  </option>
180  <option name="T">
181  <para>Allow the calling party to transfer the called party by sending the
182  DTMF sequence defined in <filename>features.conf</filename>.</para>
183  </option>
184  <option name="w">
185  <para>Allow the called party to enable recording of the call by sending
186  the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
187  </option>
188  <option name="W">
189  <para>Allow the calling party to enable recording of the call by sending
190  the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
191  </option>
192  <option name="x">
193  <para>Cause the called party to be hung up after the bridge, instead of being
194  restarted in the dialplan.</para>
195  </option>
196  </optionlist>
197  </parameter>
198  </syntax>
199  <description>
200  <para>Allows the ability to bridge two channels via the dialplan.</para>
201  <para>This application sets the following channel variable upon completion:</para>
202  <variablelist>
203  <variable name="BRIDGERESULT">
204  <para>The result of the bridge attempt as a text string.</para>
205  <value name="SUCCESS" />
206  <value name="FAILURE" />
207  <value name="LOOP" />
208  <value name="NONEXISTENT" />
209  </variable>
210  </variablelist>
211  </description>
212  <see-also>
213  <ref type="manager">Bridge</ref>
214  <ref type="managerEvent">BridgeCreate</ref>
215  <ref type="managerEvent">BridgeEnter</ref>
216  </see-also>
217  </application>
218  <manager name="Bridge" language="en_US">
219  <synopsis>
220  Bridge two channels already in the PBX.
221  </synopsis>
222  <syntax>
223  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
224  <parameter name="Channel1" required="true">
225  <para>Channel to Bridge to Channel2.</para>
226  </parameter>
227  <parameter name="Channel2" required="true">
228  <para>Channel to Bridge to Channel1.</para>
229  </parameter>
230  <parameter name="Tone">
231  <para>Play courtesy tone to Channel 2.</para>
232  <enumlist>
233  <enum name="no" />
234  <enum name="Channel1" />
235  <enum name="Channel2" />
236  <enum name="Both" />
237  </enumlist>
238  </parameter>
239  </syntax>
240  <description>
241  <para>Bridge together two channels already in the PBX.</para>
242  </description>
243  <see-also>
244  <ref type="application">Bridge</ref>
245  <ref type="managerEvent">BridgeCreate</ref>
246  <ref type="managerEvent">BridgeEnter</ref>
247  <ref type="manager">BridgeDestroy</ref>
248  <ref type="manager">BridgeInfo</ref>
249  <ref type="manager">BridgeKick</ref>
250  <ref type="manager">BridgeList</ref>
251  </see-also>
252  </manager>
253  ***/
254 
255 typedef enum {
256  FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
257  FEATURE_INTERPRET_DO, /* Used by feature_interpret */
258  FEATURE_INTERPRET_CHECK, /* Used by feature_check */
259 } feature_interpret_op;
260 
262  /*! Channel's feature flags. */
264  /*! Bridge peer's feature flags. */
266 };
267 
268 static void *dial_features_duplicate(void *data)
269 {
270  struct ast_dial_features *df = data, *df_copy;
271 
272  if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
273  return NULL;
274  }
275 
276  memcpy(df_copy, df, sizeof(*df));
277 
278  return df_copy;
279 }
280 
281 static const struct ast_datastore_info dial_features_info = {
282  .type = "dial-features",
283  .destroy = ast_free_ptr,
284  .duplicate = dial_features_duplicate,
285 };
286 
287 /*!
288  * \internal
289  * \brief Set the features datastore if it doesn't exist.
290  *
291  * \param chan Channel to add features datastore
292  * \param my_features The channel's feature flags
293  * \param peer_features The channel's bridge peer feature flags
294  *
295  * \retval TRUE if features datastore already existed.
296  */
297 static int add_features_datastore(struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
298 {
299  struct ast_datastore *datastore;
300  struct ast_dial_features *dialfeatures;
301 
302  ast_channel_lock(chan);
303  datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL);
304  ast_channel_unlock(chan);
305  if (datastore) {
306  /* Already exists. */
307  return 1;
308  }
309 
310  /* Create a new datastore with specified feature flags. */
311  datastore = ast_datastore_alloc(&dial_features_info, NULL);
312  if (!datastore) {
313  ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
314  return 0;
315  }
316  dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
317  if (!dialfeatures) {
318  ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
319  ast_datastore_free(datastore);
320  return 0;
321  }
322  ast_copy_flags(&dialfeatures->my_features, my_features, AST_FLAGS_ALL);
323  ast_copy_flags(&dialfeatures->peer_features, peer_features, AST_FLAGS_ALL);
324  datastore->inheritance = DATASTORE_INHERIT_FOREVER;
325  datastore->data = dialfeatures;
326  ast_channel_lock(chan);
327  ast_channel_datastore_add(chan, datastore);
328  ast_channel_unlock(chan);
329  return 0;
330 }
331 
333 {
334  struct ast_bridge_config bconfig;
335  struct ast_channel *chan;
336  struct ast_channel *peer;
337  unsigned int return_to_pbx:1;
338 };
339 
340 static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
341 {
342  ast_clear_flag(config, AST_FLAGS_ALL);
343 
344  if (ast_test_flag(&config->features_caller, AST_FEATURE_DTMF_MASK)) {
345  ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
346  }
347  if (ast_test_flag(&config->features_callee, AST_FEATURE_DTMF_MASK)) {
348  ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
349  }
350 
351  if (!(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
352  RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
353 
354  ast_channel_lock(chan);
355  applicationmap = ast_get_chan_applicationmap(chan);
356  ast_channel_unlock(chan);
357 
358  if (!applicationmap) {
359  return;
360  }
361 
362  /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
363  ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
364  }
365 }
366 
367 void ast_channel_log(char *title, struct ast_channel *chan);
368 
369 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
370 {
371  ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
372  ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
373  ast_channel_name(chan), ast_channel_appl(chan), ast_channel_data(chan),
374  ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan));
375  ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x;\n",
376  ast_channel_accountcode(chan), ast_channel_dialcontext(chan), ast_channel_amaflags(chan));
377  ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
378  ast_channel_masq(chan), ast_channel_masqr(chan),
379  ast_channel_uniqueid(chan), ast_channel_linkedid(chan));
380  if (ast_channel_masqr(chan)) {
381  ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
382  ast_channel_name(ast_channel_masqr(chan)), ast_channel_cdr(ast_channel_masqr(chan)));
383  }
384 
385  ast_log(LOG_NOTICE, "===== done ====\n");
386 }
387 
388 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
389 {
390  const char *feature;
391 
392  if (ast_strlen_zero(features)) {
393  return;
394  }
395 
396  for (feature = features; *feature; feature++) {
397  struct ast_flags *party;
398 
399  if (isupper(*feature)) {
400  party = &config->features_caller;
401  } else {
402  party = &config->features_callee;
403  }
404 
405  switch (tolower(*feature)) {
406  case 't' :
407  ast_set_flag(party, AST_FEATURE_REDIRECT);
408  break;
409  case 'k' :
410  ast_set_flag(party, AST_FEATURE_PARKCALL);
411  break;
412  case 'h' :
413  ast_set_flag(party, AST_FEATURE_DISCONNECT);
414  break;
415  case 'w' :
416  ast_set_flag(party, AST_FEATURE_AUTOMON);
417  break;
418  case 'x' :
419  ast_set_flag(party, AST_FEATURE_AUTOMIXMON);
420  break;
421  default :
422  ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
423  break;
424  }
425  }
426 }
427 
428 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
429 {
430  if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
431  /*
432  * If we don't return here, then when we do a builtin_atxfer we
433  * will copy the disconnect flags over from the atxfer to the
434  * callee (Party C).
435  */
436  return;
437  }
438 
439  add_features_datastore(callee, &config->features_callee, &config->features_caller);
440 }
441 
442 static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
443 {
444  if (config->end_sound) {
445  ast_string_field_set(limits, duration_sound, config->end_sound);
446  }
447 
448  if (config->warning_sound) {
449  ast_string_field_set(limits, warning_sound, config->warning_sound);
450  }
451 
452  if (config->start_sound) {
453  ast_string_field_set(limits, connect_sound, config->start_sound);
454  }
455 
456  limits->frequency = config->warning_freq;
457  limits->warning = config->play_warning;
458 }
459 
460 /*!
461  * \internal brief Setup limit hook structures on calls that need limits
462  *
463  * \param config ast_bridge_config which provides the limit data
464  * \param caller_limits pointer to an ast_bridge_features_limits struct which will store the caller side limits
465  * \param callee_limits pointer to an ast_bridge_features_limits struct which will store the callee side limits
466  */
467 static void bridge_config_set_limits(struct ast_bridge_config *config, struct ast_bridge_features_limits *caller_limits, struct ast_bridge_features_limits *callee_limits)
468 {
469  if (ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING)) {
470  bridge_config_set_limits_warning_values(config, caller_limits);
471  }
472 
473  if (ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING)) {
474  bridge_config_set_limits_warning_values(config, callee_limits);
475  }
476 
477  caller_limits->duration = config->timelimit;
478  callee_limits->duration = config->timelimit;
479 }
480 
481 /*!
482  * \internal
483  * \brief Send the peer channel on its way on bridge start failure.
484  * \since 12.0.0
485  *
486  * \param chan Chan to put into autoservice.
487  * \param peer Chan to send to after bridge goto or run hangup handlers and hangup.
488  */
489 static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
490 {
492  || ast_pbx_start(peer)) {
494  }
495 }
496 
497 static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config,
498  struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features, int noanswer)
499 {
500  int res;
501  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
502 
503  set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
504  add_features_datastores(chan, peer, config);
505 
506  /*
507  * This is an interesting case. One example is if a ringing
508  * channel gets redirected to an extension that picks up a
509  * parked call. This will make sure that the call taken out of
510  * parking gets told that the channel it just got bridged to is
511  * still ringing.
512  */
514  && ast_channel_visible_indication(peer) != AST_CONTROL_RINGING) {
516  }
517 
518  set_config_flags(chan, config);
519 
520  /* Answer if need be */
521 
522  res = 0;
523 
524  if (noanswer) {
525  ast_debug(1, "Skipping answer on %s due to no answer directive\n", ast_channel_name(chan));
526  } else if (ast_channel_state(chan) != AST_STATE_UP) {
527  ast_debug(1, "Answering channel for bridge: %s\n", ast_channel_name(chan));
529  if (res != 0) {
530  return -1;
531  }
532  }
533 
534 
535 #ifdef FOR_DEBUG
536  /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
537  ast_channel_log("Pre-bridge CHAN Channel info", chan);
538  ast_channel_log("Pre-bridge PEER Channel info", peer);
539 #endif
540 
541  res = 0;
542  ast_channel_lock(chan);
543  ast_max_forwards_reset(chan);
544  res |= ast_bridge_features_ds_append(chan, &config->features_caller);
545  ast_channel_unlock(chan);
546  ast_channel_lock(peer);
547  ast_max_forwards_reset(peer);
548  res |= ast_bridge_features_ds_append(peer, &config->features_callee);
549  ast_channel_unlock(peer);
550 
551  if (res) {
552  return -1;
553  }
554 
555  if (config->timelimit) {
556  struct ast_bridge_features_limits call_duration_limits_chan;
557  struct ast_bridge_features_limits call_duration_limits_peer;
558  int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
559 
560  if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
561  ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
562 
563  return -1;
564  }
565 
566  if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
567  ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
568  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
569 
570  return -1;
571  }
572 
573  bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
574 
575  if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
576  abandon_call = 1;
577  }
578  if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
579  abandon_call = 1;
580  }
581 
582  /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
583  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
584  ast_bridge_features_limits_destroy(&call_duration_limits_peer);
585 
586  if (abandon_call) {
587  ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
588  return -1;
589  }
590  }
591 
592  return 0;
593 }
594 
595 int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
596 {
597  int res;
598  struct ast_bridge *bridge;
599  struct ast_bridge_features chan_features;
600  struct ast_bridge_features *peer_features;
601  const char *value;
602  int noanswer;
603  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
604 
605  /* Setup features. */
606  res = ast_bridge_features_init(&chan_features);
607  peer_features = ast_bridge_features_new();
608  if (res || !peer_features) {
609  ast_bridge_features_destroy(peer_features);
610  ast_bridge_features_cleanup(&chan_features);
611  bridge_failed_peer_goto(chan, peer);
612  return -1;
613  }
614 
615  ast_channel_lock(chan);
616  value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
617  noanswer = !ast_strlen_zero(value) ? 1 : 0;
618  ast_channel_unlock(chan);
619 
620  if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features, noanswer)) {
621  ast_bridge_features_destroy(peer_features);
622  ast_bridge_features_cleanup(&chan_features);
623  bridge_failed_peer_goto(chan, peer);
624  return -1;
625  }
626 
627  /* Create bridge */
628  bridge = ast_bridge_basic_new();
629  if (!bridge) {
630  ast_bridge_features_destroy(peer_features);
631  ast_bridge_features_cleanup(&chan_features);
632  bridge_failed_peer_goto(chan, peer);
633  return -1;
634  }
635 
636  ast_bridge_basic_set_flags(bridge, flags);
637 
638  /* Put peer into the bridge */
639  if (ast_bridge_impart(bridge, peer, NULL, peer_features,
641  ast_bridge_destroy(bridge, 0);
642  ast_bridge_features_cleanup(&chan_features);
643  bridge_failed_peer_goto(chan, peer);
644  return -1;
645  }
646 
647  /* Join bridge */
648  ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
650 
651  /*
652  * If the bridge was broken for a hangup that isn't real, then
653  * don't run the h extension, because the channel isn't really
654  * hung up. This should really only happen with
655  * AST_SOFTHANGUP_ASYNCGOTO.
656  */
657  res = -1;
658  ast_channel_lock(chan);
659  if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
660  res = 0;
661  }
662  ast_channel_unlock(chan);
663 
664  ast_bridge_features_cleanup(&chan_features);
665 
666  if (res && config->end_bridge_callback) {
668  }
669 
670  return res;
671 }
672 
673 /*!
674  * \brief bridge the call and set CDR
675  *
676  * \param chan The bridge considers this channel the caller.
677  * \param peer The bridge considers this channel the callee.
678  * \param config Configuration for this bridge.
679  *
680  * Set start time, check for two channels,check if monitor on
681  * check for feature activation, create new CDR
682  * \return res on success.
683  * \retval -1 on failure to bridge.
684  */
685 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
686 {
687  return ast_bridge_call_with_flags(chan, peer, config, 0);
688 }
689 
690 enum play_tone_action {
691  PLAYTONE_NONE = 0,
692  PLAYTONE_CHANNEL1 = (1 << 0),
693  PLAYTONE_CHANNEL2 = (1 << 1),
694  PLAYTONE_BOTH = PLAYTONE_CHANNEL1 | PLAYTONE_CHANNEL2,
695 };
696 
697 static enum play_tone_action parse_playtone(const char *playtone_val)
698 {
699  if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
700  return PLAYTONE_NONE;
701  } if (!strcasecmp(playtone_val, "channel1")) {
702  return PLAYTONE_CHANNEL1;
703  } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
704  return PLAYTONE_CHANNEL2;
705  } else if (!strcasecmp(playtone_val, "both")) {
706  return PLAYTONE_BOTH;
707  } else {
708  /* Invalid input. Assume none */
709  return PLAYTONE_NONE;
710  }
711 }
712 
713 /*!
714  * \brief Bridge channels together
715  * \param s
716  * \param m
717  *
718  * Make sure valid channels were specified,
719  * send errors if any of the channels could not be found/locked, answer channels if needed,
720  * create the placeholder channels and grab the other channels
721  * make the channels compatible, send error if we fail doing so
722  * setup the bridge thread object and start the bridge.
723  *
724  * \retval 0
725  */
726 static int action_bridge(struct mansession *s, const struct message *m)
727 {
728  const char *channela = astman_get_header(m, "Channel1");
729  const char *channelb = astman_get_header(m, "Channel2");
730  enum play_tone_action playtone = parse_playtone(astman_get_header(m, "Tone"));
731  RAII_VAR(struct ast_channel *, chana, NULL, ao2_cleanup);
732  RAII_VAR(struct ast_channel *, chanb, NULL, ao2_cleanup);
733  const char *chana_exten;
734  const char *chana_context;
735  int chana_priority;
736  const char *chanb_exten;
737  const char *chanb_context;
738  int chanb_priority;
739  struct ast_bridge *bridge;
740  char buf[256];
741  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_a, NULL, ao2_cleanup);
742  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_b, NULL, ao2_cleanup);
743 
744  /* make sure valid channels were specified */
745  if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
746  astman_send_error(s, m, "Missing channel parameter in request");
747  return 0;
748  }
749 
750  ast_debug(1, "Performing Bridge action on %s and %s\n", channela, channelb);
751 
752  /* Start with chana */
753  chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
754  if (!chana) {
755  snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
756  astman_send_error(s, m, buf);
757  return 0;
758  }
759  ast_channel_lock(chana);
760  xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
761  chana_exten = ast_strdupa(ast_channel_exten(chana));
762  chana_context = ast_strdupa(ast_channel_context(chana));
763  chana_priority = ast_channel_priority(chana);
764  if (ast_test_flag(ast_channel_flags(chana), AST_FLAG_IN_AUTOLOOP)) {
765  chana_priority++;
766  }
767  ast_channel_unlock(chana);
768 
769  chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
770  if (!chanb) {
771  snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
772  astman_send_error(s, m, buf);
773  return 0;
774  }
775  ast_channel_lock(chanb);
776  xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
777  chanb_exten = ast_strdupa(ast_channel_exten(chanb));
778  chanb_context = ast_strdupa(ast_channel_context(chanb));
779  chanb_priority = ast_channel_priority(chanb);
780  if (ast_test_flag(ast_channel_flags(chanb), AST_FLAG_IN_AUTOLOOP)) {
781  chanb_priority++;
782  }
783  ast_channel_unlock(chanb);
784 
785  bridge = ast_bridge_basic_new();
786  if (!bridge) {
787  astman_send_error(s, m, "Unable to create bridge\n");
788  return 0;
789  }
790 
791  ast_bridge_set_after_goto(chana, chana_context, chana_exten, chana_priority);
792  if (ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
793  snprintf(buf, sizeof(buf), "Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
794  astman_send_error(s, m, buf);
795  ast_bridge_destroy(bridge, 0);
796  return 0;
797  }
798 
799  ast_bridge_set_after_goto(chanb, chanb_context, chanb_exten, chanb_priority);
800  if (ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
801  snprintf(buf, sizeof(buf), "Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
802  astman_send_error(s, m, buf);
803  ast_bridge_destroy(bridge, 0);
804  return 0;
805  }
806 
807  astman_send_ack(s, m, "Channels have been bridged");
808  ao2_cleanup(bridge);
809 
810  return 0;
811 }
812 
813 static char *app_bridge = "Bridge";
814 
815 enum {
816  BRIDGE_OPT_PLAYTONE = (1 << 0),
817  OPT_CALLEE_HANGUP = (1 << 1),
818  OPT_CALLER_HANGUP = (1 << 2),
819  OPT_DURATION_LIMIT = (1 << 3),
820  OPT_DURATION_STOP = (1 << 4),
821  OPT_CALLEE_TRANSFER = (1 << 5),
822  OPT_CALLER_TRANSFER = (1 << 6),
823  OPT_CALLEE_MONITOR = (1 << 7),
824  OPT_CALLER_MONITOR = (1 << 8),
825  OPT_CALLEE_PARK = (1 << 9),
826  OPT_CALLER_PARK = (1 << 10),
827  OPT_CALLEE_KILL = (1 << 11),
828  OPT_CALLEE_GO_ON = (1 << 12),
829  OPT_NOANSWER = (1 << 13),
830 };
831 
832 enum {
833  OPT_ARG_DURATION_LIMIT = 0,
834  OPT_ARG_DURATION_STOP,
835  OPT_ARG_CALLEE_GO_ON,
836  /* note: this entry _MUST_ be the last one in the enum */
837  OPT_ARG_ARRAY_SIZE,
838 };
839 
840 AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
841  AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE),
842  AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
843  AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
844  AST_APP_OPTION('H', OPT_CALLER_HANGUP),
845  AST_APP_OPTION('k', OPT_CALLEE_PARK),
846  AST_APP_OPTION('K', OPT_CALLER_PARK),
847  AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
848  AST_APP_OPTION('n', OPT_NOANSWER),
849  AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
850  AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
851  AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
852  AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
853  AST_APP_OPTION('W', OPT_CALLER_MONITOR),
854  AST_APP_OPTION('x', OPT_CALLEE_KILL),
855 END_OPTIONS );
856 
857 int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
858  char *parse, struct timeval *calldurationlimit)
859 {
860  char *stringp = ast_strdupa(parse);
861  char *limit_str, *warning_str, *warnfreq_str;
862  const char *var;
863  int play_to_caller = 0, play_to_callee = 0;
864  int delta;
865 
866  limit_str = strsep(&stringp, ":");
867  warning_str = strsep(&stringp, ":");
868  warnfreq_str = strsep(&stringp, ":");
869 
870  config->timelimit = atol(limit_str);
871  if (warning_str)
872  config->play_warning = atol(warning_str);
873  if (warnfreq_str)
874  config->warning_freq = atol(warnfreq_str);
875 
876  if (!config->timelimit) {
877  ast_log(LOG_WARNING, "Bridge does not accept L(%s)\n", limit_str);
878  config->timelimit = config->play_warning = config->warning_freq = 0;
879  config->warning_sound = NULL;
880  return -1; /* error */
881  } else if ( (delta = config->play_warning - config->timelimit) > 0) {
882  int w = config->warning_freq;
883 
884  /*
885  * If the first warning is requested _after_ the entire call
886  * would end, and no warning frequency is requested, then turn
887  * off the warning. If a warning frequency is requested, reduce
888  * the 'first warning' time by that frequency until it falls
889  * within the call's total time limit.
890  *
891  * Graphically:
892  * timelim->| delta |<-playwarning
893  * 0__________________|_________________|
894  * | w | | | |
895  *
896  * so the number of intervals to cut is 1+(delta-1)/w
897  */
898  if (w == 0) {
899  config->play_warning = 0;
900  } else {
901  config->play_warning -= w * ( 1 + (delta-1)/w );
902  if (config->play_warning < 1)
903  config->play_warning = config->warning_freq = 0;
904  }
905  }
906 
907  ast_channel_lock(chan);
908 
909  var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
910  play_to_caller = var ? ast_true(var) : 1;
911 
912  var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
913  play_to_callee = var ? ast_true(var) : 0;
914 
915  if (!play_to_caller && !play_to_callee)
916  play_to_caller = 1;
917 
918  var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
919  config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
920 
921  /* The code looking at config wants a NULL, not just "", to decide
922  * that the message should not be played, so we replace "" with NULL.
923  * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
924  * not found.
925  */
926 
927  var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
928  config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
929 
930  var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
931  config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
932 
933  ast_channel_unlock(chan);
934 
935  /* undo effect of S(x) in case they are both used */
936  calldurationlimit->tv_sec = 0;
937  calldurationlimit->tv_usec = 0;
938 
939  /* more efficient to do it like S(x) does since no advanced opts */
940  if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
941  calldurationlimit->tv_sec = config->timelimit / 1000;
942  calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
943  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
944  calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
945  play_to_caller = 0;
946  play_to_callee = 0;
947  config->timelimit = 0;
948  config->play_warning = 0;
949  config->warning_freq = 0;
950  } else {
951  ast_verb(4, "Limit Data for this call:\n");
952  ast_verb(4, "timelimit = %ld ms (%.3lf s)\n", config->timelimit, config->timelimit / 1000.0);
953  ast_verb(4, "play_warning = %ld ms (%.3lf s)\n", config->play_warning, config->play_warning / 1000.0);
954  ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
955  ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
956  ast_verb(4, "warning_freq = %ld ms (%.3lf s)\n", config->warning_freq, config->warning_freq / 1000.0);
957  ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
958  ast_verb(4, "warning_sound = %s\n", config->warning_sound);
959  ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
960  }
961  if (play_to_caller)
962  ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
963  if (play_to_callee)
964  ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
965  return 0;
966 }
967 
968 
969 /*!
970  * \brief Bridge channels
971  * \param chan
972  * \param data channel to bridge with.
973  *
974  * Split data, check we aren't bridging with ourself, check valid channel,
975  * answer call if not already, check compatible channels, setup bridge config
976  * now bridge call, if transferred party hangs up return to PBX extension.
977  */
978 static int bridge_exec(struct ast_channel *chan, const char *data)
979 {
980  struct ast_channel *current_dest_chan = NULL;
981  char *tmp_data = NULL;
982  struct ast_flags opts = { 0, };
983  struct ast_bridge_config bconfig = { { 0, }, };
984  char *opt_args[OPT_ARG_ARRAY_SIZE];
985  struct timeval calldurationlimit = { 0, };
986  const char *context;
987  const char *extension;
988  int priority;
989  int bridge_add_failed;
990  int res = -1;
991  struct ast_bridge_features chan_features;
992  struct ast_bridge_features *peer_features;
993  struct ast_bridge *bridge;
994  struct ast_features_xfer_config *xfer_cfg;
995  int noanswer;
996 
998  AST_APP_ARG(dest_chan);
999  AST_APP_ARG(options);
1000  );
1001 
1002  tmp_data = ast_strdupa(data ?: "");
1003  AST_STANDARD_APP_ARGS(args, tmp_data);
1004  if (!ast_strlen_zero(args.options)) {
1005  ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
1006  }
1007 
1008  /* make sure we have a valid end point */
1009  if (!ast_strlen_zero(args.dest_chan)) {
1010  current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
1011  strlen(args.dest_chan));
1012  }
1013  if (!current_dest_chan) {
1014  ast_verb(4, "Bridge failed because channel '%s' does not exist\n",
1015  args.dest_chan ?: "");
1016  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
1017  return 0;
1018  }
1019 
1020  /* avoid bridge with ourselves */
1021  if (chan == current_dest_chan) {
1022  ast_channel_unref(current_dest_chan);
1023  ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1024  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
1025  return 0;
1026  }
1027 
1028  if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
1029  && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])
1030  && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1031  goto done;
1032  }
1033 
1034  if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
1035  ast_set_flag(&(bconfig.features_callee), AST_FEATURE_REDIRECT);
1036  if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
1037  ast_set_flag(&(bconfig.features_caller), AST_FEATURE_REDIRECT);
1038  if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1039  ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1040  if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1041  ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1042  if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
1043  ast_set_flag(&(bconfig.features_callee), AST_FEATURE_AUTOMON);
1044  if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
1045  ast_set_flag(&(bconfig.features_caller), AST_FEATURE_AUTOMON);
1046  if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1047  ast_set_flag(&(bconfig.features_callee), AST_FEATURE_PARKCALL);
1048  if (ast_test_flag(&opts, OPT_CALLER_PARK))
1049  ast_set_flag(&(bconfig.features_caller), AST_FEATURE_PARKCALL);
1050  noanswer = ast_test_flag(&opts, OPT_NOANSWER);
1051 
1052  /* Setup after bridge goto location. */
1053  if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1054  ast_channel_lock(chan);
1055  context = ast_strdupa(ast_channel_context(chan));
1056  extension = ast_strdupa(ast_channel_exten(chan));
1057  priority = ast_channel_priority(chan);
1058  ast_channel_unlock(chan);
1059  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority,
1060  opt_args[OPT_ARG_CALLEE_GO_ON]);
1061  } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1062  ast_channel_lock(current_dest_chan);
1063  context = ast_strdupa(ast_channel_context(current_dest_chan));
1064  extension = ast_strdupa(ast_channel_exten(current_dest_chan));
1065  priority = ast_channel_priority(current_dest_chan);
1066  ast_channel_unlock(current_dest_chan);
1067  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority, NULL);
1068  }
1069 
1070  if (ast_bridge_features_init(&chan_features)) {
1071  ast_bridge_features_cleanup(&chan_features);
1072  goto done;
1073  }
1074 
1075  peer_features = ast_bridge_features_new();
1076  if (!peer_features) {
1077  ast_bridge_features_cleanup(&chan_features);
1078  goto done;
1079  }
1080 
1081  if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features, noanswer)) {
1082  ast_bridge_features_destroy(peer_features);
1083  ast_bridge_features_cleanup(&chan_features);
1084  goto done;
1085  }
1086 
1087  bridge = ast_bridge_basic_new();
1088  if (!bridge) {
1089  ast_bridge_features_destroy(peer_features);
1090  ast_bridge_features_cleanup(&chan_features);
1091  goto done;
1092  }
1093 
1094  ast_channel_lock(current_dest_chan);
1095  xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1096  ast_channel_unlock(current_dest_chan);
1097  bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
1098  ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE),
1099  xfer_cfg ? xfer_cfg->xfersound : NULL);
1100  ao2_cleanup(xfer_cfg);
1101  if (bridge_add_failed) {
1102  ast_bridge_features_cleanup(&chan_features);
1103  ast_bridge_destroy(bridge, 0);
1104  goto done;
1105  }
1106 
1107  /* Don't keep the channel ref in case it was not already in a bridge. */
1108  current_dest_chan = ast_channel_unref(current_dest_chan);
1109 
1110  res = ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
1112 
1113  ast_bridge_features_cleanup(&chan_features);
1114 
1115 done:
1116  if (res == -1) {
1117  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
1118  } else {
1119  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
1120  }
1121 
1122  ast_free((char *) bconfig.warning_sound);
1123  ast_free((char *) bconfig.end_sound);
1124  ast_free((char *) bconfig.start_sound);
1125 
1126  ast_channel_cleanup(current_dest_chan);
1127  return 0;
1128 }
1129 
1130 static int unload_module(void)
1131 {
1132  unload_features_config();
1133 
1134  ast_manager_unregister("Bridge");
1135 
1136  ast_unregister_application(app_bridge);
1137 
1138  return 0;
1139 }
1140 
1141 static int load_module(void)
1142 {
1143  int res;
1144 
1145  res = load_features_config();
1146  res |= ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
1147  res |= ast_manager_register_xml_core("Bridge", EVENT_FLAG_CALL, action_bridge);
1148 
1150 }
1151 
1152 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Call Features",
1153  .support_level = AST_MODULE_SUPPORT_CORE,
1154  .load = load_module,
1155  .unload = unload_module,
1156  .reload = reload_features_config,
1157  .load_pri = AST_MODPRI_CORE,
1158  .requires = "extconfig",
1159 );
const char * type
Definition: datastore.h:32
struct ast_flags peer_features
Definition: features.c:265
Main Channel structure associated with a channel.
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
Music on hold handling.
Feature configuration relating to transfers.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Limit the amount of time a channel may stay in the bridge and optionally play warning messages as tim...
Definition: bridge.c:3412
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
Definition: features.c:978
struct ast_stream_topology * answer_topology
Definition: channel.h:1099
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
Device state management.
Support for translation of data formats. translate.c.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
Audiohooks Architecture.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
int ast_raw_answer_with_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Answer a channel passing in a stream topology.
Definition: channel.c:2639
globally accessible channel datastores
Test Framework API.
Structure for a data store type.
Definition: datastore.h:31
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
struct ast_flags my_features
Definition: features.c:263
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
Bridge a call, and add additional flags to the bridge.
Definition: features.c:595
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3407
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Media Stream API.
Utility functions.
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1434
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3050
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
bridge the call and set CDR
Definition: features.c:685
Configuration File Parser.
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
General Asterisk PBX channel definitions.
void ast_bridge_set_after_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set channel to goto specific location after the bridge.
Definition: bridge_after.c:612
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
void ast_bridge_basic_set_flags(struct ast_bridge *bridge, unsigned int flags)
Set feature flags on a basic bridge.
bridge configuration
Definition: channel.h:1076
void * end_bridge_callback_data
Definition: channel.h:1091
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
structure to hold extensions
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
Definition: manager.c:1785
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:2372
#define ast_debug(level,...)
Log a DEBUG message.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
Core PBX routines and definitions.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Structure that contains information about a bridge.
Definition: bridge.h:349
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
int ast_bridge_add_channel(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
Add an arbitrary channel to a bridge.
Definition: bridge.c:2471
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3396
Structure that contains configuration information for the limits feature.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
Module could not be loaded properly.
Definition: module.h:102
Prototypes for public functions only of internal interest,.
unsigned int inheritance
Definition: datastore.h:69
Basic bridge subclass API.
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Definition: autoservice.c:342
static int action_bridge(struct mansession *s, const struct message *m)
Bridge channels together.
Definition: features.c:726
Structure used to handle boolean flags.
Definition: utils.h:199
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1621
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void(* end_bridge_callback)(void *)
Definition: channel.h:1090
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
Definition: features.c:857
void * data
Definition: datastore.h:66
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags)
Append basic bridge DTMF feature flags on the channel.
Definition: bridge_basic.c:263
After Bridge Execution API.
Standard Command Line Interface.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: utils.c:2216
Internal Asterisk hangup causes.
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx_app.c:103
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
Definition: bridge_after.c:622
Generic container type.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Bridging API.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
Asterisk module definitions.
#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
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:2370
Channel Bridging API.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521