merge new_loader_completion branch, including (at least):
[asterisk/asterisk.git] / cdr / cdr_manager.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2004 - 2005
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Asterisk Call Manager CDR records.
20  * 
21  * See also
22  * \arg \ref AstCDR
23  * \arg \ref AstAMI
24  * \arg \ref Config_ami
25  * \ingroup cdr_drivers
26  */
27
28 #include "asterisk.h"
29
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31
32 #include <sys/types.h>
33 #include <strings.h>
34 #include <unistd.h>
35 #include <time.h>
36
37 #include "asterisk/channel.h"
38 #include "asterisk/cdr.h"
39 #include "asterisk/module.h"
40 #include "asterisk/logger.h"
41 #include "asterisk/utils.h"
42 #include "asterisk/manager.h"
43 #include "asterisk/config.h"
44
45 #define DATE_FORMAT     "%Y-%m-%d %T"
46 #define CONF_FILE       "cdr_manager.conf"
47
48 static char *name = "cdr_manager";
49
50 static int enablecdr = 0;
51
52 static void loadconfigurationfile(void)
53 {
54         char *cat;
55         struct ast_config *cfg;
56         struct ast_variable *v;
57         
58         cfg = ast_config_load(CONF_FILE);
59         if (!cfg) {
60                 /* Standard configuration */
61                 enablecdr = 0;
62                 return;
63         }
64         
65         cat = ast_category_browse(cfg, NULL);
66         while (cat) {
67                 if (!strcasecmp(cat, "general")) {
68                         v = ast_variable_browse(cfg, cat);
69                         while (v) {
70                                 if (!strcasecmp(v->name, "enabled")) {
71                                         enablecdr = ast_true(v->value);
72                                 }
73                                 
74                                 v = v->next;
75                         }
76                 }
77         
78                 /* Next category */
79                 cat = ast_category_browse(cfg, cat);
80         }
81         
82         ast_config_destroy(cfg);
83 }
84
85 static int manager_log(struct ast_cdr *cdr)
86 {
87         time_t t;
88         struct tm timeresult;
89         char strStartTime[80] = "";
90         char strAnswerTime[80] = "";
91         char strEndTime[80] = "";
92         
93         if (!enablecdr)
94                 return 0;
95
96         t = cdr->start.tv_sec;
97         localtime_r(&t, &timeresult);
98         strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
99         
100         if (cdr->answer.tv_sec) {
101                 t = cdr->answer.tv_sec;
102                 localtime_r(&t, &timeresult);
103                 strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
104         }
105
106         t = cdr->end.tv_sec;
107         localtime_r(&t, &timeresult);
108         strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
109
110         manager_event(EVENT_FLAG_CALL, "Cdr",
111             "AccountCode: %s\r\n"
112             "Source: %s\r\n"
113             "Destination: %s\r\n"
114             "DestinationContext: %s\r\n"
115             "CallerID: %s\r\n"
116             "Channel: %s\r\n"
117             "DestinationChannel: %s\r\n"
118             "LastApplication: %s\r\n"
119             "LastData: %s\r\n"
120             "StartTime: %s\r\n"
121             "AnswerTime: %s\r\n"
122             "EndTime: %s\r\n"
123             "Duration: %ld\r\n"
124             "BillableSeconds: %ld\r\n"
125             "Disposition: %s\r\n"
126             "AMAFlags: %s\r\n"
127             "UniqueID: %s\r\n"
128             "UserField: %s\r\n",
129             cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
130             cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
131             cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), 
132             ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield);
133                 
134         return 0;
135 }
136
137 static int unload_module(void)
138 {
139         ast_cdr_unregister(name);
140         return 0;
141 }
142
143 static int load_module(void)
144 {
145         int res;
146
147         /* Configuration file */
148         loadconfigurationfile();
149         
150         res = ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
151         if (res) {
152                 ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CDR handling\n");
153         }
154         
155         return res;
156 }
157
158 static int reload(void)
159 {
160         loadconfigurationfile();
161         return 0;
162 }
163
164 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Manager Interface CDR Backend",
165                 .load = load_module,
166                 .unload = unload_module,
167                 .reload = reload,
168                );