Asterisk - The Open Source Telephony Project  18.5.0
bridge_builtin_interval_features.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Jonathan Rose <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Built in bridging interval features
22  *
23  * \author Jonathan Rose <[email protected]>
24  *
25  * \ingroup bridges
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 
39 #include "asterisk/module.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/bridge.h"
42 #include "asterisk/file.h"
43 #include "asterisk/app.h"
44 #include "asterisk/astobj2.h"
45 #include "asterisk/test.h"
46 #include "asterisk/say.h"
47 #include "asterisk/stringfields.h"
48 #include "asterisk/musiconhold.h"
49 #include "asterisk/causes.h"
50 
51 static int bridge_features_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
52 {
53  struct ast_bridge_features_limits *limits = hook_pvt;
54 
55  if (!ast_strlen_zero(limits->duration_sound)) {
56  ast_stream_and_wait(bridge_channel->chan, limits->duration_sound, AST_DIGIT_NONE);
57  }
58 
61 
62  ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s",
63  ast_channel_name(bridge_channel->chan));
64  return -1;
65 }
66 
67 static void limits_interval_playback(struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, const char *file)
68 {
69  if (!strcasecmp(file, "timeleft")) {
70  unsigned int remaining = ast_tvdiff_ms(limits->quitting_time, ast_tvnow()) / 1000;
71  unsigned int min;
72  unsigned int sec;
73 
74  if (remaining <= 0) {
75  return;
76  }
77 
78  if ((remaining / 60) > 1) {
79  min = remaining / 60;
80  sec = remaining % 60;
81  } else {
82  min = 0;
83  sec = remaining;
84  }
85 
86  ast_stream_and_wait(bridge_channel->chan, "vm-youhave", AST_DIGIT_NONE);
87  if (min) {
88  ast_say_number(bridge_channel->chan, min, AST_DIGIT_NONE,
89  ast_channel_language(bridge_channel->chan), NULL);
90  ast_stream_and_wait(bridge_channel->chan, "queue-minutes", AST_DIGIT_NONE);
91  }
92  if (sec) {
93  ast_say_number(bridge_channel->chan, sec, AST_DIGIT_NONE,
94  ast_channel_language(bridge_channel->chan), NULL);
95  ast_stream_and_wait(bridge_channel->chan, "queue-seconds", AST_DIGIT_NONE);
96  }
97  } else {
98  ast_stream_and_wait(bridge_channel->chan, file, AST_DIGIT_NONE);
99  }
100 
101  /*
102  * It may be necessary to resume music on hold after we finish
103  * playing the announcment.
104  */
105  if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
106  const char *latest_musicclass;
107 
108  ast_channel_lock(bridge_channel->chan);
109  latest_musicclass = ast_strdupa(ast_channel_latest_musicclass(bridge_channel->chan));
110  ast_channel_unlock(bridge_channel->chan);
111  ast_moh_start(bridge_channel->chan, latest_musicclass, NULL);
112  }
113 }
114 
115 static int bridge_features_connect_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
116 {
117  struct ast_bridge_features_limits *limits = hook_pvt;
118 
119  limits_interval_playback(bridge_channel, limits, limits->connect_sound);
120  return -1;
121 }
122 
123 static int bridge_features_warning_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
124 {
125  struct ast_bridge_features_limits *limits = hook_pvt;
126 
127  limits_interval_playback(bridge_channel, limits, limits->warning_sound);
128  return limits->frequency ?: -1;
129 }
130 
132 {
133  ast_string_fields_copy(dst, src);
134  dst->quitting_time = src->quitting_time;
135  dst->duration = src->duration;
136  dst->warning = src->warning;
137  dst->frequency = src->frequency;
138 }
139 
140 static void bridge_features_limits_dtor(void *vdoomed)
141 {
142  struct ast_bridge_features_limits *doomed = vdoomed;
143 
146 }
147 
148 static int bridge_builtin_set_limits(struct ast_bridge_features *features,
150  enum ast_bridge_hook_remove_flags remove_flags)
151 {
152  RAII_VAR(struct ast_bridge_features_limits *, feature_limits, NULL, ao2_cleanup);
153 
154  if (!limits->duration) {
155  return -1;
156  }
157 
158  /* Create limits hook_pvt data. */
160  feature_limits = ao2_alloc_options(sizeof(*feature_limits),
162  if (!feature_limits) {
164  return -1;
165  }
166  if (ast_bridge_features_limits_construct(feature_limits)) {
167  return -1;
168  }
169  bridge_features_limits_copy(feature_limits, limits);
170  feature_limits->quitting_time = ast_tvadd(ast_tvnow(),
171  ast_samp2tv(feature_limits->duration, 1000));
172 
173  /* Install limit hooks. */
174  ao2_ref(feature_limits, +1);
176  feature_limits->duration,
177  bridge_features_duration_callback, feature_limits, __ao2_cleanup, remove_flags)) {
178  ast_log(LOG_ERROR, "Failed to schedule the duration limiter to the bridge channel.\n");
179  ao2_ref(feature_limits, -1);
180  return -1;
181  }
182  if (!ast_strlen_zero(feature_limits->connect_sound)) {
183  ao2_ref(feature_limits, +1);
185  bridge_features_connect_callback, feature_limits, __ao2_cleanup, remove_flags)) {
186  ast_log(LOG_WARNING, "Failed to schedule connect sound to the bridge channel.\n");
187  ao2_ref(feature_limits, -1);
188  }
189  }
190  if (feature_limits->warning && feature_limits->warning < feature_limits->duration) {
191  ao2_ref(feature_limits, +1);
193  feature_limits->duration - feature_limits->warning,
194  bridge_features_warning_callback, feature_limits, __ao2_cleanup, remove_flags)) {
195  ast_log(LOG_WARNING, "Failed to schedule warning sound playback to the bridge channel.\n");
196  ao2_ref(feature_limits, -1);
197  }
198  }
199 
200  return 0;
201 }
202 
203 static int unload_module(void)
204 {
206  return 0;
207 }
208 
209 static int load_module(void)
210 {
213 }
214 
215 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Built in bridging interval features");
#define ast_channel_lock(chan)
Definition: channel.h:2945
Music on hold handling.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
Structure that contains features information.
const ast_string_field duration_sound
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_bridge_hook_remove_flags
static int bridge_features_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
#define LOG_WARNING
Definition: logger.h:274
static void bridge_features_limits_dtor(void *vdoomed)
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
static void bridge_features_limits_copy(struct ast_bridge_features_limits *dst, struct ast_bridge_features_limits *src)
int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback)
Register a handler for a built in interval feature.
Definition: bridge.c:3168
Test Framework API.
static int unload_module(void)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define NULL
Definition: resample.c:96
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_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int bridge_features_warning_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
#define ast_log
Definition: astobj2.c:42
struct ast_module * self
Definition: module.h:342
const char * ast_channel_latest_musicclass(const struct ast_channel *chan)
General Asterisk PBX channel 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:911
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3382
int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval)
Definition: bridge.c:3180
static int bridge_features_connect_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static int load_module(void)
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
Definition: stringfields.h:627
#define LOG_ERROR
Definition: logger.h:285
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_DIGIT_NONE
Definition: file.h:47
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const ast_string_field warning_sound
static void limits_interval_playback(struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, const char *file)
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1814
const ast_string_field connect_sound
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
const char * ast_channel_name(const struct ast_channel *chan)
Internal Asterisk hangup causes.
const char * ast_channel_language(const struct ast_channel *chan)
static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
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.
Asterisk module definitions.
#define min(a, b)
Definition: f2c.h:197
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443