Asterisk - The Open Source Telephony Project  18.5.0
cel_manager.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008 - 2009, Digium, Inc.
5  *
6  * Steve Murphy <[email protected]>
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 = {
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 
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,
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) {
347  } else if (!enablecel && newenablecel) {
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 {
360  return 0;
361 }
362 
363 static int load_module(void)
364 {
365  if (load_config(0)) {
367  }
368 
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 );
const char * account_code
Definition: cel.h:161
struct ast_variable * next
const char * caller_id_name
Definition: cel.h:151
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:136
const char * linked_id
Definition: cel.h:164
An event.
Definition: event.c:81
static int reload(void)
Definition: cel_manager.c:372
Asterisk main include file. File version handling, generic pbx functions.
static int unload_module(void)
Definition: cel_manager.c:357
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
Call Event Logging API.
const char * user_defined_name
Definition: cel.h:150
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition: cel.c:1740
#define LOG_WARNING
Definition: logger.h:274
const char * application_data
Definition: cel.h:160
const char * application_name
Definition: cel.h:159
#define CONFIG_STATUS_FILEINVALID
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
Structure for variables, used for configurations and for channel variables.
const char * extension
Definition: cel.h:156
#define EVENT_FLAG_CALL
Definition: manager.h:72
Definition: astman.c:222
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
#define CEL_AMI_ENABLED_DEFAULT
AMI CEL is off by default.
Definition: cel_manager.c:211
static const char CONF_FILE[]
Definition: cel_manager.c:208
const char * caller_id_num
Definition: cel.h:152
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define CEL_SHOW_USERDEF_DEFAULT
show_user_def is off by default
Definition: cel_manager.c:216
const char * extra
Definition: cel.h:168
Utility functions.
Configuration File Parser.
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
static unsigned char cel_show_user_def
Definition: cel_manager.c:221
const char * context
Definition: cel.h:157
static void manager_log(struct ast_event *event)
Definition: cel_manager.c:223
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
uint32_t version
struct ABI version
Definition: cel.h:146
static int load_module(void)
Definition: cel_manager.c:363
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1728
#define CONFIG_STATUS_FILEUNCHANGED
enum ast_cel_event_type event_type
Definition: cel.h:147
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
static int load_config(int reload)
Definition: cel_manager.c:300
#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:1951
static int enablecel
Definition: cel_manager.c:213
const char * caller_id_rdnis
Definition: cel.h:154
const char * peer
Definition: cel.h:167
#define LOG_NOTICE
Definition: logger.h:263
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
const char * caller_id_ani
Definition: cel.h:153
const char * user_field
Definition: cel.h:166
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:141
Structure used to handle boolean flags.
Definition: utils.h:199
Support for logging to various files, console and syslog Configuration in file logger.conf.
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",)
const char * peer_account
Definition: cel.h:162
static const char DATE_FORMAT[]
Definition: cel_manager.c:206
const char * unique_id
Definition: cel.h:163
a user-defined event, the event name field should be set
Definition: cel.h:69
const char * caller_id_dnid
Definition: cel.h:155
const char * channel_name
Definition: cel.h:158
const char * event_name
Definition: cel.h:149
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
Asterisk module definitions.
struct timeval event_time
Definition: cel.h:148
#define MANAGER_BACKEND_NAME
Definition: cel_manager.c:218
int ast_cel_fill_record(const struct ast_event *event, struct ast_cel_event_record *r)
Fill in an ast_cel_event_record from a CEL event.
Definition: cel.c:819