Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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:3452
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:4408
#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:783
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
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
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
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#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:289
long int disposition
Definition: cdr.h:305
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:293
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:319
long int billsec
Definition: cdr.h:303
struct timeval answer
Definition: cdr.h:297
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:287
long int duration
Definition: cdr.h:301
long int amaflags
Definition: cdr.h:307
char src[AST_MAX_EXTENSION]
Definition: cdr.h:281
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:283
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:279
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:315
struct timeval start
Definition: cdr.h:295
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:309
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:291
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:285
struct timeval end
Definition: cdr.h:299
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) {
111  ast_free(bs_host);
112  ast_free(bs_tube);
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")) {
129  ast_free(bs_host);
130  bs_host = ast_strdup(v->value);
131  } else if (!strcasecmp(v->name, "port")) {
132  bs_port = atoi(v->value);
133  } else if (!strcasecmp(v->name, "tube")) {
134  ast_free(bs_tube);
135  bs_tube = ast_strdup(v->value);
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 
149  ast_config_destroy(cfg);
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:2906
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Definition: cdr.c:2888
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:3327
@ CONFIG_FLAG_FILEUNCHANGED
#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
#define LOG_NOTICE
#define LOG_WARNING
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097
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().

◆ 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:3010
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:2965
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 }

Referenced by load_config().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 235 of file cdr_beanstalkd.c.

235  {
236  if (ast_cdr_unregister(name)) {
237  return -1;
238  }
239 
240  ast_free(bs_host);
241  ast_free(bs_tube);
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 259 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(), _skinny_message_clear(), _skinny_message_set(), _transmit_displayprinotify(), _transmit_displayprinotifyvar(), action_dialplan_exec(), action_originate(), action_redirect(), add_action_to_menu_entry(), add_extension(), ast_add_extension2(), 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_json_dialplan_cep(), ast_json_dialplan_cep_app(), ast_matchmore_extension(), 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(), 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(), pidf_generate_body_content(), raise_exception(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_matchmore(), realtime_switch_common(), send_displayprinotify(), setup_peer_after_bridge_goto(), stasis_app_control_continue(), transmit_clearprinotify(), and xmpp_client_set_presence().