Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 anthmct@yahoo.com
5 * Development of this app Sponsored/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 anthmct@yahoo.com
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 <since>
47 <version>1.6.1.0</version>
48 </since>
49 <synopsis>
50 Forks the current Call Data Record for this channel.
51 </synopsis>
52 <syntax>
53 <parameter name="options">
54 <optionlist>
55 <option name="a">
56 <para>If the channel is answered, set the answer time on
57 the forked CDR to the current time. If this option is
58 not used, the answer time on the forked CDR will be the
59 answer time on the original CDR. If the channel is not
60 answered, this option has no effect.</para>
61 <para>Note that this option is implicitly assumed if the
62 <literal>r</literal> option is used.</para>
63 </option>
64 <option name="e">
65 <para>End (finalize) the original CDR.</para>
66 </option>
67 <option name="r">
68 <para>Reset the start and answer times on the forked CDR.
69 This will set the start and answer times (if the channel
70 is answered) to be set to the current time.</para>
71 <para>Note that this option implicitly assumes the
72 <literal>a</literal> option.</para>
73 </option>
74 <option name="v">
75 <para>Do not copy CDR variables and attributes from the
76 original CDR to the forked CDR.</para>
77 <warning><para>This option has changed. Previously, the
78 variables were removed from the original CDR. This no
79 longer occurs - this option now controls whether or not
80 a forked CDR inherits the variables from the original
81 CDR.</para></warning>
82 </option>
83 </optionlist>
84 </parameter>
85 </syntax>
86 <description>
87 <para>Causes the Call Data Record engine to fork a new CDR starting
88 from the time the application is executed. The forked CDR will be
89 linked to the end of the CDRs associated with the channel.</para>
90 </description>
91 <see-also>
92 <ref type="function">CDR</ref>
93 <ref type="function">CDR_PROP</ref>
94 <ref type="application">ResetCDR</ref>
95 </see-also>
96 </application>
97 ***/
98
99static char *app = "ForkCDR";
100
106});
107
108STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type);
109
110/*! \internal \brief Message payload for the Stasis message sent to fork the CDR */
112 /*! The name of the channel whose CDR will be forked */
113 const char *channel_name;
114 /*! Option flags that control how the CDR will be forked */
116};
117
118static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
119{
120 struct fork_cdr_message_payload *payload;
121
122 if (stasis_message_type(message) != forkcdr_message_type()) {
123 return;
124 }
125
126 payload = stasis_message_data(message);
127 if (!payload) {
128 return;
129 }
130
131 if (ast_cdr_fork(payload->channel_name, payload->flags)) {
132 ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s\n",
133 payload->channel_name);
134 }
135}
136
137static int forkcdr_exec(struct ast_channel *chan, const char *data)
138{
142
143 char *parse;
144 struct ast_flags flags = { 0, };
147 );
148
149 parse = ast_strdupa(data);
150
152
153 if (!ast_strlen_zero(args.options)) {
155 }
156
157 if (!forkcdr_message_type()) {
158 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message type\n",
159 ast_channel_name(chan));
160 return -1;
161 }
162
163 payload = ao2_alloc(sizeof(*payload), NULL);
164 if (!payload) {
165 return -1;
166 }
167
168 if (!router) {
169 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
170 ast_channel_name(chan));
171 return -1;
172 }
173
174 payload->channel_name = ast_channel_name(chan);
175 payload->flags = &flags;
176 message = stasis_message_create(forkcdr_message_type(), payload);
177 if (!message) {
178 ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s: unable to create message\n",
179 ast_channel_name(chan));
180 return -1;
181 }
183
184 return 0;
185}
186
187static int unload_module(void)
188{
190
191 if (router) {
192 stasis_message_router_remove(router, forkcdr_message_type());
193 }
194 STASIS_MESSAGE_TYPE_CLEANUP(forkcdr_message_type);
196 return 0;
197}
198
199static int load_module(void)
200{
202 int res = 0;
203
204 if (!router) {
206 }
207
208 res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
210 res |= stasis_message_router_add(router, forkcdr_message_type(),
212
213 if (res) {
215
217 }
219}
220
221AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Fork The CDR into 2 separate entities",
222 .support_level = AST_MODULE_SUPPORT_CORE,
223 .load = load_module,
224 .unload = unload_module,
225 .requires = "cdr",
static const struct ast_app_option forkcdr_exec_options[128]
Definition: app_forkcdr.c:106
STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type)
static char * app
Definition: app_forkcdr.c:99
static int forkcdr_exec(struct ast_channel *chan, const char *data)
Definition: app_forkcdr.c:137
static int load_module(void)
Definition: app_forkcdr.c:199
static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: app_forkcdr.c:118
static int unload_module(void)
Definition: app_forkcdr.c:187
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
Call Detail Record API.
struct stasis_message_router * ast_cdr_message_router(void)
Return the message router for the CDR engine.
Definition: cdr.c:4427
@ AST_CDR_FLAG_FINALIZE
Definition: cdr.h:247
@ AST_CDR_FLAG_KEEP_VARS
Definition: cdr.h:243
@ AST_CDR_FLAG_RESET
Definition: cdr.h:249
@ AST_CDR_FLAG_SET_ANSWER
Definition: cdr.h:248
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition: cdr.c:3770
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
Generic File Format Support. Should be included by clients of the file handling routines....
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
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
#define AST_LOG_WARNING
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition: module.h:329
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
Core PBX routines and definitions.
static struct stasis_message_router * router
struct stasis_forward * sub
Definition: res_corosync.c:240
#define NULL
Definition: resample.c:96
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
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.
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.
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.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
struct ast_flags * flags
Definition: app_forkcdr.c:115
const char * channel_name
Definition: app_forkcdr.c:113
const char * args
static struct test_options options
#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