Asterisk - The Open Source Telephony Project  18.5.0
app_cdr.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Martin Pycko <[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 Applications connected with CDR engine
22  *
23  * \author Martin Pycko <[email protected]>
24  *
25  * \ingroup applications
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include "asterisk/channel.h"
35 #include "asterisk/module.h"
36 #include "asterisk/app.h"
37 #include "asterisk/stasis.h"
39 
40 /*** DOCUMENTATION
41  <application name="NoCDR" language="en_US">
42  <synopsis>
43  Tell Asterisk to not maintain a CDR for this channel.
44  </synopsis>
45  <syntax />
46  <description>
47  <para>This application will tell Asterisk not to maintain a CDR for
48  the current channel. This does <emphasis>NOT</emphasis> mean that
49  information is not tracked; rather, if the channel is hung up no
50  CDRs will be created for that channel.</para>
51  <para>If a subsequent call to ResetCDR occurs, all non-finalized
52  CDRs created for the channel will be enabled.</para>
53  <note><para>This application is deprecated. Please use the CDR_PROP
54  function to disable CDRs on a channel.</para></note>
55  </description>
56  <see-also>
57  <ref type="application">ResetCDR</ref>
58  <ref type="function">CDR_PROP</ref>
59  </see-also>
60  </application>
61  <application name="ResetCDR" language="en_US">
62  <synopsis>
63  Resets the Call Data Record.
64  </synopsis>
65  <syntax>
66  <parameter name="options">
67  <optionlist>
68  <option name="v">
69  <para>Save the CDR variables during the reset.</para>
70  </option>
71  <option name="e">
72  <para>Enable the CDRs for this channel only (negate
73  effects of NoCDR).</para>
74  </option>
75  </optionlist>
76  </parameter>
77  </syntax>
78  <description>
79  <para>This application causes the Call Data Record to be reset.
80  Depending on the flags passed in, this can have several effects.
81  With no options, a reset does the following:</para>
82  <para>1. The <literal>start</literal> time is set to the current time.</para>
83  <para>2. If the channel is answered, the <literal>answer</literal> time is set to the
84  current time.</para>
85  <para>3. All variables are wiped from the CDR. Note that this step
86  can be prevented with the <literal>v</literal> option.</para>
87  <para>On the other hand, if the <literal>e</literal> option is
88  specified, the effects of the NoCDR application will be lifted. CDRs
89  will be re-enabled for this channel.</para>
90  <note><para>The <literal>e</literal> option is deprecated. Please
91  use the CDR_PROP function instead.</para></note>
92  </description>
93  <see-also>
94  <ref type="application">ForkCDR</ref>
95  <ref type="application">NoCDR</ref>
96  <ref type="function">CDR_PROP</ref>
97  </see-also>
98  </application>
99  ***/
100 
101 static const char nocdr_app[] = "NoCDR";
102 static const char resetcdr_app[] = "ResetCDR";
103 
106  OPT_KEEP_VARS = (1 << 1),
107  OPT_ENABLE = (1 << 2),
108 };
109 
113 });
114 
115 STASIS_MESSAGE_TYPE_DEFN_LOCAL(appcdr_message_type);
116 
117 /*! \internal \brief Payload for the Stasis message sent to manipulate a CDR */
119  /*! The name of the channel to be manipulated */
120  const char *channel_name;
121  /*! Disable the CDR for this channel */
122  unsigned int disable:1;
123  /*! Re-enable the CDR for this channel */
124  unsigned int reenable:1;
125  /*! Reset the CDR */
126  unsigned int reset:1;
127  /*! If reseting the CDR, keep the variables */
128  unsigned int keep_variables:1;
129 };
130 
131 static void appcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
132 {
133  struct app_cdr_message_payload *payload;
134 
135  if (stasis_message_type(message) != appcdr_message_type()) {
136  return;
137  }
138 
139  payload = stasis_message_data(message);
140  if (!payload) {
141  return;
142  }
143 
144  if (payload->disable) {
146  ast_log(AST_LOG_WARNING, "Failed to disable CDRs on channel %s\n",
147  payload->channel_name);
148  }
149  }
150 
151  if (payload->reenable) {
153  ast_log(AST_LOG_WARNING, "Failed to enable CDRs on channel %s\n",
154  payload->channel_name);
155  }
156  }
157 
158  if (payload->reset) {
159  if (ast_cdr_reset(payload->channel_name, payload->keep_variables)) {
160  ast_log(AST_LOG_WARNING, "Failed to reset CDRs on channel %s\n",
161  payload->channel_name);
162  }
163  }
164 }
165 
166 static int publish_app_cdr_message(struct ast_channel *chan, struct app_cdr_message_payload *payload)
167 {
170 
171  if (!router) {
172  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
173  ast_channel_name(chan));
174  return -1;
175  }
176 
177  message = stasis_message_create(appcdr_message_type(), payload);
178  if (!message) {
179  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
180  payload->channel_name);
181  return -1;
182  }
184 
185  return 0;
186 }
187 
188 static int resetcdr_exec(struct ast_channel *chan, const char *data)
189 {
190  RAII_VAR(struct app_cdr_message_payload *, payload,
191  ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
192  char *args;
193  struct ast_flags flags = { 0 };
194 
195  if (!payload) {
196  return -1;
197  }
198 
199  if (!ast_strlen_zero(data)) {
200  args = ast_strdupa(data);
201  ast_app_parse_options(resetcdr_opts, &flags, NULL, args);
202  }
203 
204  payload->channel_name = ast_channel_name(chan);
205  payload->reset = 1;
206 
208  payload->reenable = 1;
209  }
210 
211  if (ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
212  payload->keep_variables = 1;
213  }
214 
215  return publish_app_cdr_message(chan, payload);
216 }
217 
218 static int nocdr_exec(struct ast_channel *chan, const char *data)
219 {
220  RAII_VAR(struct app_cdr_message_payload *, payload,
221  ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
222 
223  if (!payload) {
224  return -1;
225  }
226 
227  payload->channel_name = ast_channel_name(chan);
228  payload->disable = 1;
229 
230  return publish_app_cdr_message(chan, payload);
231 }
232 
233 static int unload_module(void)
234 {
236 
237  if (router) {
238  stasis_message_router_remove(router, appcdr_message_type());
239  }
240  STASIS_MESSAGE_TYPE_CLEANUP(appcdr_message_type);
243  return 0;
244 }
245 
246 static int load_module(void)
247 {
249  int res = 0;
250 
251  if (!router) {
253  }
254 
255  res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type);
258  res |= stasis_message_router_add(router, appcdr_message_type(),
260 
261  if (res) {
262  unload_module();
264  }
266 }
267 
268 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Tell Asterisk to not maintain a CDR for the current call");
Main Channel structure associated with a channel.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
static int resetcdr_exec(struct ast_channel *chan, const char *data)
Definition: app_cdr.c:188
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct stasis_message_router * router
unsigned int reenable
Definition: app_cdr.c:124
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
static void appcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: app_cdr.c:131
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router&#39;s subscription synchronously.
#define AST_LOG_WARNING
Definition: logger.h:279
STASIS_MESSAGE_TYPE_DEFN_LOCAL(appcdr_message_type)
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
const char * channel_name
Definition: app_cdr.c:120
const char * args
#define NULL
Definition: resample.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
reset_cdr_options
Definition: app_cdr.c:104
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
static int unload_module(void)
Definition: app_cdr.c:233
unsigned int keep_variables
Definition: app_cdr.c:128
#define ast_log
Definition: astobj2.c:42
struct stasis_message_router * ast_cdr_message_router(void)
Return the message router for the CDR engine.
Definition: cdr.c:4291
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
unsigned int reset
Definition: app_cdr.c:126
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3598
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2906
static const char nocdr_app[]
Definition: app_cdr.c:101
static const char resetcdr_app[]
Definition: app_cdr.c:102
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
Definition: cdr.c:3548
static const struct ast_app_option resetcdr_opts[128]
Definition: app_cdr.c:113
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
unsigned int disable
Definition: app_cdr.c:122
void stasis_message_router_remove(struct stasis_message_router *router, struct stasis_message_type *message_type)
Remove a route from a message router.
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Structure used to handle boolean flags.
Definition: utils.h:199
static int nocdr_exec(struct ast_channel *chan, const char *data)
Definition: app_cdr.c:218
static int publish_app_cdr_message(struct ast_channel *chan, struct app_cdr_message_payload *payload)
Definition: app_cdr.c:166
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
struct stasis_forward * sub
Definition: res_corosync.c:240
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
Clear a property on a CDR for a channel.
Definition: cdr.c:3575
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
static int load_module(void)
Definition: app_cdr.c:246