Asterisk - The Open Source Telephony Project GIT-master-3dae2cf
Macros | Functions | Variables
cdr_beanstalkd.c File Reference

Asterisk Beanstalkd CDR records. More...

#include "asterisk.h"
#include <time.h>
#include <stdio.h>
#include "beanstalk.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/pbx.h"
#include "asterisk/json.h"
Include dependency graph for cdr_beanstalkd.c:

Go to the source code of this file.

Macros

#define BEANSTALK_JOB_DELAY   0
 
#define BEANSTALK_JOB_PRIORITY   99
 
#define BEANSTALK_JOB_SIZE   4096
 
#define BEANSTALK_JOB_TTR   60
 
#define CONF_FILE   "cdr_beanstalkd.conf"
 
#define DATE_FORMAT   "%Y-%m-%d %T"
 
#define DEFAULT_BEANSTALK_HOST   "127.0.0.1"
 
#define DEFAULT_BEANSTALK_PORT   11300
 
#define DEFAULT_BEANSTALK_TUBE   "asterisk-cdr"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int beanstalk_put (struct ast_cdr *cdr)
 
static int load_config (int reload)
 
static int load_module (void)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Beanstalkd CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static char * bs_host
 
static int bs_port
 
static char * bs_tube
 
static ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static int enablecdr = 0
 
static const char name [] = "cdr_beanstalkd"
 
static int priority
 

Detailed Description

Asterisk Beanstalkd CDR records.

This module requires the beanstalk-client library, avaialble from https://github.com/deepfryed/beanstalk-client

See also

Definition in file cdr_beanstalkd.c.

Macro Definition Documentation

◆ BEANSTALK_JOB_DELAY

#define BEANSTALK_JOB_DELAY   0

Definition at line 65 of file cdr_beanstalkd.c.

◆ BEANSTALK_JOB_PRIORITY

#define BEANSTALK_JOB_PRIORITY   99

Definition at line 63 of file cdr_beanstalkd.c.

◆ BEANSTALK_JOB_SIZE

#define BEANSTALK_JOB_SIZE   4096

Definition at line 62 of file cdr_beanstalkd.c.

◆ BEANSTALK_JOB_TTR

#define BEANSTALK_JOB_TTR   60

Definition at line 64 of file cdr_beanstalkd.c.

◆ CONF_FILE

#define CONF_FILE   "cdr_beanstalkd.conf"

Definition at line 61 of file cdr_beanstalkd.c.

◆ DATE_FORMAT

#define DATE_FORMAT   "%Y-%m-%d %T"

Definition at line 60 of file cdr_beanstalkd.c.

◆ DEFAULT_BEANSTALK_HOST

#define DEFAULT_BEANSTALK_HOST   "127.0.0.1"

Definition at line 66 of file cdr_beanstalkd.c.

◆ DEFAULT_BEANSTALK_PORT

#define DEFAULT_BEANSTALK_PORT   11300

Definition at line 67 of file cdr_beanstalkd.c.

◆ DEFAULT_BEANSTALK_TUBE

#define DEFAULT_BEANSTALK_TUBE   "asterisk-cdr"

Definition at line 68 of file cdr_beanstalkd.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 270 of file cdr_beanstalkd.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 270 of file cdr_beanstalkd.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 270 of file cdr_beanstalkd.c.

◆ beanstalk_put()

static int beanstalk_put ( struct ast_cdr cdr)
static

Definition at line 162 of file cdr_beanstalkd.c.

162 {
163 struct ast_tm timeresult;
164 char strAnswerTime[80] = "";
165 char strStartTime[80];
166 char strEndTime[80];
167 char *cdr_buffer;
168 int bs_id;
169 int bs_socket;
170 struct ast_json *t_cdr_json;
171
172 if (!enablecdr) {
173 return 0;
174 }
175
177 bs_socket = bs_connect(bs_host, bs_port);
178
179 if (bs_use(bs_socket, bs_tube) != BS_STATUS_OK) {
180 ast_log(LOG_ERROR, "Connection to Beanstalk tube %s @ %s:%d had failed", bs_tube, bs_host, bs_port);
182 return 0;
183 }
184
185 ast_localtime(&cdr->start, &timeresult, NULL);
186 ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
187
188 if (cdr->answer.tv_sec) {
189 ast_localtime(&cdr->answer, &timeresult, NULL);
190 ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
191 }
192
193 ast_localtime(&cdr->end, &timeresult, NULL);
194 ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
195
197
198 t_cdr_json = ast_json_pack("{s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:i, s:i, s:s, s:s, s:s, s:s}",
199 "AccountCode", S_OR(cdr->accountcode, ""),
200 "Source", S_OR(cdr->src, ""),
201 "Destination", S_OR(cdr->dst, ""),
202 "DestinationContext", S_OR(cdr->dcontext, ""),
203 "CallerID", S_OR(cdr->clid, ""),
204 "Channel", S_OR(cdr->channel, ""),
205 "DestinationChannel", S_OR(cdr->dstchannel, ""),
206 "LastApplication", S_OR(cdr->lastapp, ""),
207 "LastData", S_OR(cdr->lastdata, ""),
208 "StartTime", S_OR(strStartTime, ""),
209 "AnswerTime", S_OR(strAnswerTime, ""),
210 "EndTime", S_OR(strEndTime, ""),
211 "Duration", cdr->duration,
212 "Billsec", cdr->billsec,
213 "Disposition", S_OR(ast_cdr_disp2str(cdr->disposition), ""),
214 "AMAFlags", S_OR(ast_channel_amaflags2string(cdr->amaflags), ""),
215 "UniqueID", S_OR(cdr->uniqueid, ""),
216 "UserField", S_OR(cdr->userfield, ""));
217
218 cdr_buffer = ast_json_dump_string(t_cdr_json);
219
220 ast_json_unref(t_cdr_json);
221
222 bs_id = bs_put(bs_socket, priority, BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, cdr_buffer, strlen(cdr_buffer));
223
224 if (bs_id > 0) {
225 ast_log(LOG_DEBUG, "Successfully created job %d with %s\n", bs_id, cdr_buffer);
226 } else {
227 ast_log(LOG_ERROR, "CDR job creation failed for %s\n", cdr_buffer);
228 }
229
230 bs_disconnect(bs_socket);
231 ast_json_free(cdr_buffer);
232 return 0;
233}
#define ast_log
Definition: astobj2.c:42
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3509
static char * bs_tube
static int bs_port
static int enablecdr
static ast_rwlock_t config_lock
#define BEANSTALK_JOB_DELAY
static int priority
static char * bs_host
#define DATE_FORMAT
#define BEANSTALK_JOB_TTR
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4392
#define LOG_DEBUG
#define LOG_ERROR
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:810
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
#define ast_rwlock_rdlock(a)
Definition: lock.h:235
#define ast_rwlock_unlock(a)
Definition: lock.h:234
#define NULL
Definition: resample.c:96
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:291
long int disposition
Definition: cdr.h:307
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:295
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:325
long int billsec
Definition: cdr.h:305
struct timeval answer
Definition: cdr.h:299
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:289
long int duration
Definition: cdr.h:303
long int amaflags
Definition: cdr.h:309
char src[AST_MAX_EXTENSION]
Definition: cdr.h:283
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:285
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
struct timeval start
Definition: cdr.h:297
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:311
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:293
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:287
struct timeval end
Definition: cdr.h:301
Abstract JSON element (object, array, string, int, ...).

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_channel_amaflags2string(), ast_json_dump_string, ast_json_free(), ast_json_pack(), ast_json_unref(), ast_localtime(), ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, ast_strftime(), BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, ast_cdr::billsec, bs_host, bs_port, bs_tube, ast_cdr::channel, ast_cdr::clid, config_lock, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, enablecdr, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, LOG_DEBUG, LOG_ERROR, NULL, priority, S_OR, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by load_module().

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 82 of file cdr_beanstalkd.c.

82 {
83 char *cat = NULL;
84 struct ast_config *cfg;
85 struct ast_variable *v;
86 struct ast_flags config_flags = {reload ? CONFIG_FLAG_FILEUNCHANGED : 0};
87 int newenablecdr = 0;
88
89 cfg = ast_config_load(CONF_FILE, config_flags);
90 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
91 return 0;
92 }
93
94 if (cfg == CONFIG_STATUS_FILEINVALID) {
95 ast_log(LOG_ERROR, "Config file '%s' could not be parsed\n", CONF_FILE);
96 return -1;
97 }
98
99 if (!cfg) {
100 /* Standard configuration */
101 ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
102 if (enablecdr) {
104 }
105 enablecdr = 0;
106 return -1;
107 }
108
109 if (reload) {
113 }
114
115 /* Bootstrap the default configuration */
120
121 while ((cat = ast_category_browse(cfg, cat))) {
122 if (!strcasecmp(cat, "general")) {
123 v = ast_variable_browse(cfg, cat);
124 while (v) {
125
126 if (!strcasecmp(v->name, "enabled")) {
127 newenablecdr = ast_true(v->value);
128 } else if (!strcasecmp(v->name, "host")) {
131 } else if (!strcasecmp(v->name, "port")) {
132 bs_port = atoi(v->value);
133 } else if (!strcasecmp(v->name, "tube")) {
136 } else if (!strcasecmp(v->name, "priority")) {
137 priority = atoi(v->value);
138 }
139 v = v->next;
140
141 }
142 }
143 }
144
145 if (reload) {
147 }
148
150
151 if (!newenablecdr) {
153 } else if (newenablecdr) {
155 ast_log(LOG_NOTICE, "Added beanstalkd server %s at port %d with tube %s", bs_host, bs_port, bs_tube);
156 }
157 enablecdr = newenablecdr;
158
159 return 0;
160}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
Definition: cdr.c:2950
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Definition: cdr.c:2932
static const char name[]
#define CONF_FILE
#define DEFAULT_BEANSTALK_HOST
#define DEFAULT_BEANSTALK_TUBE
static int reload(void)
#define BEANSTALK_JOB_PRIORITY
#define DEFAULT_BEANSTALK_PORT
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
#define LOG_NOTICE
#define LOG_WARNING
#define ast_rwlock_wrlock(a)
Definition: lock.h:236
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ast_category_browse(), ast_cdr_backend_suspend(), ast_cdr_backend_unsuspend(), ast_config_destroy(), ast_config_load, ast_free, ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, ast_strdup, ast_true(), ast_variable_browse(), BEANSTALK_JOB_PRIORITY, bs_host, bs_port, bs_tube, CONF_FILE, CONFIG_FLAG_FILEUNCHANGED, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_BEANSTALK_HOST, DEFAULT_BEANSTALK_PORT, DEFAULT_BEANSTALK_TUBE, enablecdr, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, ast_variable::name, ast_variable::next, NULL, priority, reload(), and ast_variable::value.

Referenced by load_module(), and reload().

◆ load_module()

static int load_module ( void  )
static

Definition at line 246 of file cdr_beanstalkd.c.

246 {
247 if (ast_cdr_register(name, "Asterisk CDR Beanstalkd Backend", beanstalk_put)) {
249 }
250
251 if (load_config(0)) {
254 }
255
257}
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:3054
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:3009
static int beanstalk_put(struct ast_cdr *cdr)
static int load_config(int reload)
@ 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

References ast_cdr_register(), ast_cdr_unregister(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, beanstalk_put(), load_config(), and name.

◆ reload()

static int reload ( void  )
static

Definition at line 259 of file cdr_beanstalkd.c.

259 {
260 return load_config(1);
261}

References load_config().

Referenced by load_config().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 235 of file cdr_beanstalkd.c.

235 {
237 return -1;
238 }
239
242
243 return 0;
244}

References ast_cdr_unregister(), ast_free, bs_host, bs_tube, and name.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Beanstalkd CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
static

Definition at line 270 of file cdr_beanstalkd.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 270 of file cdr_beanstalkd.c.

◆ bs_host

char* bs_host
static

Definition at line 73 of file cdr_beanstalkd.c.

Referenced by beanstalk_put(), load_config(), and unload_module().

◆ bs_port

int bs_port
static

Definition at line 74 of file cdr_beanstalkd.c.

Referenced by beanstalk_put(), and load_config().

◆ bs_tube

char* bs_tube
static

Definition at line 75 of file cdr_beanstalkd.c.

Referenced by beanstalk_put(), load_config(), and unload_module().

◆ config_lock

ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

Definition at line 78 of file cdr_beanstalkd.c.

Referenced by beanstalk_put(), and load_config().

◆ enablecdr

int enablecdr = 0
static

Definition at line 72 of file cdr_beanstalkd.c.

Referenced by beanstalk_put(), and load_config().

◆ name

const char name[] = "cdr_beanstalkd"
static

Definition at line 70 of file cdr_beanstalkd.c.

Referenced by load_config(), load_module(), and unload_module().

◆ priority

int priority
static

Definition at line 76 of file cdr_beanstalkd.c.

Referenced by __after_bridge_set_goto(), __ast_goto_if_exists(), acf_isexten_exec(), action_dialplan_exec(), action_originate(), action_redirect(), add_action_to_menu_entry(), add_extension(), ast_add_extension(), ast_add_extension2(), ast_add_extension2_lockopt(), ast_add_extension2_nolock(), ast_add_extension_nolock(), ast_async_goto(), ast_async_goto_by_name(), ast_async_goto_if_exists(), ast_bridge_set_after_go_on(), ast_bridge_set_after_goto(), ast_bridge_setup_after_goto(), ast_canmatch_extension(), ast_compile_ael2(), ast_context_remove_extension(), ast_context_remove_extension2(), ast_context_remove_extension_callerid(), ast_context_remove_extension_callerid2(), ast_exists_extension(), ast_explicit_goto(), ast_get_extension_data(), ast_goto_if_exists(), ast_json_dialplan_cep(), ast_json_dialplan_cep_app(), ast_matchmore_extension(), ast_pbx_outgoing_exten(), ast_pbx_outgoing_exten_predial(), ast_realtime_append_mapping(), ast_spawn_extension(), ast_srv_get_nth_record(), ast_syslog_priority(), ast_syslog_priority_name(), AST_TEST_DEFINE(), ast_walk_extension_priorities(), beanstalk_put(), bridge_exec(), canmatch(), change_priority_caller_on_queue(), complete_dialplan_remove_extension(), copy_plain_file(), dns_srv_alloc(), dns_srv_sort(), dundi_canmatch(), dundi_exec(), dundi_exists(), dundi_helper(), dundi_matchmore(), exec(), exists(), find_engine(), find_matching_priority(), generate_srv_record(), gosub_allocate_frame(), handle_gosub(), handle_queue_change_priority_caller(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), isexten_function_read(), jingle_interpret_ice_udp_transport(), leave_voicemail(), load_config(), load_module(), localized_add_extension2(), localized_find_extension(), localized_walk_extension_priorities(), loopback_parse(), loopback_subst(), lua_find_extension(), lua_pbx_exec(), lua_update_registry(), manager_change_priority_caller_on_queue(), manager_dialplan_extension_add(), manager_dialplan_extension_remove(), matchmore(), originate_exec(), parking_add_extension(), parse_srv(), pbx_extension_helper(), pbx_find_extension(), pbx_outgoing_attempt(), pidf_generate_body_content(), raise_exception(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_matchmore(), realtime_switch_common(), setup_peer_after_bridge_goto(), srv_result_read(), stasis_app_control_continue(), and xmpp_client_set_presence().