Asterisk - The Open Source Telephony Project GIT-master-a358458
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 <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="function">CDR_PROP</ref>
91 <ref type="application">ResetCDR</ref>
92 </see-also>
93 </application>
94 ***/
95
96static char *app = "ForkCDR";
97
103});
104
105STASIS_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 */
113};
114
115static 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
134static int forkcdr_exec(struct ast_channel *chan, const char *data)
135{
139
140 char *parse;
141 struct ast_flags flags = { 0, };
144 );
145
146 parse = ast_strdupa(data);
147
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
184static 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
196static 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) {
212
214 }
216}
217
218AST_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",
static const struct ast_app_option forkcdr_exec_options[128]
Definition: app_forkcdr.c:103
STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type)
static char * app
Definition: app_forkcdr.c:96
static int forkcdr_exec(struct ast_channel *chan, const char *data)
Definition: app_forkcdr.c:134
static int load_module(void)
Definition: app_forkcdr.c:196
static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: app_forkcdr.c:115
static int unload_module(void)
Definition: app_forkcdr.c:184
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:4356
@ 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:3699
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:3056
#define AST_LOG_WARNING
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition: module.h:315
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ 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:626
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:112
const char * channel_name
Definition: app_forkcdr.c:110
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