Asterisk - The Open Source Telephony Project GIT-master-a358458
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 <jrose@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Built in bridging interval features
22 *
23 * \author Jonathan Rose <jrose@digium.com>
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"
49#include "asterisk/causes.h"
50
51static 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
67static 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 {
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
115static 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
123static 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
140static void bridge_features_limits_dtor(void *vdoomed)
141{
142 struct ast_bridge_features_limits *doomed = vdoomed;
143
146}
147
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
203static int unload_module(void)
204{
206 return 0;
207}
208
209static int load_module(void)
210{
213}
214
215AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Built in bridging interval features");
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
Bridging API.
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)
static void bridge_features_limits_copy(struct ast_bridge_features_limits *dst, struct ast_bridge_features_limits *src)
static int bridge_features_warning_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static int bridge_features_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static int bridge_features_connect_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static void limits_interval_playback(struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, const char *file)
static void bridge_features_limits_dtor(void *vdoomed)
static int load_module(void)
static int unload_module(void)
@ BRIDGE_CHANNEL_STATE_END
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).
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3396
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:3319
ast_bridge_hook_remove_flags
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:3107
int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval)
Unregisters a handler for a built in interval feature.
Definition: bridge.c:3119
@ AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3407
@ AST_BRIDGE_BUILTIN_INTERVAL_LIMITS
Internal Asterisk hangup causes.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_latest_musicclass(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
@ AST_FLAG_MOH
Definition: channel.h:991
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define min(a, b)
Definition: f2c.h:197
Generic File Format Support. Should be included by clients of the file handling routines....
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:1878
#define AST_DIGIT_NONE
Definition: file.h:47
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define LOG_ERROR
#define LOG_WARNING
Asterisk module definitions.
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Music on hold handling.
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:7766
#define NULL
Definition: resample.c:96
Say numbers and dates (maybe words one day too)
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:8235
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
Definition: stringfields.h:630
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure that contains information regarding a channel in a bridge.
struct ast_channel * chan
Structure that contains configuration information for the limits feature.
Structure that contains features information.
struct ast_module * self
Definition: module.h:342
Test Framework API.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
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:282
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_test_flag(p, flag)
Definition: utils.h:63
#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