Asterisk - The Open Source Telephony Project  18.5.0
app_forkcdr.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Anthony Minessale [email protected]
5  * Development of this app Sponsered/Funded by TAAN Softworks Corp
6  *
7  * See http://www.asterisk.org for more information about
8  * the Asterisk project. Please do not directly contact
9  * any of the maintainers of this project for assistance;
10  * the project provides a web site, mailing lists and IRC
11  * channels for your use.
12  *
13  * This program is free software, distributed under the terms of
14  * the GNU General Public License Version 2. See the LICENSE file
15  * at the top of the source tree.
16  */
17 
18 /*! \file
19  *
20  * \brief Fork CDR application
21  *
22  * \author Anthony Minessale [email protected]
23  *
24  * \note Development of this app Sponsored/Funded by TAAN Softworks Corp
25  *
26  * \ingroup applications
27  */
28 
29 /*** MODULEINFO
30  <support_level>core</support_level>
31  ***/
32 
33 #include "asterisk.h"
34 
35 #include "asterisk/file.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/cdr.h"
39 #include "asterisk/app.h"
40 #include "asterisk/module.h"
41 #include "asterisk/stasis.h"
43 
44 /*** DOCUMENTATION
45  <application name="ForkCDR" language="en_US">
46  <synopsis>
47  Forks the current Call Data Record for this channel.
48  </synopsis>
49  <syntax>
50  <parameter name="options">
51  <optionlist>
52  <option name="a">
53  <para>If the channel is answered, set the answer time on
54  the forked CDR to the current time. If this option is
55  not used, the answer time on the forked CDR will be the
56  answer time on the original CDR. If the channel is not
57  answered, this option has no effect.</para>
58  <para>Note that this option is implicitly assumed if the
59  <literal>r</literal> option is used.</para>
60  </option>
61  <option name="e">
62  <para>End (finalize) the original CDR.</para>
63  </option>
64  <option name="r">
65  <para>Reset the start and answer times on the forked CDR.
66  This will set the start and answer times (if the channel
67  is answered) to be set to the current time.</para>
68  <para>Note that this option implicitly assumes the
69  <literal>a</literal> option.</para>
70  </option>
71  <option name="v">
72  <para>Do not copy CDR variables and attributes from the
73  original CDR to the forked CDR.</para>
74  <warning><para>This option has changed. Previously, the
75  variables were removed from the original CDR. This no
76  longer occurs - this option now controls whether or not
77  a forked CDR inherits the variables from the original
78  CDR.</para></warning>
79  </option>
80  </optionlist>
81  </parameter>
82  </syntax>
83  <description>
84  <para>Causes the Call Data Record engine to fork a new CDR starting
85  from the time the application is executed. The forked CDR will be
86  linked to the end of the CDRs associated with the channel.</para>
87  </description>
88  <see-also>
89  <ref type="function">CDR</ref>
90  <ref type="application">NoCDR</ref>
91  <ref type="application">ResetCDR</ref>
92  </see-also>
93  </application>
94  ***/
95 
96 static char *app = "ForkCDR";
97 
103 });
104 
105 STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type);
106 
107 /*! \internal \brief Message payload for the Stasis message sent to fork the CDR */
109  /*! The name of the channel whose CDR will be forked */
110  const char *channel_name;
111  /*! Option flags that control how the CDR will be forked */
112  struct ast_flags *flags;
113 };
114 
115 static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
116 {
117  struct fork_cdr_message_payload *payload;
118 
119  if (stasis_message_type(message) != forkcdr_message_type()) {
120  return;
121  }
122 
123  payload = stasis_message_data(message);
124  if (!payload) {
125  return;
126  }
127 
128  if (ast_cdr_fork(payload->channel_name, payload->flags)) {
129  ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s\n",
130  payload->channel_name);
131  }
132 }
133 
134 static int forkcdr_exec(struct ast_channel *chan, const char *data)
135 {
137  RAII_VAR(struct fork_cdr_message_payload *, payload, NULL, ao2_cleanup);
139 
140  char *parse;
141  struct ast_flags flags = { 0, };
144  );
145 
146  parse = ast_strdupa(data);
147 
148  AST_STANDARD_APP_ARGS(args, parse);
149 
150  if (!ast_strlen_zero(args.options)) {
152  }
153 
154  if (!forkcdr_message_type()) {
155  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message type\n",
156  ast_channel_name(chan));
157  return -1;
158  }
159 
160  payload = ao2_alloc(sizeof(*payload), NULL);
161  if (!payload) {
162  return -1;
163  }
164 
165  if (!router) {
166  ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
167  ast_channel_name(chan));
168  return -1;
169  }
170 
171  payload->channel_name = ast_channel_name(chan);
172  payload->flags = &flags;
173  message = stasis_message_create(forkcdr_message_type(), payload);
174  if (!message) {
175  ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s: unable to create message\n",
176  ast_channel_name(chan));
177  return -1;
178  }
180 
181  return 0;
182 }
183 
184 static int unload_module(void)
185 {
187 
188  if (router) {
189  stasis_message_router_remove(router, forkcdr_message_type());
190  }
191  STASIS_MESSAGE_TYPE_CLEANUP(forkcdr_message_type);
193  return 0;
194 }
195 
196 static int load_module(void)
197 {
199  int res = 0;
200 
201  if (!router) {
203  }
204 
205  res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
207  res |= stasis_message_router_add(router, forkcdr_message_type(),
209 
210  if (res) {
211  unload_module();
212 
214  }
216 }
217 
218 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Fork The CDR into 2 separate entities",
219  .support_level = AST_MODULE_SUPPORT_CORE,
220  .load = load_module,
221  .unload = unload_module,
222  .requires = "cdr",
223 );
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
static struct stasis_message_router * router
const char * channel_name
Definition: app_forkcdr.c:110
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
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition: cdr.c:3637
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
#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.
static char * app
Definition: app_forkcdr.c:96
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
const char * args
#define NULL
Definition: resample.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type)
Call Detail Record API.
#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
#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
Core PBX routines and definitions.
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.
static int unload_module(void)
Definition: app_forkcdr.c:184
static int load_module(void)
Definition: app_forkcdr.c:196
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const struct ast_app_option forkcdr_exec_options[128]
Definition: app_forkcdr.c:103
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct ast_flags * flags
Definition: app_forkcdr.c:112
Structure used to handle boolean flags.
Definition: utils.h:199
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",)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: app_forkcdr.c:115
struct stasis_forward * sub
Definition: res_corosync.c:240
static struct test_options options
#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 AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
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 forkcdr_exec(struct ast_channel *chan, const char *data)
Definition: app_forkcdr.c:134
#define AST_APP_ARG(name)
Define an application argument.