ARI: Add ability to raise arbitrary User Events
[asterisk/asterisk.git] / main / mixmonitor.c
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 loadable MixMonitor functionality
22  *
23  * \author Jonathan Rose <jrose@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/lock.h"
35 #include "asterisk/logger.h"
36 #include "asterisk/mixmonitor.h"
37 #include "asterisk/utils.h"
38 #include "asterisk/channel.h"
39
40 AST_RWLOCK_DEFINE_STATIC(mixmonitor_lock);
41
42 static struct ast_mixmonitor_methods mixmonitor_methods;
43 static int table_loaded = 0;
44
45 int ast_set_mixmonitor_methods(struct ast_mixmonitor_methods *method_table)
46 {
47         SCOPED_WRLOCK(lock, &mixmonitor_lock);
48
49         if (table_loaded) {
50                 /* If mixmonitor methods have already been provided, reject the new set */
51                 ast_log(LOG_ERROR, "Tried to set mixmonitor methods, but something else has already provided them.\n");
52                 return -1;
53         }
54
55         mixmonitor_methods = *method_table;
56
57         table_loaded = 1;
58         return 0;
59 }
60
61 int ast_clear_mixmonitor_methods(void)
62 {
63         SCOPED_WRLOCK(lock, &mixmonitor_lock);
64
65         if (!table_loaded) {
66                 ast_log(LOG_ERROR, "Tried to clear mixmonitor methods, but none are currently loaded.\n");
67                 return -1;
68         }
69
70         memset(&mixmonitor_methods, 0, sizeof(mixmonitor_methods));
71
72         table_loaded = 0;
73         return 0;
74 }
75
76 int ast_start_mixmonitor(struct ast_channel *chan, const char *filename, const char *options)
77 {
78         SCOPED_RDLOCK(lock, &mixmonitor_lock);
79
80         if (!mixmonitor_methods.start) {
81                 ast_log(LOG_ERROR, "No loaded module currently provides MixMonitor starting functionality.\n");
82                 return -1;
83         }
84
85         return mixmonitor_methods.start(chan, filename, options);
86 }
87
88 int ast_stop_mixmonitor(struct ast_channel *chan, const char *mixmon_id)
89 {
90         SCOPED_RDLOCK(lock, &mixmonitor_lock);
91
92         if (!mixmonitor_methods.stop) {
93                 ast_log(LOG_ERROR, "No loaded module currently provides MixMonitor stopping functionality.\n");
94                 return -1;
95         }
96
97         return mixmonitor_methods.stop(chan, mixmon_id);
98 }