50 #include "beanstalk.h"
60 #define DATE_FORMAT "%Y-%m-%d %T"
61 #define CONF_FILE "cdr_beanstalkd.conf"
62 #define BEANSTALK_JOB_SIZE 4096
63 #define BEANSTALK_JOB_PRIORITY 99
64 #define BEANSTALK_JOB_TTR 60
65 #define BEANSTALK_JOB_DELAY 0
66 #define DEFAULT_BEANSTALK_HOST "127.0.0.1"
67 #define DEFAULT_BEANSTALK_PORT 11300
68 #define DEFAULT_BEANSTALK_TUBE "asterisk-cdr"
70 static const char name[] =
"cdr_beanstalkd";
72 static int enablecdr = 0;
78 AST_RWLOCK_DEFINE_STATIC(config_lock);
80 static int beanstalk_put(
struct ast_cdr *cdr);
82 static int load_config(
int reload) {
90 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
94 if (cfg == CONFIG_STATUS_FILEINVALID) {
95 ast_log(LOG_ERROR,
"Config file '%s' could not be parsed\n", CONF_FILE);
101 ast_log(LOG_WARNING,
"Failed to load configuration file. Module not activated.\n");
110 ast_rwlock_wrlock(&config_lock);
117 bs_port = DEFAULT_BEANSTALK_PORT;
119 priority = BEANSTALK_JOB_PRIORITY;
122 if (!strcasecmp(cat,
"general")) {
123 v = ast_variable_browse(cfg, cat);
126 if (!strcasecmp(v->
name,
"enabled")) {
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);
146 ast_rwlock_unlock(&config_lock);
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);
157 enablecdr = newenablecdr;
162 static int beanstalk_put(
struct ast_cdr *cdr) {
164 char strAnswerTime[80] =
"";
165 char strStartTime[80];
176 ast_rwlock_rdlock(&config_lock);
177 bs_socket = bs_connect(bs_host, bs_port);
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);
181 ast_rwlock_unlock(&config_lock);
186 ast_strftime(strStartTime,
sizeof(strStartTime), DATE_FORMAT, &timeresult);
188 if (cdr->answer.tv_sec) {
190 ast_strftime(strAnswerTime,
sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
194 ast_strftime(strEndTime,
sizeof(strEndTime), DATE_FORMAT, &timeresult);
196 ast_rwlock_unlock(&config_lock);
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}",
201 "Destination",
S_OR(cdr->
dst,
""),
204 "Channel",
S_OR(cdr->channel,
""),
208 "StartTime",
S_OR(strStartTime,
""),
209 "AnswerTime",
S_OR(strAnswerTime,
""),
210 "EndTime",
S_OR(strEndTime,
""),
222 bs_id = bs_put(bs_socket, priority, BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, cdr_buffer, strlen(cdr_buffer));
225 ast_log(LOG_DEBUG,
"Successfully created job %d with %s\n", bs_id, cdr_buffer);
227 ast_log(LOG_ERROR,
"CDR job creation failed for %s\n", cdr_buffer);
230 bs_disconnect(bs_socket);
235 static int unload_module(
void) {
246 static int load_module(
void) {
247 if (
ast_cdr_register(name,
"Asterisk CDR Beanstalkd Backend", beanstalk_put)) {
251 if (load_config(0)) {
259 static int reload(
void) {
260 return load_config(1);
263 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Asterisk Beanstalkd CDR Backend",
264 .support_level = AST_MODULE_SUPPORT_EXTENDED,
266 .unload = unload_module,
struct ast_variable * next
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
char accountcode[AST_MAX_ACCOUNT_CODE]
Asterisk main include file. File version handling, generic pbx functions.
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
char dstchannel[AST_MAX_EXTENSION]
Time-related functions and macros.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
char dcontext[AST_MAX_EXTENSION]
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Structure for variables, used for configurations and for channel variables.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
#define ast_strdup(str)
A wrapper for strdup()
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
char lastdata[AST_MAX_EXTENSION]
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
General Asterisk PBX channel definitions.
Asterisk JSON abstraction layer.
char uniqueid[AST_MAX_UNIQUEID]
char dst[AST_MAX_EXTENSION]
Core PBX routines and definitions.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Responsible for call detail data.
char lastapp[AST_MAX_EXTENSION]
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Module has failed to load, may be in an inconsistent state.
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...
Structure used to handle boolean flags.
char src[AST_MAX_EXTENSION]
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Abstract JSON element (object, array, string, int, ...).
char clid[AST_MAX_EXTENSION]
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
char userfield[AST_MAX_USER_FIELD]