Asterisk - The Open Source Telephony Project  GIT-master-44aef04
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"
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 Macro() 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="S(x)">
168  <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
169  </option>
170  <option name="t">
171  <para>Allow the called party to transfer the calling party by sending the
172  DTMF sequence defined in <filename>features.conf</filename>.</para>
173  </option>
174  <option name="T">
175  <para>Allow the calling party to transfer the called party by sending the
176  DTMF sequence defined in <filename>features.conf</filename>.</para>
177  </option>
178  <option name="w">
179  <para>Allow the called party to enable recording of the call by sending
180  the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
181  </option>
182  <option name="W">
183  <para>Allow the calling party to enable recording of the call by sending
184  the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
185  </option>
186  <option name="x">
187  <para>Cause the called party to be hung up after the bridge, instead of being
188  restarted in the dialplan.</para>
189  </option>
190  </optionlist>
191  </parameter>
192  </syntax>
193  <description>
194  <para>Allows the ability to bridge two channels via the dialplan.</para>
195  <para>This application sets the following channel variable upon completion:</para>
196  <variablelist>
197  <variable name="BRIDGERESULT">
198  <para>The result of the bridge attempt as a text string.</para>
199  <value name="SUCCESS" />
200  <value name="FAILURE" />
201  <value name="LOOP" />
202  <value name="NONEXISTENT" />
203  </variable>
204  </variablelist>
205  </description>
206  <see-also>
207  <ref type="manager">Bridge</ref>
208  <ref type="managerEvent">BridgeCreate</ref>
209  <ref type="managerEvent">BridgeEnter</ref>
210  </see-also>
211  </application>
212  <manager name="Bridge" language="en_US">
213  <synopsis>
214  Bridge two channels already in the PBX.
215  </synopsis>
216  <syntax>
217  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
218  <parameter name="Channel1" required="true">
219  <para>Channel to Bridge to Channel2.</para>
220  </parameter>
221  <parameter name="Channel2" required="true">
222  <para>Channel to Bridge to Channel1.</para>
223  </parameter>
224  <parameter name="Tone">
225  <para>Play courtesy tone to Channel 2.</para>
226  <enumlist>
227  <enum name="no" />
228  <enum name="Channel1" />
229  <enum name="Channel2" />
230  <enum name="Both" />
231  </enumlist>
232  </parameter>
233  </syntax>
234  <description>
235  <para>Bridge together two channels already in the PBX.</para>
236  </description>
237  <see-also>
238  <ref type="application">Bridge</ref>
239  <ref type="managerEvent">BridgeCreate</ref>
240  <ref type="managerEvent">BridgeEnter</ref>
241  <ref type="manager">BridgeDestroy</ref>
242  <ref type="manager">BridgeInfo</ref>
243  <ref type="manager">BridgeKick</ref>
244  <ref type="manager">BridgeList</ref>
245  </see-also>
246  </manager>
247  ***/
248 
249 typedef enum {
250  FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
251  FEATURE_INTERPRET_DO, /* Used by feature_interpret */
252  FEATURE_INTERPRET_CHECK, /* Used by feature_check */
254 
256  /*! Channel's feature flags. */
258  /*! Bridge peer's feature flags. */
260 };
261 
262 static void *dial_features_duplicate(void *data)
263 {
264  struct ast_dial_features *df = data, *df_copy;
265 
266  if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
267  return NULL;
268  }
269 
270  memcpy(df_copy, df, sizeof(*df));
271 
272  return df_copy;
273 }
274 
275 static const struct ast_datastore_info dial_features_info = {
276  .type = "dial-features",
277  .destroy = ast_free_ptr,
278  .duplicate = dial_features_duplicate,
279 };
280 
281 /*!
282  * \internal
283  * \brief Set the features datastore if it doesn't exist.
284  *
285  * \param chan Channel to add features datastore
286  * \param my_features The channel's feature flags
287  * \param peer_features The channel's bridge peer feature flags
288  *
289  * \retval TRUE if features datastore already existed.
290  */
291 static int add_features_datastore(struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
292 {
293  struct ast_datastore *datastore;
294  struct ast_dial_features *dialfeatures;
295 
296  ast_channel_lock(chan);
297  datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL);
298  ast_channel_unlock(chan);
299  if (datastore) {
300  /* Already exists. */
301  return 1;
302  }
303 
304  /* Create a new datastore with specified feature flags. */
305  datastore = ast_datastore_alloc(&dial_features_info, NULL);
306  if (!datastore) {
307  ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
308  return 0;
309  }
310  dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
311  if (!dialfeatures) {
312  ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
313  ast_datastore_free(datastore);
314  return 0;
315  }
316  ast_copy_flags(&dialfeatures->my_features, my_features, AST_FLAGS_ALL);
317  ast_copy_flags(&dialfeatures->peer_features, peer_features, AST_FLAGS_ALL);
319  datastore->data = dialfeatures;
320  ast_channel_lock(chan);
321  ast_channel_datastore_add(chan, datastore);
322  ast_channel_unlock(chan);
323  return 0;
324 }
325 
327 {
328  struct ast_bridge_config bconfig;
329  struct ast_channel *chan;
330  struct ast_channel *peer;
331  unsigned int return_to_pbx:1;
332 };
333 
334 static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
335 {
336  ast_clear_flag(config, AST_FLAGS_ALL);
337 
340  }
343  }
344 
346  RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
347 
348  ast_channel_lock(chan);
349  applicationmap = ast_get_chan_applicationmap(chan);
350  ast_channel_unlock(chan);
351 
352  if (!applicationmap) {
353  return;
354  }
355 
356  /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
358  }
359 }
360 
361 void ast_channel_log(char *title, struct ast_channel *chan);
362 
363 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
364 {
365  ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
366  ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
369  ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
372  ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
373  ast_channel_masq(chan), ast_channel_masqr(chan),
375  if (ast_channel_masqr(chan)) {
376  ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
378  }
379 
380  ast_log(LOG_NOTICE, "===== done ====\n");
381 }
382 
383 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
384 {
385  const char *feature;
386 
387  if (ast_strlen_zero(features)) {
388  return;
389  }
390 
391  for (feature = features; *feature; feature++) {
392  struct ast_flags *party;
393 
394  if (isupper(*feature)) {
395  party = &config->features_caller;
396  } else {
397  party = &config->features_callee;
398  }
399 
400  switch (tolower(*feature)) {
401  case 't' :
403  break;
404  case 'k' :
406  break;
407  case 'h' :
409  break;
410  case 'w' :
412  break;
413  case 'x' :
415  break;
416  default :
417  ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
418  break;
419  }
420  }
421 }
422 
423 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
424 {
425  if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
426  /*
427  * If we don't return here, then when we do a builtin_atxfer we
428  * will copy the disconnect flags over from the atxfer to the
429  * callee (Party C).
430  */
431  return;
432  }
433 
434  add_features_datastore(callee, &config->features_callee, &config->features_caller);
435 }
436 
438 {
439  if (config->end_sound) {
440  ast_string_field_set(limits, duration_sound, config->end_sound);
441  }
442 
443  if (config->warning_sound) {
444  ast_string_field_set(limits, warning_sound, config->warning_sound);
445  }
446 
447  if (config->start_sound) {
448  ast_string_field_set(limits, connect_sound, config->start_sound);
449  }
450 
451  limits->frequency = config->warning_freq;
452  limits->warning = config->play_warning;
453 }
454 
455 /*!
456  * \internal brief Setup limit hook structures on calls that need limits
457  *
458  * \param config ast_bridge_config which provides the limit data
459  * \param caller_limits pointer to an ast_bridge_features_limits struct which will store the caller side limits
460  * \param callee_limits pointer to an ast_bridge_features_limits struct which will store the callee side limits
461  */
462 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)
463 {
465  bridge_config_set_limits_warning_values(config, caller_limits);
466  }
467 
469  bridge_config_set_limits_warning_values(config, callee_limits);
470  }
471 
472  caller_limits->duration = config->timelimit;
473  callee_limits->duration = config->timelimit;
474 }
475 
476 /*!
477  * \internal
478  * \brief Check if Monitor needs to be started on a channel.
479  * \since 12.0.0
480  *
481  * \param chan The bridge considers this channel the caller.
482  * \param peer The bridge considers this channel the callee.
483  *
484  * \return Nothing
485  */
486 static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
487 {
488  const char *value;
489  const char *monitor_args = NULL;
490  struct ast_channel *monitor_chan = NULL;
491 
492  ast_channel_lock(chan);
493  value = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR");
494  if (!ast_strlen_zero(value)) {
495  monitor_args = ast_strdupa(value);
496  monitor_chan = chan;
497  }
498  ast_channel_unlock(chan);
499  if (!monitor_chan) {
500  ast_channel_lock(peer);
501  value = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR");
502  if (!ast_strlen_zero(value)) {
503  monitor_args = ast_strdupa(value);
504  monitor_chan = peer;
505  }
506  ast_channel_unlock(peer);
507  }
508  if (monitor_chan) {
509  struct ast_app *monitor_app;
510 
511  monitor_app = pbx_findapp("Monitor");
512  if (monitor_app) {
513  pbx_exec(monitor_chan, monitor_app, monitor_args);
514  }
515  }
516 }
517 
518 /*!
519  * \internal
520  * \brief Send the peer channel on its way on bridge start failure.
521  * \since 12.0.0
522  *
523  * \param chan Chan to put into autoservice.
524  * \param peer Chan to send to after bridge goto or run hangup handlers and hangup.
525  *
526  * \return Nothing
527  */
528 static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
529 {
531  || ast_pbx_start(peer)) {
533  }
534 }
535 
536 static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config,
537  struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features)
538 {
539  int res;
540  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
541 
542  set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
543  add_features_datastores(chan, peer, config);
544 
545  /*
546  * This is an interesting case. One example is if a ringing
547  * channel gets redirected to an extension that picks up a
548  * parked call. This will make sure that the call taken out of
549  * parking gets told that the channel it just got bridged to is
550  * still ringing.
551  */
555  }
556 
557  bridge_check_monitor(chan, peer);
558 
559  set_config_flags(chan, config);
560 
561  /* Answer if need be */
562 
563  res = 0;
564 
565  if (ast_channel_state(chan) != AST_STATE_UP) {
567  if (res != 0) {
568  return -1;
569  }
570  }
571 
572 
573 #ifdef FOR_DEBUG
574  /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
575  ast_channel_log("Pre-bridge CHAN Channel info", chan);
576  ast_channel_log("Pre-bridge PEER Channel info", peer);
577 #endif
578 
579  res = 0;
580  ast_channel_lock(chan);
582  res |= ast_bridge_features_ds_append(chan, &config->features_caller);
583  ast_channel_unlock(chan);
584  ast_channel_lock(peer);
586  res |= ast_bridge_features_ds_append(peer, &config->features_callee);
587  ast_channel_unlock(peer);
588 
589  if (res) {
590  return -1;
591  }
592 
593  if (config->timelimit) {
594  struct ast_bridge_features_limits call_duration_limits_chan;
595  struct ast_bridge_features_limits call_duration_limits_peer;
596  int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
597 
598  if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
599  ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
600 
601  return -1;
602  }
603 
604  if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
605  ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
606  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
607 
608  return -1;
609  }
610 
611  bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
612 
613  if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
614  abandon_call = 1;
615  }
616  if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
617  abandon_call = 1;
618  }
619 
620  /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
621  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
622  ast_bridge_features_limits_destroy(&call_duration_limits_peer);
623 
624  if (abandon_call) {
625  ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
626  return -1;
627  }
628  }
629 
630  return 0;
631 }
632 
633 int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
634 {
635  int res;
636  struct ast_bridge *bridge;
637  struct ast_bridge_features chan_features;
639  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
640 
641  /* Setup features. */
642  res = ast_bridge_features_init(&chan_features);
643  peer_features = ast_bridge_features_new();
644  if (res || !peer_features) {
645  ast_bridge_features_destroy(peer_features);
646  ast_bridge_features_cleanup(&chan_features);
647  bridge_failed_peer_goto(chan, peer);
648  return -1;
649  }
650 
651  if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features)) {
652  ast_bridge_features_destroy(peer_features);
653  ast_bridge_features_cleanup(&chan_features);
654  bridge_failed_peer_goto(chan, peer);
655  return -1;
656  }
657 
658  /* Create bridge */
659  bridge = ast_bridge_basic_new();
660  if (!bridge) {
661  ast_bridge_features_destroy(peer_features);
662  ast_bridge_features_cleanup(&chan_features);
663  bridge_failed_peer_goto(chan, peer);
664  return -1;
665  }
666 
667  ast_bridge_basic_set_flags(bridge, flags);
668 
669  /* Put peer into the bridge */
670  if (ast_bridge_impart(bridge, peer, NULL, peer_features,
672  ast_bridge_destroy(bridge, 0);
673  ast_bridge_features_cleanup(&chan_features);
674  bridge_failed_peer_goto(chan, peer);
675  return -1;
676  }
677 
678  /* Join bridge */
679  ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
681 
682  /*
683  * If the bridge was broken for a hangup that isn't real, then
684  * don't run the h extension, because the channel isn't really
685  * hung up. This should really only happen with
686  * AST_SOFTHANGUP_ASYNCGOTO.
687  */
688  res = -1;
689  ast_channel_lock(chan);
691  res = 0;
692  }
693  ast_channel_unlock(chan);
694 
695  ast_bridge_features_cleanup(&chan_features);
696 
697  if (res && config->end_bridge_callback) {
699  }
700 
701  return res;
702 }
703 
704 /*!
705  * \brief bridge the call and set CDR
706  *
707  * \param chan The bridge considers this channel the caller.
708  * \param peer The bridge considers this channel the callee.
709  * \param config Configuration for this bridge.
710  *
711  * Set start time, check for two channels,check if monitor on
712  * check for feature activation, create new CDR
713  * \retval res on success.
714  * \retval -1 on failure to bridge.
715  */
716 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
717 {
718  return ast_bridge_call_with_flags(chan, peer, config, 0);
719 }
720 
723  PLAYTONE_CHANNEL1 = (1 << 0),
724  PLAYTONE_CHANNEL2 = (1 << 1),
726 };
727 
728 static enum play_tone_action parse_playtone(const char *playtone_val)
729 {
730  if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
731  return PLAYTONE_NONE;
732  } if (!strcasecmp(playtone_val, "channel1")) {
733  return PLAYTONE_CHANNEL1;
734  } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
735  return PLAYTONE_CHANNEL2;
736  } else if (!strcasecmp(playtone_val, "both")) {
737  return PLAYTONE_BOTH;
738  } else {
739  /* Invalid input. Assume none */
740  return PLAYTONE_NONE;
741  }
742 }
743 
744 /*!
745  * \brief Bridge channels together
746  * \param s
747  * \param m
748  *
749  * Make sure valid channels were specified,
750  * send errors if any of the channels could not be found/locked, answer channels if needed,
751  * create the placeholder channels and grab the other channels
752  * make the channels compatible, send error if we fail doing so
753  * setup the bridge thread object and start the bridge.
754  *
755  * \retval 0
756  */
757 static int action_bridge(struct mansession *s, const struct message *m)
758 {
759  const char *channela = astman_get_header(m, "Channel1");
760  const char *channelb = astman_get_header(m, "Channel2");
762  RAII_VAR(struct ast_channel *, chana, NULL, ao2_cleanup);
763  RAII_VAR(struct ast_channel *, chanb, NULL, ao2_cleanup);
764  const char *chana_exten;
765  const char *chana_context;
766  int chana_priority;
767  const char *chanb_exten;
768  const char *chanb_context;
769  int chanb_priority;
770  struct ast_bridge *bridge;
771  char buf[256];
772  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_a, NULL, ao2_cleanup);
773  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_b, NULL, ao2_cleanup);
774 
775  /* make sure valid channels were specified */
776  if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
777  astman_send_error(s, m, "Missing channel parameter in request");
778  return 0;
779  }
780 
781  ast_debug(1, "Performing Bridge action on %s and %s\n", channela, channelb);
782 
783  /* Start with chana */
784  chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
785  if (!chana) {
786  snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
787  astman_send_error(s, m, buf);
788  return 0;
789  }
790  ast_channel_lock(chana);
791  xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
792  chana_exten = ast_strdupa(ast_channel_exten(chana));
793  chana_context = ast_strdupa(ast_channel_context(chana));
794  chana_priority = ast_channel_priority(chana);
796  chana_priority++;
797  }
798  ast_channel_unlock(chana);
799 
800  chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
801  if (!chanb) {
802  snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
803  astman_send_error(s, m, buf);
804  return 0;
805  }
806  ast_channel_lock(chanb);
807  xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
808  chanb_exten = ast_strdupa(ast_channel_exten(chanb));
809  chanb_context = ast_strdupa(ast_channel_context(chanb));
810  chanb_priority = ast_channel_priority(chanb);
812  chanb_priority++;
813  }
814  ast_channel_unlock(chanb);
815 
816  bridge = ast_bridge_basic_new();
817  if (!bridge) {
818  astman_send_error(s, m, "Unable to create bridge\n");
819  return 0;
820  }
821 
822  ast_bridge_set_after_goto(chana, chana_context, chana_exten, chana_priority);
823  if (ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
824  snprintf(buf, sizeof(buf), "Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
825  astman_send_error(s, m, buf);
826  ast_bridge_destroy(bridge, 0);
827  return 0;
828  }
829 
830  ast_bridge_set_after_goto(chanb, chanb_context, chanb_exten, chanb_priority);
831  if (ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
832  snprintf(buf, sizeof(buf), "Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
833  astman_send_error(s, m, buf);
834  ast_bridge_destroy(bridge, 0);
835  return 0;
836  }
837 
838  astman_send_ack(s, m, "Channels have been bridged");
839  ao2_cleanup(bridge);
840 
841  return 0;
842 }
843 
844 static char *app_bridge = "Bridge";
845 
846 enum {
848  OPT_CALLEE_HANGUP = (1 << 1),
849  OPT_CALLER_HANGUP = (1 << 2),
850  OPT_DURATION_LIMIT = (1 << 3),
851  OPT_DURATION_STOP = (1 << 4),
854  OPT_CALLEE_MONITOR = (1 << 7),
855  OPT_CALLER_MONITOR = (1 << 8),
856  OPT_CALLEE_PARK = (1 << 9),
857  OPT_CALLER_PARK = (1 << 10),
858  OPT_CALLEE_KILL = (1 << 11),
859  OPT_CALLEE_GO_ON = (1 << 12),
860 };
861 
862 enum {
866  /* note: this entry _MUST_ be the last one in the enum */
868 };
869 
885 
887  char *parse, struct timeval *calldurationlimit)
888 {
889  char *stringp = ast_strdupa(parse);
890  char *limit_str, *warning_str, *warnfreq_str;
891  const char *var;
892  int play_to_caller = 0, play_to_callee = 0;
893  int delta;
894 
895  limit_str = strsep(&stringp, ":");
896  warning_str = strsep(&stringp, ":");
897  warnfreq_str = strsep(&stringp, ":");
898 
899  config->timelimit = atol(limit_str);
900  if (warning_str)
901  config->play_warning = atol(warning_str);
902  if (warnfreq_str)
903  config->warning_freq = atol(warnfreq_str);
904 
905  if (!config->timelimit) {
906  ast_log(LOG_WARNING, "Bridge does not accept L(%s)\n", limit_str);
907  config->timelimit = config->play_warning = config->warning_freq = 0;
908  config->warning_sound = NULL;
909  return -1; /* error */
910  } else if ( (delta = config->play_warning - config->timelimit) > 0) {
911  int w = config->warning_freq;
912 
913  /*
914  * If the first warning is requested _after_ the entire call
915  * would end, and no warning frequency is requested, then turn
916  * off the warning. If a warning frequency is requested, reduce
917  * the 'first warning' time by that frequency until it falls
918  * within the call's total time limit.
919  *
920  * Graphically:
921  * timelim->| delta |<-playwarning
922  * 0__________________|_________________|
923  * | w | | | |
924  *
925  * so the number of intervals to cut is 1+(delta-1)/w
926  */
927  if (w == 0) {
928  config->play_warning = 0;
929  } else {
930  config->play_warning -= w * ( 1 + (delta-1)/w );
931  if (config->play_warning < 1)
932  config->play_warning = config->warning_freq = 0;
933  }
934  }
935 
936  ast_channel_lock(chan);
937 
938  var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
939  play_to_caller = var ? ast_true(var) : 1;
940 
941  var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
942  play_to_callee = var ? ast_true(var) : 0;
943 
944  if (!play_to_caller && !play_to_callee)
945  play_to_caller = 1;
946 
947  var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
948  config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
949 
950  /* The code looking at config wants a NULL, not just "", to decide
951  * that the message should not be played, so we replace "" with NULL.
952  * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
953  * not found.
954  */
955 
956  var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
957  config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
958 
959  var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
960  config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
961 
962  ast_channel_unlock(chan);
963 
964  /* undo effect of S(x) in case they are both used */
965  calldurationlimit->tv_sec = 0;
966  calldurationlimit->tv_usec = 0;
967 
968  /* more efficient to do it like S(x) does since no advanced opts */
969  if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
970  calldurationlimit->tv_sec = config->timelimit / 1000;
971  calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
972  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
973  calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
974  play_to_caller = 0;
975  play_to_callee = 0;
976  config->timelimit = 0;
977  config->play_warning = 0;
978  config->warning_freq = 0;
979  } else {
980  ast_verb(4, "Limit Data for this call:\n");
981  ast_verb(4, "timelimit = %ld ms (%.3lf s)\n", config->timelimit, config->timelimit / 1000.0);
982  ast_verb(4, "play_warning = %ld ms (%.3lf s)\n", config->play_warning, config->play_warning / 1000.0);
983  ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
984  ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
985  ast_verb(4, "warning_freq = %ld ms (%.3lf s)\n", config->warning_freq, config->warning_freq / 1000.0);
986  ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
987  ast_verb(4, "warning_sound = %s\n", config->warning_sound);
988  ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
989  }
990  if (play_to_caller)
992  if (play_to_callee)
994  return 0;
995 }
996 
997 
998 /*!
999  * \brief Bridge channels
1000  * \param chan
1001  * \param data channel to bridge with.
1002  *
1003  * Split data, check we aren't bridging with ourself, check valid channel,
1004  * answer call if not already, check compatible channels, setup bridge config
1005  * now bridge call, if transferred party hangs up return to PBX extension.
1006  */
1007 static int bridge_exec(struct ast_channel *chan, const char *data)
1008 {
1009  struct ast_channel *current_dest_chan = NULL;
1010  char *tmp_data = NULL;
1011  struct ast_flags opts = { 0, };
1012  struct ast_bridge_config bconfig = { { 0, }, };
1013  char *opt_args[OPT_ARG_ARRAY_SIZE];
1014  struct timeval calldurationlimit = { 0, };
1015  const char *context;
1016  const char *extension;
1017  int priority;
1018  int bridge_add_failed;
1019  int res = -1;
1020  struct ast_bridge_features chan_features;
1022  struct ast_bridge *bridge;
1023  struct ast_features_xfer_config *xfer_cfg;
1024 
1026  AST_APP_ARG(dest_chan);
1028  );
1029 
1030  tmp_data = ast_strdupa(data ?: "");
1031  AST_STANDARD_APP_ARGS(args, tmp_data);
1032  if (!ast_strlen_zero(args.options)) {
1033  ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
1034  }
1035 
1036  /* make sure we have a valid end point */
1037  if (!ast_strlen_zero(args.dest_chan)) {
1038  current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
1039  strlen(args.dest_chan));
1040  }
1041  if (!current_dest_chan) {
1042  ast_verb(4, "Bridge failed because channel '%s' does not exist\n",
1043  args.dest_chan ?: "");
1044  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
1045  return 0;
1046  }
1047 
1048  /* avoid bridge with ourselves */
1049  if (chan == current_dest_chan) {
1050  ast_channel_unref(current_dest_chan);
1051  ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1052  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
1053  return 0;
1054  }
1055 
1056  if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
1058  && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1059  goto done;
1060  }
1061 
1062  if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
1064  if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
1066  if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1068  if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1070  if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
1072  if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
1074  if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1076  if (ast_test_flag(&opts, OPT_CALLER_PARK))
1078 
1079  /* Setup after bridge goto location. */
1080  if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1081  ast_channel_lock(chan);
1082  context = ast_strdupa(ast_channel_context(chan));
1083  extension = ast_strdupa(ast_channel_exten(chan));
1084  priority = ast_channel_priority(chan);
1085  ast_channel_unlock(chan);
1086  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority,
1087  opt_args[OPT_ARG_CALLEE_GO_ON]);
1088  } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1089  ast_channel_lock(current_dest_chan);
1090  context = ast_strdupa(ast_channel_context(current_dest_chan));
1091  extension = ast_strdupa(ast_channel_exten(current_dest_chan));
1092  priority = ast_channel_priority(current_dest_chan);
1093  ast_channel_unlock(current_dest_chan);
1094  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority, NULL);
1095  }
1096 
1097  if (ast_bridge_features_init(&chan_features)) {
1098  ast_bridge_features_cleanup(&chan_features);
1099  goto done;
1100  }
1101 
1102  peer_features = ast_bridge_features_new();
1103  if (!peer_features) {
1104  ast_bridge_features_cleanup(&chan_features);
1105  goto done;
1106  }
1107 
1108  if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features)) {
1109  ast_bridge_features_destroy(peer_features);
1110  ast_bridge_features_cleanup(&chan_features);
1111  goto done;
1112  }
1113 
1114  bridge = ast_bridge_basic_new();
1115  if (!bridge) {
1116  ast_bridge_features_destroy(peer_features);
1117  ast_bridge_features_cleanup(&chan_features);
1118  goto done;
1119  }
1120 
1121  ast_channel_lock(current_dest_chan);
1122  xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1123  ast_channel_unlock(current_dest_chan);
1124  bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
1126  xfer_cfg ? xfer_cfg->xfersound : NULL);
1127  ao2_cleanup(xfer_cfg);
1128  if (bridge_add_failed) {
1129  ast_bridge_features_cleanup(&chan_features);
1130  ast_bridge_destroy(bridge, 0);
1131  goto done;
1132  }
1133 
1134  /* Don't keep the channel ref in case it was not already in a bridge. */
1135  current_dest_chan = ast_channel_unref(current_dest_chan);
1136 
1137  res = ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
1139 
1140  ast_bridge_features_cleanup(&chan_features);
1141 
1142 done:
1143  if (res == -1) {
1144  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
1145  } else {
1146  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
1147  }
1148 
1149  ast_free((char *) bconfig.warning_sound);
1150  ast_free((char *) bconfig.end_sound);
1151  ast_free((char *) bconfig.start_sound);
1152 
1153  ast_channel_cleanup(current_dest_chan);
1154  return 0;
1155 }
1156 
1157 static int unload_module(void)
1158 {
1160 
1161  ast_manager_unregister("Bridge");
1162 
1163  ast_unregister_application(app_bridge);
1164 
1165  return 0;
1166 }
1167 
1168 static int load_module(void)
1169 {
1170  int res;
1171 
1172  res = load_features_config();
1173  res |= ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
1175 
1177 }
1178 
1180  .support_level = AST_MODULE_SUPPORT_CORE,
1181  .load = load_module,
1182  .unload = unload_module,
1184  .load_pri = AST_MODPRI_CORE,
1185  .requires = "extconfig",
1186 );
static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
Definition: features.c:437
const char * type
Definition: datastore.h:32
struct ast_flags peer_features
Definition: features.c:259
#define ast_channel_lock(chan)
Definition: channel.h:2902
static void * dial_features_duplicate(void *data)
Definition: features.c:262
Main Channel structure associated with a channel.
static const struct ast_datastore_info dial_features_info
Definition: features.c:275
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
Music on hold handling.
feature_interpret_op
Definition: features.c:249
Feature configuration relating to transfers.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:486
struct ast_channel * peer
Definition: features.c:330
int load_features_config(void)
struct ast_cdr * ast_channel_cdr(const struct ast_channel *chan)
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_channel * chan
Definition: features.c:329
struct ast_flags features_callee
Definition: channel.h:1079
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:3475
int ast_max_forwards_reset(struct ast_channel *chan)
Reset the max forwards on a channel to its starting value.
Definition: max_forwards.c:151
char * config
Definition: conf2ael.c:66
struct ao2_container * ast_get_chan_applicationmap(struct ast_channel *chan)
Get the applicationmap for a given channel.
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
Definition: features.c:1007
struct ast_stream_topology * answer_topology
Definition: channel.h:1100
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2938
#define ast_test_flag(p, flag)
Definition: utils.h:63
Device state management.
Support for translation of data formats. translate.c.
#define BEGIN_OPTIONS
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4291
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define SCOPE_TRACE(__level,...)
Definition: logger.h:888
static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
Definition: features.c:423
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
Audiohooks Architecture.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
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:2634
#define var
Definition: ast_expr2f.c:614
globally accessible channel datastores
struct ast_features_xfer_config * ast_get_chan_features_xfer_config(struct ast_channel *chan)
Get the transfer configuration options for a channel.
Test Framework API.
#define EVENT_FLAG_CALL
Definition: manager.h:72
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:970
play_tone_action
Definition: features.c:721
static void playtone(struct ast_channel *chan, int tone, int len)
struct ast_flags my_features
Definition: features.c:257
static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
Definition: features.c:334
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
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:2390
static int load_module(void)
Definition: features.c:1168
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
const char * args
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
int value
Definition: syslog.c:37
static enum play_tone_action parse_playtone(const char *playtone_val)
Definition: features.c:728
static int priority
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:633
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
int ast_channel_priority(const struct ast_channel *chan)
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3470
#define ast_verb(level,...)
Definition: logger.h:455
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
const char * ast_channel_linkedid(const struct ast_channel *chan)
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.
static const struct ast_app_option bridge_exec_options[128]
Definition: features.c:884
Media Stream API.
static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features)
Definition: features.c:536
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:1430
const char * start_sound
Definition: channel.h:1089
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
int done
Definition: test_amihooks.c:48
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:716
Configuration File Parser.
int reload_features_config(void)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
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:1924
General Asterisk PBX channel definitions.
const char * ast_channel_accountcode(const struct ast_channel *chan)
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:626
#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:851
static int unload_module(void)
Definition: features.c:1157
int ast_channel_macropriority(const struct ast_channel *chan)
int ast_channel_visible_indication(const struct ast_channel *chan)
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:1077
void * end_bridge_callback_data
Definition: channel.h:1092
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2949
structure to hold extensions
const char * end_sound
Definition: channel.h:1088
In case you didn&#39;t read that giant block of text above the mansession_session struct, the struct 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:1625
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:2341
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:2829
const char * ast_channel_exten(const struct ast_channel *chan)
Core PBX routines and definitions.
struct ast_flags features_caller
Definition: channel.h:1078
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
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:357
#define LOG_ERROR
Definition: logger.h:285
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: main/utils.c:1822
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:2519
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3459
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.
static char * app_bridge
Definition: features.c:844
struct ast_channel * ast_channel_masq(const struct ast_channel *chan)
#define LOG_NOTICE
Definition: logger.h:263
#define AST_FEATURE_DTMF_MASK
Definition: channel.h:1073
const char * ast_channel_appl(const struct ast_channel *chan)
#define ast_strlen_zero(a)
Definition: muted.c:73
const char * ast_channel_dialcontext(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2903
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int reload(void)
Definition: cdr_mysql.c:741
static int add_features_datastore(struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
Definition: features.c:291
#define AST_FLAGS_ALL
Definition: utils.h:196
Module could not be loaded properly.
Definition: module.h:102
Prototypes for public functions only of internal interest,.
void unload_features_config(void)
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:193
unsigned int inheritance
Definition: datastore.h:73
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:757
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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:1667
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
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...
const char * ast_channel_data(const struct ast_channel *chan)
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750
void(* end_bridge_callback)(void *)
Definition: channel.h:1091
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:886
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
void * data
Definition: datastore.h:70
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
char * strsep(char **str, const char *delims)
After Bridge Execution API.
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)
Definition: features.c:462
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:79
ast_app: A registered application
Definition: pbx_app.c:45
const char * ast_channel_name(const struct ast_channel *chan)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1839
#define END_OPTIONS
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
static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
Definition: features.c:383
const char * ast_channel_context(const struct ast_channel *chan)
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:636
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
const char * warning_sound
Definition: channel.h:1087
Generic container type.
static struct test_options options
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
void ast_channel_log(char *title, struct ast_channel *chan)
Definition: features.c:363
const char * ast_channel_macrocontext(const struct ast_channel *chan)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
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:3159
Asterisk module definitions.
unsigned int return_to_pbx
Definition: features.c:331
enum ama_flags ast_channel_amaflags(const struct ast_channel *chan)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2376
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_channel * ast_channel_masqr(const struct ast_channel *chan)
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447
const char * ast_channel_macroexten(const struct ast_channel *chan)
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:528
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:2339
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:514