minor simplification of a conditional statement
[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 #include "asterisk/pbx.h"
45
46 #define DATE_FORMAT     "%Y-%m-%d %T"
47 #define CONF_FILE       "cdr_manager.conf"
48 #define CUSTOM_FIELDS_BUF_SIZE 1024
49
50 static char *name = "cdr_manager";
51
52 static int enablecdr = 0;
53 struct ast_str *customfields;
54
55 static int load_config(void)
56 {
57         char *cat = NULL;
58         struct ast_config *cfg;
59         struct ast_variable *v;
60         
61         customfields = NULL;
62
63         cfg = ast_config_load(CONF_FILE);
64         if (!cfg) {
65                 /* Standard configuration */
66                 ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
67                 enablecdr = 0;
68                 return 0;
69         }
70         
71         while ( (cat = ast_category_browse(cfg, cat)) ) {
72                 if (!strcasecmp(cat, "general")) {
73                         v = ast_variable_browse(cfg, cat);
74                         while (v) {
75                                 if (!strcasecmp(v->name, "enabled")) {
76                                         enablecdr = ast_true(v->value);
77                                 }
78                                 
79                                 v = v->next;
80                         }
81                 } else if (!strcasecmp(cat, "mappings")) {
82                         customfields = ast_str_create(CUSTOM_FIELDS_BUF_SIZE);
83                         v = ast_variable_browse(cfg, cat);
84                         while (v) {
85                                 if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) {
86                                         if( (customfields->used + strlen(v->value) + strlen(v->name) + 14) < customfields->len) {
87                                                 ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name);
88                                                 ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name);
89                                         } else {
90                                                 ast_log(LOG_WARNING, "No more buffer space to add other custom fields\n");
91                                                 break;
92                                         }
93                                         
94                                 }
95                                 v = v->next;
96                         }
97                 }
98         }
99         
100         ast_config_destroy(cfg);
101         return 1;
102 }
103
104 static int manager_log(struct ast_cdr *cdr)
105 {
106         struct ast_tm timeresult;
107         char strStartTime[80] = "";
108         char strAnswerTime[80] = "";
109         char strEndTime[80] = "";
110         char buf[CUSTOM_FIELDS_BUF_SIZE];
111         struct ast_channel dummy;
112
113         if (!enablecdr)
114                 return 0;
115
116         ast_localtime(&cdr->start, &timeresult, NULL);
117         ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
118         
119         if (cdr->answer.tv_sec) {
120                 ast_localtime(&cdr->answer, &timeresult, NULL);
121                 ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
122         }
123
124         ast_localtime(&cdr->end, &timeresult, NULL);
125         ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
126
127         /* Custom fields handling */
128         memset(buf, 0 , sizeof(buf));
129         if (customfields != NULL && customfields->used > 0) {
130                 memset(&dummy, 0, sizeof(dummy));
131                 dummy.cdr = cdr;
132                 pbx_substitute_variables_helper(&dummy, customfields->str, buf, sizeof(buf) - 1);
133         }
134
135         manager_event(EVENT_FLAG_CALL, "Cdr",
136             "AccountCode: %s\r\n"
137             "Source: %s\r\n"
138             "Destination: %s\r\n"
139             "DestinationContext: %s\r\n"
140             "CallerID: %s\r\n"
141             "Channel: %s\r\n"
142             "DestinationChannel: %s\r\n"
143             "LastApplication: %s\r\n"
144             "LastData: %s\r\n"
145             "StartTime: %s\r\n"
146             "AnswerTime: %s\r\n"
147             "EndTime: %s\r\n"
148             "Duration: %ld\r\n"
149             "BillableSeconds: %ld\r\n"
150             "Disposition: %s\r\n"
151             "AMAFlags: %s\r\n"
152             "UniqueID: %s\r\n"
153             "UserField: %s\r\n"
154             "%s",
155             cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
156             cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
157             cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
158             ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf);
159
160         return 0;
161 }
162
163 static int unload_module(void)
164 {
165         ast_cdr_unregister(name);
166         if (customfields)
167                 ast_free(customfields);
168
169         return 0;
170 }
171
172 static int load_module(void)
173 {
174         int res;
175
176         /* Configuration file */
177         if (!load_config())
178                 return AST_MODULE_LOAD_DECLINE;
179         
180         res = ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
181         if (res) {
182                 ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CDR handling\n");
183         }
184         
185         return res;
186 }
187
188 static int reload(void)
189 {
190         if (customfields) {
191                 ast_free(customfields);
192         }
193         
194         load_config();
195         return 0;
196 }
197
198 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Manager Interface CDR Backend",
199                 .load = load_module,
200                 .unload = unload_module,
201                 .reload = reload,
202                );