Asterisk - The Open Source Telephony Project  21.4.1
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 <martinp@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 Applications connected with CDR engine
22  *
23  * \author Martin Pycko <martinp@digium.com>
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"
38 #include "asterisk/stasis_message_router.h"
39 
40 /*** DOCUMENTATION
41  <application name="ResetCDR" language="en_US">
42  <synopsis>
43  Resets the Call Data Record.
44  </synopsis>
45  <syntax>
46  <parameter name="options">
47  <optionlist>
48  <option name="v">
49  <para>Save the CDR variables during the reset.</para>
50  </option>
51  </optionlist>
52  </parameter>
53  </syntax>
54  <description>
55  <para>This application causes the Call Data Record to be reset.
56  Depending on the flags passed in, this can have several effects.
57  With no options, a reset does the following:</para>
58  <para>1. The <literal>start</literal> time is set to the current time.</para>
59  <para>2. If the channel is answered, the <literal>answer</literal> time is set to the
60  current time.</para>
61  <para>3. All variables are wiped from the CDR. Note that this step
62  can be prevented with the <literal>v</literal> option.</para>
63  </description>
64  <see-also>
65  <ref type="application">ForkCDR</ref>
66  <ref type="function">CDR_PROP</ref>
67  </see-also>
68  </application>
69  ***/
70 
71 static const char resetcdr_app[] = "ResetCDR";
72 
73 enum reset_cdr_options {
74  OPT_DISABLE_DISPATCH = (1 << 0),
75  OPT_KEEP_VARS = (1 << 1),
76  OPT_ENABLE = (1 << 2),
77 };
78 
79 AST_APP_OPTIONS(resetcdr_opts, {
81 });
82 
83 STASIS_MESSAGE_TYPE_DEFN_LOCAL(appcdr_message_type);
84 
85 /*! \internal \brief Payload for the Stasis message sent to manipulate a CDR */
87  /*! The name of the channel to be manipulated */
88  const char *channel_name;
89  /*! Reset the CDR */
90  unsigned int reset:1;
91  /*! If reseting the CDR, keep the variables */
92  unsigned int keep_variables:1;
93 };
94 
95 static void appcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
96 {
97  struct app_cdr_message_payload *payload;
98 
99  if (stasis_message_type(message) != appcdr_message_type()) {
100  return;
101  }
102 
103  payload = stasis_message_data(message);
104  if (!payload) {
105  return;
106  }
107 
108  if (payload->reset) {
109  if (ast_cdr_reset(payload->channel_name, payload->keep_variables)) {
110  ast_log(AST_LOG_WARNING, "Failed to reset CDRs on channel %s\n", payload->channel_name);
111  }
112  }
113 }
114 
115 static int publish_app_cdr_message(struct ast_channel *chan, struct app_cdr_message_payload *payload)
116 {
117  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
118  RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
119 
120  if (!router) {
121  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
122  ast_channel_name(chan));
123  return -1;
124  }
125 
126  message = stasis_message_create(appcdr_message_type(), payload);
127  if (!message) {
128  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
129  payload->channel_name);
130  return -1;
131  }
132  stasis_message_router_publish_sync(router, message);
133 
134  return 0;
135 }
136 
137 static int resetcdr_exec(struct ast_channel *chan, const char *data)
138 {
139  RAII_VAR(struct app_cdr_message_payload *, payload,
140  ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
141  char *args;
142  struct ast_flags flags = { 0 };
143 
144  if (!payload) {
145  return -1;
146  }
147 
148  if (!ast_strlen_zero(data)) {
149  args = ast_strdupa(data);
150  ast_app_parse_options(resetcdr_opts, &flags, NULL, args);
151  }
152 
153  payload->channel_name = ast_channel_name(chan);
154  payload->reset = 1;
155 
156  if (ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
157  payload->keep_variables = 1;
158  }
159 
160  return publish_app_cdr_message(chan, payload);
161 }
162 
163 static int unload_module(void)
164 {
165  RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
166 
167  if (router) {
168  stasis_message_router_remove(router, appcdr_message_type());
169  }
170  STASIS_MESSAGE_TYPE_CLEANUP(appcdr_message_type);
171  ast_unregister_application(resetcdr_app);
172  return 0;
173 }
174 
175 static int load_module(void)
176 {
177  RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
178  int res = 0;
179 
180  if (!router) {
182  }
183 
184  res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type);
185  res |= ast_register_application_xml(resetcdr_app, resetcdr_exec);
186  res |= stasis_message_router_add(router, appcdr_message_type(), appcdr_callback, NULL);
187 
188  if (res) {
189  unload_module();
191  }
193 }
194 
195 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.
Asterisk main include file. File version handling, generic pbx functions.
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:1493
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
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:88
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
unsigned int keep_variables
Definition: app_cdr.c:92
struct stasis_message_router * ast_cdr_message_router(void)
Return the message router for the CDR engine.
Definition: cdr.c:4356
General Asterisk PBX channel definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
unsigned int reset
Definition: app_cdr.c:90
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3660
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:3066
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.
void stasis_message_router_remove(struct stasis_message_router *router, struct stasis_message_type *message_type)
Remove a route from a message router.
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
STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type)
A message type used to synchronize with the CDR topic.
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router's subscription synchronously.
#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.
#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
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:640