123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #include "asterisk.h"
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- #include "asterisk/file.h"
- #include "asterisk/channel.h"
- #include "asterisk/pbx.h"
- #include "asterisk/cdr.h"
- #include "asterisk/app.h"
- #include "asterisk/module.h"
- #include "asterisk/stasis.h"
- #include "asterisk/stasis_message_router.h"
- static char *app = "ForkCDR";
- AST_APP_OPTIONS(forkcdr_exec_options, {
- AST_APP_OPTION('a', AST_CDR_FLAG_SET_ANSWER),
- AST_APP_OPTION('e', AST_CDR_FLAG_FINALIZE),
- AST_APP_OPTION('r', AST_CDR_FLAG_RESET),
- AST_APP_OPTION('v', AST_CDR_FLAG_KEEP_VARS),
- });
- STASIS_MESSAGE_TYPE_DEFN_LOCAL(forkcdr_message_type);
- struct fork_cdr_message_payload {
-
- const char *channel_name;
-
- struct ast_flags *flags;
- };
- static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
- {
- struct fork_cdr_message_payload *payload;
- if (stasis_message_type(message) != forkcdr_message_type()) {
- return;
- }
- payload = stasis_message_data(message);
- if (!payload) {
- return;
- }
- if (ast_cdr_fork(payload->channel_name, payload->flags)) {
- ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s\n",
- payload->channel_name);
- }
- }
- static int forkcdr_exec(struct ast_channel *chan, const char *data)
- {
- RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
- RAII_VAR(struct fork_cdr_message_payload *, payload, ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
- RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
- char *parse;
- struct ast_flags flags = { 0, };
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(options);
- );
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
- if (!ast_strlen_zero(args.options)) {
- ast_app_parse_options(forkcdr_exec_options, &flags, NULL, args.options);
- }
- if (!payload) {
- return -1;
- }
- if (!router) {
- ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
- ast_channel_name(chan));
- return -1;
- }
- payload->channel_name = ast_channel_name(chan);
- payload->flags = &flags;
- message = stasis_message_create(forkcdr_message_type(), payload);
- if (!message) {
- ast_log(AST_LOG_WARNING, "Failed to fork CDR for channel %s: unable to create message\n",
- ast_channel_name(chan));
- return -1;
- }
- stasis_message_router_publish_sync(router, message);
- return 0;
- }
- static int unload_module(void)
- {
- RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
- if (router) {
- stasis_message_router_remove(router, forkcdr_message_type());
- }
- STASIS_MESSAGE_TYPE_CLEANUP(forkcdr_message_type);
- ast_unregister_application(app);
- return 0;
- }
- static int load_module(void)
- {
- RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
- int res = 0;
- if (!router) {
- return AST_MODULE_LOAD_FAILURE;
- }
- res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
- res |= ast_register_application_xml(app, forkcdr_exec);
- res |= stasis_message_router_add(router, forkcdr_message_type(),
- forkcdr_callback, NULL);
- if (res) {
- return AST_MODULE_LOAD_FAILURE;
- }
- return AST_MODULE_LOAD_SUCCESS;
- }
- AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Fork The CDR into 2 separate entities");
|