Use non-blocking socket() and pipe() wrappers
[asterisk/asterisk.git] / cel / cel_manager.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008 - 2009, Digium, Inc.
5  *
6  * Steve Murphy <murf@digium.com>
7  * who freely borrowed code from the cdr equivalents
8  *     (see cdr/cdr_manager.c)
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief Asterisk Channel Event records.
24  *
25  * See also
26  * \arg \ref AstCDR
27  * \arg \ref AstAMI
28  * \arg \ref Config_ami
29  * \ingroup cel_drivers
30  */
31
32 /*** MODULEINFO
33         <support_level>core</support_level>
34  ***/
35
36 /*** DOCUMENTATION
37         <managerEvent language="en_US" name="CEL">
38                 <managerEventInstance class="EVENT_FLAG_CEL">
39                         <synopsis>Raised when a Channel Event Log is generated for a channel.</synopsis>
40                         <syntax>
41                                 <parameter name="EventName">
42                                         <para>
43                                                 The name of the CEL event being raised. This can include
44                                                 both the system defined CEL events, as well as user defined
45                                                 events.
46                                         </para>
47                                         <note>
48                                                 <para>All events listed here may not be raised, depending
49                                                 on the configuration in <filename>cel.conf</filename>.</para>
50                                         </note>
51                                         <enumlist>
52                                                 <enum name="CHAN_START">
53                                                         <para>A channel was created.</para>
54                                                 </enum>
55                                                 <enum name="CHAN_END">
56                                                         <para>A channel was terminated.</para>
57                                                 </enum>
58                                                 <enum name="ANSWER">
59                                                         <para>A channel answered.</para>
60                                                 </enum>
61                                                 <enum name="HANGUP">
62                                                         <para>A channel was hung up.</para>
63                                                 </enum>
64                                                 <enum name="BRIDGE_ENTER">
65                                                         <para>A channel entered a bridge.</para>
66                                                 </enum>
67                                                 <enum name="BRIDGE_EXIT">
68                                                         <para>A channel left a bridge.</para>
69                                                 </enum>
70                                                 <enum name="APP_START">
71                                                         <para>A channel entered into a tracked application.</para>
72                                                 </enum>
73                                                 <enum name="APP_END">
74                                                         <para>A channel left a tracked application.</para>
75                                                 </enum>
76                                                 <enum name="PARK_START">
77                                                         <para>A channel was parked.</para>
78                                                 </enum>
79                                                 <enum name="PARK_END">
80                                                         <para>A channel was unparked.</para>
81                                                 </enum>
82                                                 <enum name="BLINDTRANSFER">
83                                                         <para>A channel initiated a blind transfer.</para>
84                                                 </enum>
85                                                 <enum name="ATTENDEDTRANSFER">
86                                                         <para>A channel initiated an attended transfer.</para>
87                                                 </enum>
88                                                 <enum name="PICKUP">
89                                                         <para>A channel initated a call pickup.</para>
90                                                 </enum>
91                                                 <enum name="FORWARD">
92                                                         <para>A channel is being forwarded to another destination.</para>
93                                                 </enum>
94                                                 <enum name="LINKEDID_END">
95                                                         <para>The linked ID associated with this channel is being retired.</para>
96                                                 </enum>
97                                                 <enum name="LOCAL_OPTIMIZE">
98                                                         <para>A Local channel optimization has occurred.</para>
99                                                 </enum>
100                                                 <enum name="USER_DEFINED">
101                                                         <para>A user defined type.</para>
102                                                         <note>
103                                                                 <para>
104                                                                         This event is only present if <literal>show_user_defined</literal>
105                                                                         in <filename>cel.conf</filename> is <literal>True</literal>. Otherwise,
106                                                                         the user defined event will be placed directly in the
107                                                                         <replaceable>EventName</replaceable> field.
108                                                                 </para>
109                                                         </note>
110                                                 </enum>
111                                         </enumlist>
112                                 </parameter>
113                                 <parameter name="AccountCode">
114                                         <para>The channel's account code.</para>
115                                 </parameter>
116                                 <parameter name="CallerIDnum">
117                                         <para>The Caller ID number.</para>
118                                 </parameter>
119                                 <parameter name="CallerIDname">
120                                         <para>The Caller ID name.</para>
121                                 </parameter>
122                                 <parameter name="CallerIDani">
123                                         <para>The Caller ID Automatic Number Identification.</para>
124                                 </parameter>
125                                 <parameter name="CallerIDrdnis">
126                                         <para>The Caller ID Redirected Dialed Number Identification Service.</para>
127                                 </parameter>
128                                 <parameter name="CallerIDdnid">
129                                         <para>The Caller ID Dialed Number Identifier.</para>
130                                 </parameter>
131                                 <parameter name="Exten">
132                                         <para>The dialplan extension the channel is currently executing in.</para>
133                                 </parameter>
134                                 <parameter name="Context">
135                                         <para>The dialplan context the channel is currently executing in.</para>
136                                 </parameter>
137                                 <parameter name="Application">
138                                         <para>The dialplan application the channel is currently executing.</para>
139                                 </parameter>
140                                 <parameter name="AppData">
141                                         <para>The arguments passed to the dialplan <replaceable>Application</replaceable>.</para>
142                                 </parameter>
143                                 <parameter name="EventTime">
144                                         <para>The time the CEL event occurred.</para>
145                                 </parameter>
146                                 <parameter name="AMAFlags">
147                                         <para>A flag that informs a billing system how to treat the CEL.</para>
148                                         <enumlist>
149                                                 <enum name="OMIT">
150                                                         <para>This event should be ignored.</para>
151                                                 </enum>
152                                                 <enum name="BILLING">
153                                                         <para>This event contains valid billing data.</para>
154                                                 </enum>
155                                                 <enum name="DOCUMENTATION">
156                                                         <para>This event is for documentation purposes.</para>
157                                                 </enum>
158                                         </enumlist>
159                                 </parameter>
160                                 <parameter name="UniqueID">
161                                         <para>The unique ID of the channel.</para>
162                                 </parameter>
163                                 <parameter name="LinkedID">
164                                         <para>The linked ID of the channel, which ties this event to other related channel's events.</para>
165                                 </parameter>
166                                 <parameter name="UserField">
167                                         <para>
168                                                 A user defined field set on a channel, containing arbitrary
169                                                 application specific data.
170                                         </para>
171                                 </parameter>
172                                 <parameter name="Peer">
173                                         <para>
174                                                 If this channel is in a bridge, the channel that it is in
175                                                 a bridge with.
176                                         </para>
177                                 </parameter>
178                                 <parameter name="PeerAccount">
179                                         <para>
180                                                 If this channel is in a bridge, the accountcode of the
181                                                 channel it is in a bridge with.
182                                         </para>
183                                 </parameter>
184                                 <parameter name="Extra">
185                                         <para>
186                                                 Some events will have event specific data that accompanies the CEL record.
187                                                 This extra data is JSON encoded, and is dependent on the event in
188                                                 question.
189                                         </para>
190                                 </parameter>
191                         </syntax>
192                 </managerEventInstance>
193         </managerEvent>
194  ***/
195
196 #include "asterisk.h"
197
198 #include "asterisk/channel.h"
199 #include "asterisk/cel.h"
200 #include "asterisk/module.h"
201 #include "asterisk/logger.h"
202 #include "asterisk/utils.h"
203 #include "asterisk/manager.h"
204 #include "asterisk/config.h"
205
206 static const char DATE_FORMAT[] = "%Y-%m-%d %T";
207
208 static const char CONF_FILE[] = "cel.conf";
209
210 /*! \brief AMI CEL is off by default */
211 #define CEL_AMI_ENABLED_DEFAULT         0
212
213 static int enablecel;
214
215 /*! \brief show_user_def is off by default */
216 #define CEL_SHOW_USERDEF_DEFAULT        0
217
218 #define MANAGER_BACKEND_NAME "Manager Event Logging"
219
220 /*! TRUE if we should set the EventName header to USER_DEFINED on user events. */
221 static unsigned char cel_show_user_def;
222
223 static void manager_log(struct ast_event *event)
224 {
225         struct ast_tm timeresult;
226         char start_time[80] = "";
227         char user_defined_header[160];
228         const char *event_name;
229         struct ast_cel_event_record record = {
230                 .version = AST_CEL_EVENT_RECORD_VERSION,
231         };
232
233         if (!enablecel) {
234                 return;
235         }
236
237         if (ast_cel_fill_record(event, &record)) {
238                 return;
239         }
240
241         ast_localtime(&record.event_time, &timeresult, NULL);
242         ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult);
243
244         event_name = record.event_name;
245         user_defined_header[0] = '\0';
246         if (record.event_type == AST_CEL_USER_DEFINED) {
247                 if (cel_show_user_def) {
248                         snprintf(user_defined_header, sizeof(user_defined_header),
249                                 "UserDefType: %s\r\n", record.user_defined_name);
250                 } else {
251                         event_name = record.user_defined_name;
252                 }
253         }
254
255         manager_event(EVENT_FLAG_CALL, "CEL",
256                 "EventName: %s\r\n"
257                 "AccountCode: %s\r\n"
258                 "CallerIDnum: %s\r\n"
259                 "CallerIDname: %s\r\n"
260                 "CallerIDani: %s\r\n"
261                 "CallerIDrdnis: %s\r\n"
262                 "CallerIDdnid: %s\r\n"
263                 "Exten: %s\r\n"
264                 "Context: %s\r\n"
265                 "Channel: %s\r\n"
266                 "Application: %s\r\n"
267                 "AppData: %s\r\n"
268                 "EventTime: %s\r\n"
269                 "AMAFlags: %s\r\n"
270                 "UniqueID: %s\r\n"
271                 "LinkedID: %s\r\n"
272                 "Userfield: %s\r\n"
273                 "Peer: %s\r\n"
274                 "PeerAccount: %s\r\n"
275                 "%s"
276                 "Extra: %s\r\n",
277                 event_name,
278                 record.account_code,
279                 record.caller_id_num,
280                 record.caller_id_name,
281                 record.caller_id_ani,
282                 record.caller_id_rdnis,
283                 record.caller_id_dnid,
284                 record.extension,
285                 record.context,
286                 record.channel_name,
287                 record.application_name,
288                 record.application_data,
289                 start_time,
290                 ast_channel_amaflags2string(record.amaflag),
291                 record.unique_id,
292                 record.linked_id,
293                 record.user_field,
294                 record.peer,
295                 record.peer_account,
296                 user_defined_header,
297                 record.extra);
298 }
299
300 static int load_config(int reload)
301 {
302         const char *cat = NULL;
303         struct ast_config *cfg;
304         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
305         struct ast_variable *v;
306         int newenablecel = CEL_AMI_ENABLED_DEFAULT;
307         int new_cel_show_user_def = CEL_SHOW_USERDEF_DEFAULT;
308
309         cfg = ast_config_load(CONF_FILE, config_flags);
310         if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
311                 return 0;
312         }
313
314         if (cfg == CONFIG_STATUS_FILEINVALID) {
315                 ast_log(LOG_WARNING, "Configuration file '%s' is invalid. CEL manager Module not activated.\n",
316                         CONF_FILE);
317                 enablecel = 0;
318                 return -1;
319         } else if (!cfg) {
320                 ast_log(LOG_WARNING, "Failed to load configuration file. CEL manager Module not activated.\n");
321                 enablecel = 0;
322                 return -1;
323         }
324
325         while ((cat = ast_category_browse(cfg, cat))) {
326                 if (strcasecmp(cat, "manager")) {
327                         continue;
328                 }
329
330                 for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
331                         if (!strcasecmp(v->name, "enabled")) {
332                                 newenablecel = ast_true(v->value) ? 1 : 0;
333                         } else if (!strcasecmp(v->name, "show_user_defined")) {
334                                 new_cel_show_user_def = ast_true(v->value) ? 1 : 0;
335                         } else {
336                                 ast_log(LOG_NOTICE, "Unknown option '%s' specified "
337                                                 "for cel_manager.\n", v->name);
338                         }
339                 }
340         }
341
342         ast_config_destroy(cfg);
343
344         cel_show_user_def = new_cel_show_user_def;
345         if (enablecel && !newenablecel) {
346                 ast_cel_backend_unregister(MANAGER_BACKEND_NAME);
347         } else if (!enablecel && newenablecel) {
348                 if (ast_cel_backend_register(MANAGER_BACKEND_NAME, manager_log)) {
349                         ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CEL handling\n");
350                 }
351         }
352         enablecel = newenablecel;
353
354         return 0;
355 }
356
357 static int unload_module(void)
358 {
359         ast_cel_backend_unregister(MANAGER_BACKEND_NAME);
360         return 0;
361 }
362
363 static int load_module(void)
364 {
365         if (load_config(0)) {
366                 return AST_MODULE_LOAD_DECLINE;
367         }
368
369         return AST_MODULE_LOAD_SUCCESS;
370 }
371
372 static int reload(void)
373 {
374         return load_config(1);
375 }
376
377 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Asterisk Manager Interface CEL Backend",
378         .support_level = AST_MODULE_SUPPORT_CORE,
379         .load = load_module,
380         .unload = unload_module,
381         .reload = reload,
382         .load_pri = AST_MODPRI_CDR_DRIVER,
383         .requires = "cel",
384 );