Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
Data Structures | Macros | Functions | Variables
cdr_mysql.c File Reference

MySQL CDR backend. More...

#include "asterisk.h"
#include <mysql/mysql.h>
#include <mysql/errmsg.h>
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/strings.h"
#include "asterisk/linkedlists.h"
#include "asterisk/threadstorage.h"

Go to the source code of this file.

Data Structures

struct  column
 
struct  columns
 
struct  unload_string
 
struct  unload_strings
 

Macros

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

Functions

static void __init_escape_buf (void)
 
static void __init_sql1_buf (void)
 
static void __init_sql2_buf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void configure_connection_charset (void)
 
static void free_strings (void)
 
static char * handle_cli_cdr_mysql_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static int my_connect_db (struct ast_config *cfg)
 
static int my_load_config_number (struct ast_config *cfg, const char *category, const char *variable, int *field, int def)
 
static int my_load_config_string (struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def)
 
static int my_load_module (int reload)
 
static int my_unload_module (int reload)
 
static int mysql_log (struct ast_cdr *cdr)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "MySQL 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_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .requires = "cdr", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int calldate_compat = 0
 
static struct ast_cli_entry cdr_mysql_status_cli []
 
static struct ast_strcdrzone = NULL
 
static struct columns columns = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static const char config [] = "cdr_mysql.conf"
 
static time_t connect_time = 0
 
static int connected = 0
 
static struct ast_strdbcharset = NULL
 
static struct ast_strdbname = NULL
 
static int dbport = 0
 
static struct ast_strdbsock = NULL
 
static struct ast_strdbtable = NULL
 
static struct ast_strdbuser = NULL
 
static const char desc [] = "MySQL CDR Backend"
 
static struct ast_threadstorage escape_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_buf , .custom_init = NULL , }
 
static struct ast_strhostname = NULL
 
static MYSQL mysql = { { NULL }, }
 
static ast_mutex_t mysql_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static const char name [] = "mysql"
 
static struct ast_strpassword = NULL
 
static int records = 0
 
static struct ast_threadstorage sql1_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql1_buf , .custom_init = NULL , }
 
static struct ast_threadstorage sql2_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql2_buf , .custom_init = NULL , }
 
static struct ast_strssl_ca = NULL
 
static struct ast_strssl_cert = NULL
 
static struct ast_strssl_key = NULL
 
static int timeout = 0
 
static int totalrecords = 0
 
static struct unload_strings unload_strings = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 

Detailed Description

MySQL CDR backend.

Definition in file cdr_mysql.c.

Macro Definition Documentation

◆ DATE_FORMAT

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

Definition at line 59 of file cdr_mysql.c.

Referenced by mysql_log().

◆ MYSQL_PORT

#define MYSQL_PORT   3306

Definition at line 65 of file cdr_mysql.c.

Referenced by my_load_module().

Function Documentation

◆ __init_escape_buf()

static void __init_escape_buf ( void  )
static

Definition at line 71 of file cdr_mysql.c.

91 {

◆ __init_sql1_buf()

static void __init_sql1_buf ( void  )
static

Definition at line 69 of file cdr_mysql.c.

91 {

◆ __init_sql2_buf()

static void __init_sql2_buf ( void  )
static

Definition at line 70 of file cdr_mysql.c.

91 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 758 of file cdr_mysql.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 758 of file cdr_mysql.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 758 of file cdr_mysql.c.

◆ configure_connection_charset()

static void configure_connection_charset ( void  )
static

Definition at line 162 of file cdr_mysql.c.

References ast_log, ast_str_buffer(), ast_str_strlen(), dbcharset, LOG_WARNING, and mysql.

Referenced by my_connect_db(), and mysql_log().

163 {
164  if (ast_str_strlen(dbcharset)) {
165  const char *charset = ast_str_buffer(dbcharset);
166  if (mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, charset)) {
167  ast_log(LOG_WARNING, "Failed to set connection charset. Data inserted might be invalid.\n");
168  }
169  }
170 }
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static struct ast_str * dbcharset
Definition: cdr_mysql.c:77
#define ast_log
Definition: astobj2.c:42
charset
Definition: chan_unistim.c:336
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static MYSQL mysql
Definition: cdr_mysql.c:109

◆ free_strings()

static void free_strings ( void  )
static

Definition at line 371 of file cdr_mysql.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and unload_string::str.

Referenced by my_load_module(), and my_unload_module().

372 {
373  struct unload_string *us;
374 
376  while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
377  ast_free(us->str);
378  ast_free(us);
379  }
381 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_str * str
Definition: cdr_mysql.c:93
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182
Definition: search.h:40

◆ handle_cli_cdr_mysql_status()

static char* handle_cli_cdr_mysql_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 111 of file cdr_mysql.c.

References ast_cli_args::argc, ast_cli(), ast_cli_print_timestr_fromseconds(), ast_str_buffer(), ast_str_strlen(), buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, connect_time, connected, dbname, dbport, dbsock, dbtable, dbuser, ast_cli_args::fd, NULL, records, S_OR, status, totalrecords, and ast_cli_entry::usage.

112 {
113  switch (cmd) {
114  case CLI_INIT:
115  e->command = "cdr mysql status";
116  e->usage =
117  "Usage: cdr mysql status\n"
118  " Shows current connection status for cdr_mysql\n";
119  return NULL;
120  case CLI_GENERATE:
121  return NULL;
122  }
123 
124  if (a->argc != 3)
125  return CLI_SHOWUSAGE;
126 
127  if (connected) {
128  char status[256];
129  char status2[100] = "";
130  char buf[362]; /* 256+100+" for "+NULL */
131  int ctime = time(NULL) - connect_time;
132  if (dbport)
133  snprintf(status, 255, "Connected to %s@%s, port %d", ast_str_buffer(dbname), ast_str_buffer(hostname), dbport);
134  else if (dbsock)
135  snprintf(status, 255, "Connected to %s on socket file %s", ast_str_buffer(dbname), S_OR(ast_str_buffer(dbsock), "default"));
136  else
137  snprintf(status, 255, "Connected to %s@%s", ast_str_buffer(dbname), ast_str_buffer(hostname));
138 
139  if (ast_str_strlen(dbuser))
140  snprintf(status2, 99, " with username %s", ast_str_buffer(dbuser));
141  if (ast_str_strlen(dbtable))
142  snprintf(status2, 99, " using table %s", ast_str_buffer(dbtable));
143 
144  snprintf(buf, sizeof(buf), "%s%s for ", status, status2);
145  ast_cli_print_timestr_fromseconds(a->fd, ctime, buf);
146 
147  if (records == totalrecords)
148  ast_cli(a->fd, " Wrote %d records since last restart.\n", totalrecords);
149  else
150  ast_cli(a->fd, " Wrote %d records since last restart and %d records since last reconnect.\n", totalrecords, records);
151  } else {
152  ast_cli(a->fd, "Not currently connected to a MySQL server.\n");
153  }
154 
155  return CLI_SUCCESS;
156 }
static int records
Definition: cdr_mysql.c:84
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct ast_str * dbtable
Definition: cdr_mysql.c:77
const int fd
Definition: cli.h:159
static time_t connect_time
Definition: cdr_mysql.c:83
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int totalrecords
Definition: cdr_mysql.c:85
static struct ast_str * dbname
Definition: cdr_mysql.c:77
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
void ast_cli_print_timestr_fromseconds(int fd, int seconds, const char *prefix)
Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s), s second(s)
Definition: main/cli.c:2972
#define CLI_SUCCESS
Definition: cli.h:44
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int connected
Definition: cdr_mysql.c:82
static struct ast_str * dbsock
Definition: cdr_mysql.c:77
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static struct ast_str * dbuser
Definition: cdr_mysql.c:77
static struct ast_str * hostname
Definition: cdr_mysql.c:77
static int dbport
Definition: cdr_mysql.c:81
jack_status_t status
Definition: app_jack.c:146

◆ load_module()

static int load_module ( void  )
static

Definition at line 731 of file cdr_mysql.c.

References my_load_module().

Referenced by reload().

732 {
733  return my_load_module(0);
734 }
static int my_load_module(int reload)
Definition: cdr_mysql.c:597

◆ my_connect_db()

static int my_connect_db ( struct ast_config cfg)
static

Connect to MySQL. Initializes the connection.

  • Assumes the read-write lock for columns is held.
  • Caller should allocate and free cfg

Definition at line 466 of file cdr_mysql.c.

References ast_calloc, ast_debug, AST_LIST_INSERT_TAIL, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strip(), ast_strlen_zero, ast_variable_browse(), ast_verb, column::cdrname, configure_connection_charset(), connect_time, connected, dbname, dbport, dbsock, dbtable, dbuser, unload_string::entry, item, column::list, LOG_ERROR, mysql, ast_variable::name, column::name, ast_variable::next, NULL, password, records, result, ssl_cert, ssl_key, column::staticvalue, timeout, column::type, ast_variable::value, and var.

Referenced by my_load_module().

467 {
468  struct ast_variable *var;
469  char *temp;
470  MYSQL_ROW row;
471  MYSQL_RES *result;
472  char sqldesc[128];
473 #ifdef HAVE_MYSQLCLIENT_BOOL
474  bool my_bool_true = 1;
475 #elif HAVE_MYSQLCLIENT_MY_BOOL
476  my_bool my_bool_true = 1;
477 #endif
478 
479  mysql_init(&mysql);
480 
481  if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {
482  ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
483  }
484 
485 #if MYSQL_VERSION_ID >= 50013
486  /* Add option for automatic reconnection */
487  if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {
488  ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
489  }
490 #endif
491 
493  mysql_ssl_set(&mysql,
495  ssl_cert ? ast_str_buffer(ssl_cert) : NULL,
496  ssl_ca ? ast_str_buffer(ssl_ca) : NULL,
497  NULL, NULL);
498  }
499  temp = dbsock && ast_str_strlen(dbsock) ? ast_str_buffer(dbsock) : NULL;
500 
502 
503  if (!mysql_real_connect(&mysql, ast_str_buffer(hostname), ast_str_buffer(dbuser), ast_str_buffer(password), ast_str_buffer(dbname), dbport, temp, ssl_ca && ast_str_strlen(ssl_ca) ? CLIENT_SSL : 0)) {
504  ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", ast_str_buffer(dbname), ast_str_buffer(hostname));
505  connected = 0;
506  records = 0;
507 
508  return AST_MODULE_LOAD_SUCCESS; /* May be reconnected later */
509  }
510 
511  ast_debug(1, "Successfully connected to MySQL database.\n");
512  connected = 1;
513  records = 0;
514  connect_time = time(NULL);
515 
516  /* Get table description */
517  snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? ast_str_buffer(dbtable) : "cdr");
518  if (mysql_query(&mysql, sqldesc)) {
519  ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");
520  mysql_close(&mysql);
521  connected = 0;
522 
524  }
525 
526  if (!(result = mysql_store_result(&mysql))) {
527  ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");
528  mysql_close(&mysql);
529  connected = 0;
530 
532  }
533 
534  while ((row = mysql_fetch_row(result))) {
535  struct column *entry;
536  char *cdrvar = "", *staticvalue = "";
537 
538  ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);
539  /* Check for an alias or a static value */
540  for (var = ast_variable_browse(cfg, "columns"); var; var = var->next) {
541  if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, row[0]) == 0 ) {
542  char *alias = ast_strdupa(var->name + 5);
543  cdrvar = ast_strip(alias);
544  ast_verb(3, "Found alias %s for column %s\n", cdrvar, row[0]);
545  break;
546  } else if (strncmp(var->name, "static", 6) == 0 && strcasecmp(var->value, row[0]) == 0) {
547  char *item = ast_strdupa(var->name + 6);
548  item = ast_strip(item);
549  if (item[0] == '"' && item[strlen(item) - 1] == '"') {
550  /* Remove surrounding quotes */
551  item[strlen(item) - 1] = '\0';
552  item++;
553  }
554  staticvalue = item;
555  }
556  }
557 
558  entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(row[0]) + 1 + strlen(cdrvar) + 1 + strlen(staticvalue) + 1 + strlen(row[1]) + 1);
559  if (!entry) {
560  ast_log(LOG_ERROR, "Out of memory creating entry for column '%s'\n", row[0]);
561  mysql_free_result(result);
563  }
564 
565  entry->name = (char *)entry + sizeof(*entry);
566  strcpy(entry->name, row[0]);
567 
568  if (!ast_strlen_zero(cdrvar)) {
569  entry->cdrname = entry->name + strlen(row[0]) + 1;
570  strcpy(entry->cdrname, cdrvar);
571  } else { /* Point to same place as the column name */
572  entry->cdrname = (char *)entry + sizeof(*entry);
573  }
574 
576  entry->staticvalue = entry->cdrname + strlen(entry->cdrname) + 1;
577  strcpy(entry->staticvalue, staticvalue);
578  ast_debug(1, "staticvalue length: %d\n", (int) strlen(staticvalue) );
579  entry->type = entry->staticvalue + strlen(entry->staticvalue) + 1;
580  } else {
581  entry->type = entry->cdrname + strlen(entry->cdrname) + 1;
582  }
583  strcpy(entry->type, row[1]);
584 
585  ast_debug(1, "Entry name '%s'\n", entry->name);
586  ast_debug(1, " cdrname '%s'\n", entry->cdrname);
587  ast_debug(1, " static '%s'\n", entry->staticvalue);
588  ast_debug(1, " type '%s'\n", entry->type);
589 
591  }
592  mysql_free_result(result);
593 
595 }
struct ast_variable * next
static int records
Definition: cdr_mysql.c:84
static struct ast_str * ssl_cert
Definition: cdr_mysql.c:79
char * cdrname
Definition: cdr_mysql.c:100
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int timeout
Definition: cdr_mysql.c:86
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static struct aco_type item
Definition: test_config.c:1463
#define NULL
Definition: resample.c:96
char * staticvalue
Definition: cdr_mysql.c:101
static struct ast_str * ssl_ca
Definition: cdr_mysql.c:79
static struct ast_str * password
Definition: cdr_mysql.c:77
#define ast_verb(level,...)
Definition: logger.h:455
static struct ast_str * dbtable
Definition: cdr_mysql.c:77
char * type
Definition: cdr_mysql.c:102
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
struct column::@3 list
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static time_t connect_time
Definition: cdr_mysql.c:83
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static struct ast_str * ssl_key
Definition: cdr_mysql.c:79
static void configure_connection_charset(void)
Definition: cdr_mysql.c:162
#define ast_strlen_zero(a)
Definition: muted.c:73
static struct ast_str * dbname
Definition: cdr_mysql.c:77
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int connected
Definition: cdr_mysql.c:82
static struct ast_str * dbsock
Definition: cdr_mysql.c:77
static struct ast_str * dbuser
Definition: cdr_mysql.c:77
char * name
Definition: cdr_mysql.c:99
static PGresult * result
Definition: cel_pgsql.c:88
static struct ast_str * hostname
Definition: cdr_mysql.c:77
static int dbport
Definition: cdr_mysql.c:81
Definition: search.h:40
static MYSQL mysql
Definition: cdr_mysql.c:109

◆ my_load_config_number()

static int my_load_config_number ( struct ast_config cfg,
const char *  category,
const char *  variable,
int *  field,
int  def 
)
static

Definition at line 449 of file cdr_mysql.c.

References ast_variable_retrieve(), and tmp().

Referenced by my_load_module().

450 {
451  const char *tmp;
452 
453  tmp = ast_variable_retrieve(cfg, category, variable);
454 
455  if (!tmp || sscanf(tmp, "%30d", field) < 1)
456  *field = def;
457 
458  return 0;
459 }
static int tmp()
Definition: bt_open.c:389
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694

◆ my_load_config_string()

static int my_load_config_string ( struct ast_config cfg,
const char *  category,
const char *  variable,
struct ast_str **  field,
const char *  def 
)
static

Definition at line 423 of file cdr_mysql.c.

References ast_calloc, ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_str_create, ast_str_set(), ast_variable_retrieve(), unload_string::str, and tmp().

Referenced by my_load_module().

424 {
425  struct unload_string *us;
426  const char *tmp;
427 
428  if (!(us = ast_calloc(1, sizeof(*us))))
429  return -1;
430 
431  if (!(*field = ast_str_create(16))) {
432  ast_free(us);
433  return -1;
434  }
435 
436  tmp = ast_variable_retrieve(cfg, category, variable);
437 
438  ast_str_set(field, 0, "%s", tmp ? tmp : def);
439 
440  us->str = *field;
441 
445 
446  return 0;
447 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_str * str
Definition: cdr_mysql.c:93
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int tmp()
Definition: bt_open.c:389
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
Definition: search.h:40
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ my_load_module()

static int my_load_module ( int  reload)
static

Definition at line 597 of file cdr_mysql.c.

References ast_cdr_backend_unsuspend(), ast_cdr_register(), ast_cli_register_multiple, ast_config_destroy(), ast_config_load, ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_true(), ast_variable_browse(), calldate_compat, cdrzone, config, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, dbcharset, dbname, dbport, dbsock, dbtable, dbuser, desc, unload_string::entry, free_strings(), LOG_ERROR, LOG_WARNING, my_connect_db(), my_load_config_number(), my_load_config_string(), my_unload_module(), mysql_log(), MYSQL_PORT, name, ast_variable::name, ast_variable::next, password, S_OR, ssl_cert, ssl_key, timeout, ast_variable::value, and var.

Referenced by load_module(), and reload().

598 {
599  int res;
600  struct ast_config *cfg;
601  struct ast_variable *var;
602  /* CONFIG_STATUS_FILEUNCHANGED is impossible when config_flags is always 0,
603  * and it has to be zero, so a reload can be sent to tell the driver to
604  * rescan the table layout. */
605  struct ast_flags config_flags = { 0 };
606  struct column *entry;
607  struct ast_str *compat;
608 
609  /* Cannot use a conditionally different flag, because the table layout may
610  * have changed, which is not detectable by config file change detection,
611  * but should still cause the configuration to be re-parsed. */
612  cfg = ast_config_load(config, config_flags);
613  if (cfg == CONFIG_STATUS_FILEMISSING) {
614  ast_log(LOG_WARNING, "Unable to load config for mysql CDR's: %s\n", config);
616  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
617  ast_log(LOG_ERROR, "Unable to load configuration file '%s'\n", config);
619  }
620 
621  if (reload) {
623  my_unload_module(1);
624  }
625 
626  var = ast_variable_browse(cfg, "global");
627  if (!var) {
628  /* nothing configured */
629  if (reload) {
631  }
632  ast_config_destroy(cfg);
634  }
635 
636  res = 0;
637 
638  res |= my_load_config_string(cfg, "global", "hostname", &hostname, "localhost");
639  res |= my_load_config_string(cfg, "global", "dbname", &dbname, "astriskcdrdb");
640  res |= my_load_config_string(cfg, "global", "user", &dbuser, "root");
641  res |= my_load_config_string(cfg, "global", "sock", &dbsock, "");
642  res |= my_load_config_string(cfg, "global", "table", &dbtable, "cdr");
643  res |= my_load_config_string(cfg, "global", "password", &password, "");
644 
645  res |= my_load_config_string(cfg, "global", "charset", &dbcharset, "");
646 
647  res |= my_load_config_string(cfg, "global", "ssl_ca", &ssl_ca, "");
648  res |= my_load_config_string(cfg, "global", "ssl_cert", &ssl_cert, "");
649  res |= my_load_config_string(cfg, "global", "ssl_key", &ssl_key, "");
650 
651  res |= my_load_config_number(cfg, "global", "port", &dbport, MYSQL_PORT);
652  res |= my_load_config_number(cfg, "global", "timeout", &timeout, 0);
653  res |= my_load_config_string(cfg, "global", "compat", &compat, "no");
654  res |= my_load_config_string(cfg, "global", "cdrzone", &cdrzone, "");
655  if (ast_str_strlen(cdrzone) == 0) {
656  for (; var; var = var->next) {
657  if (!strcasecmp(var->name, "usegmtime") && ast_true(var->value)) {
658  ast_str_set(&cdrzone, 0, "UTC");
659  }
660  }
661  }
662 
663  if (ast_true(ast_str_buffer(compat))) {
664  calldate_compat = 1;
665  } else {
666  calldate_compat = 0;
667  }
668 
669  if (res < 0) {
670  if (reload) {
672  }
673  ast_config_destroy(cfg);
674  free_strings();
675 
677  }
678 
679  /* Check for any aliases */
680  if (!reload) {
681  /* Lock, if not already */
683  }
684  while ((entry = AST_LIST_REMOVE_HEAD(&columns, list))) {
685  ast_free(entry);
686  }
687 
688  ast_debug(1, "Got hostname of %s\n", ast_str_buffer(hostname));
689  ast_debug(1, "Got port of %d\n", dbport);
690  ast_debug(1, "Got a timeout of %d\n", timeout);
691  if (ast_str_strlen(dbsock)) {
692  ast_debug(1, "Got sock file of %s\n", ast_str_buffer(dbsock));
693  }
694  ast_debug(1, "Got user of %s\n", ast_str_buffer(dbuser));
695  ast_debug(1, "Got dbname of %s\n", ast_str_buffer(dbname));
696  ast_debug(1, "Got password of %s\n", ast_str_buffer(password));
697  ast_debug(1, "%sunning in calldate compatibility mode\n", calldate_compat ? "R" : "Not r");
698  ast_debug(1, "Dates and times are localized to %s\n", S_OR(ast_str_buffer(cdrzone), "local timezone"));
699 
700  if (ast_str_strlen(dbcharset)) {
701  ast_debug(1, "Got DB charset of %s\n", ast_str_buffer(dbcharset));
702  }
703 
704  res = my_connect_db(cfg);
706  ast_config_destroy(cfg);
707  if (res != AST_MODULE_LOAD_SUCCESS) {
708  my_unload_module(0);
709  return res;
710  }
711 
712  if (!reload) {
714  } else {
716  }
717  if (res) {
718  ast_log(LOG_ERROR, "Unable to register MySQL CDR handling\n");
719  } else {
721  }
722 
723  if (res) {
724  my_unload_module(0);
726  }
727 
729 }
struct ast_variable * next
static struct ast_str * ssl_cert
Definition: cdr_mysql.c:79
static int my_load_config_number(struct ast_config *cfg, const char *category, const char *variable, int *field, int def)
Definition: cdr_mysql.c:449
static int calldate_compat
Definition: cdr_mysql.c:87
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
descriptor for a cli entry.
Definition: cli.h:171
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
Definition: cdr.c:2884
#define CONFIG_STATUS_FILEINVALID
static int timeout
Definition: cdr_mysql.c:86
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static const char desc[]
Definition: cdr_mysql.c:73
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define MYSQL_PORT
Definition: cdr_mysql.c:65
static struct ast_str * ssl_ca
Definition: cdr_mysql.c:79
static struct ast_str * password
Definition: cdr_mysql.c:77
static struct ast_str * dbtable
Definition: cdr_mysql.c:77
static struct ast_str * dbcharset
Definition: cdr_mysql.c:77
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#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.
Definition: cdr.c:2943
static struct ast_cli_entry cdr_mysql_status_cli[]
Definition: cdr_mysql.c:158
static int my_load_config_string(struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def)
Definition: cdr_mysql.c:423
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define LOG_ERROR
Definition: logger.h:285
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".
Definition: main/utils.c:1821
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static struct ast_str * ssl_key
Definition: cdr_mysql.c:79
static struct ast_str * dbname
Definition: cdr_mysql.c:77
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
static int reload(void)
Definition: cdr_mysql.c:741
static int mysql_log(struct ast_cdr *cdr)
Definition: cdr_mysql.c:172
static int my_unload_module(int reload)
Definition: cdr_mysql.c:383
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Structure used to handle boolean flags.
Definition: utils.h:199
static int my_connect_db(struct ast_config *cfg)
Definition: cdr_mysql.c:466
#define CONFIG_STATUS_FILEMISSING
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static struct ast_str * dbsock
Definition: cdr_mysql.c:77
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static const char config[]
Definition: cdr_mysql.c:75
static struct ast_str * dbuser
Definition: cdr_mysql.c:77
static struct ast_str * cdrzone
Definition: cdr_mysql.c:77
static struct ast_str * hostname
Definition: cdr_mysql.c:77
static int dbport
Definition: cdr_mysql.c:81
Definition: search.h:40
static void free_strings(void)
Definition: cdr_mysql.c:371

◆ my_unload_module()

static int my_unload_module ( int  reload)
static

Definition at line 383 of file cdr_mysql.c.

References ast_cdr_backend_suspend(), ast_cdr_unregister(), ast_cli_unregister_multiple(), ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, connected, dbport, unload_string::entry, free_strings(), column::list, mysql, name, and records.

Referenced by my_load_module(), and unload_module().

384 {
385  struct column *entry;
386 
387  if (!reload) {
388  if (ast_cdr_unregister(name)) {
389  /* If we can't unregister the backend, we can't unload the module */
390  return -1;
391  }
392  }
393 
395 
396  if (connected) {
397  mysql_close(&mysql);
398  connected = 0;
399  records = 0;
400  }
401 
402  free_strings();
403 
404  if (!reload) {
406  }
407  while ((entry = AST_RWLIST_REMOVE_HEAD(&columns, list))) {
408  ast_free(entry);
409  }
410  if (!reload) {
412  }
413 
414  dbport = 0;
415  if (reload) {
417  } else {
418  /* We unregistered earlier */
419  return 0;
420  }
421 }
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Definition: cdr.c:2866
static int records
Definition: cdr_mysql.c:84
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:2988
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
descriptor for a cli entry.
Definition: cli.h:171
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct ast_cli_entry cdr_mysql_status_cli[]
Definition: cdr_mysql.c:158
struct column::@3 list
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
static int reload(void)
Definition: cdr_mysql.c:741
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:843
static int connected
Definition: cdr_mysql.c:82
static int dbport
Definition: cdr_mysql.c:81
Definition: search.h:40
static MYSQL mysql
Definition: cdr_mysql.c:109
static void free_strings(void)
Definition: cdr_mysql.c:371

◆ mysql_log()

static int mysql_log ( struct ast_cdr cdr)
static
Note
For some dumb reason, "calldate" used to be formulated using the datetime the record was posted, rather than the start time of the call. If someone really wants the old compatible behavior, it's provided here.

Definition at line 172 of file cdr_mysql.c.

References ast_cdr::answer, AS_OR, ast_cdr_format_var(), ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_mutex_lock, ast_mutex_unlock, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_make_space, ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_strdupa, ast_strftime(), ast_strlen_zero, ast_tvdiff_us(), ast_tvnow(), ast_tvzero(), calldate_compat, column::cdrname, cdrzone, configure_connection_charset(), connect_time, connected, DATE_FORMAT, dbname, dbport, dbsock, dbtable, dbuser, ast_cdr::end, unload_string::entry, error(), escape_buf, LOG_ERROR, mysql, mysql_lock, column::name, NULL, password, records, sql1_buf, sql2_buf, ssl_cert, ssl_key, ast_cdr::start, column::staticvalue, timeout, totalrecords, column::type, and value.

Referenced by my_load_module().

173 {
174  struct ast_str *sql1 = ast_str_thread_get(&sql1_buf, 1024), *sql2 = ast_str_thread_get(&sql2_buf, 1024);
175  int retries = 5;
176 #ifdef HAVE_MYSQLCLIENT_BOOL
177  bool my_bool_true = 1;
178 #elif HAVE_MYSQLCLIENT_MY_BOOL
179  my_bool my_bool_true = 1;
180 #endif
181 
182  if (!sql1 || !sql2) {
183  ast_log(LOG_ERROR, "Memory error\n");
184  return -1;
185  }
186 
188 
189 db_reconnect:
190  if ((!connected) && (hostname || dbsock) && dbuser && password && dbname && dbtable ) {
191  /* Attempt to connect */
192  mysql_init(&mysql);
193  /* Add option to quickly timeout the connection */
194  if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {
195  ast_log(LOG_ERROR, "mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
196  }
197 #if MYSQL_VERSION_ID >= 50013
198  /* Add option for automatic reconnection */
199  if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {
200  ast_log(LOG_ERROR, "mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
201  }
202 #endif
203  if (ssl_ca || ssl_cert || ssl_key) {
204  mysql_ssl_set(&mysql, ssl_key ? ast_str_buffer(ssl_key) : NULL, ssl_cert ? ast_str_buffer(ssl_cert) : NULL, ssl_ca ? ast_str_buffer(ssl_ca) : NULL, NULL, NULL);
205  }
206 
208 
210  connected = 1;
211  connect_time = time(NULL);
212  records = 0;
213  } else {
214  ast_log(LOG_ERROR, "Cannot connect to database server %s: (%d) %s\n", ast_str_buffer(hostname), mysql_errno(&mysql), mysql_error(&mysql));
215  connected = 0;
216  }
217  } else {
218  /* Long connection - ping the server */
219  int error;
220  if ((error = mysql_ping(&mysql))) {
221  connected = 0;
222  records = 0;
223  switch (mysql_errno(&mysql)) {
224  case CR_SERVER_GONE_ERROR:
225  case CR_SERVER_LOST:
226  ast_log(LOG_ERROR, "Server has gone away. Attempting to reconnect.\n");
227  break;
228  default:
229  ast_log(LOG_ERROR, "Unknown connection error: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
230  }
231  retries--;
232  if (retries) {
233  goto db_reconnect;
234  } else {
235  ast_log(LOG_ERROR, "Retried to connect five times, giving up.\n");
236  }
237  }
238  }
239 
240  if (connected) {
241  int column_count = 0;
242  char *cdrname;
243  char workspace[2048], *value = NULL;
244  struct column *entry;
245  struct ast_str *escape = ast_str_thread_get(&escape_buf, 16);
246 
247  ast_str_set(&sql1, 0, "INSERT INTO %s (", AS_OR(dbtable, "cdr"));
248  ast_str_set(&sql2, 0, ") VALUES (");
249 
251  AST_RWLIST_TRAVERSE(&columns, entry, list) {
252  if (!strcmp(entry->name, "calldate")) {
253  /*!\note
254  * For some dumb reason, "calldate" used to be formulated using
255  * the datetime the record was posted, rather than the start
256  * time of the call. If someone really wants the old compatible
257  * behavior, it's provided here.
258  */
259  if (calldate_compat) {
260  struct timeval tv = ast_tvnow();
261  struct ast_tm tm;
262  char timestr[128];
264  ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
265  value = ast_strdupa(timestr);
266  cdrname = "calldate";
267  } else {
268  cdrname = "start";
269  }
270  } else {
271  cdrname = entry->cdrname;
272  }
273 
274  /* Construct SQL */
275 
276  /* Need the type and value to determine if we want the raw value or not */
277  if (entry->staticvalue) {
278  value = ast_strdupa(entry->staticvalue);
279  } else if ((!strcmp(cdrname, "disposition") ||
280  !strcmp(cdrname, "amaflags")) &&
281  (strstr(entry->type, "int") ||
282  strstr(entry->type, "dec") ||
283  strstr(entry->type, "float") ||
284  strstr(entry->type, "double") ||
285  strstr(entry->type, "real") ||
286  strstr(entry->type, "numeric") ||
287  strstr(entry->type, "fixed"))) {
288  ast_cdr_format_var(cdr, cdrname, &value, workspace, sizeof(workspace), 1);
289  } else if (!strcmp(cdrname, "start") || !strcmp(cdrname, "answer") ||
290  !strcmp(cdrname, "end")) {
291  struct ast_tm tm;
292  char timestr[128];
294  ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
295  value = ast_strdupa(timestr);
296  } else if (!strcmp(cdrname, "calldate")) {
297  /* Skip calldate - the value has already been dup'd */
298  } else {
299  ast_cdr_format_var(cdr, cdrname, &value, workspace, sizeof(workspace), 0);
300  }
301 
302  if (value) {
303  size_t valsz;
304 
305  if (column_count++) {
306  ast_str_append(&sql1, 0, ",");
307  ast_str_append(&sql2, 0, ",");
308  }
309 
310  if (!strcasecmp(cdrname, "billsec") &&
311  (strstr(entry->type, "float") ||
312  strstr(entry->type, "double") ||
313  strstr(entry->type, "decimal") ||
314  strstr(entry->type, "numeric") ||
315  strstr(entry->type, "real"))) {
316 
317  if (!ast_tvzero(cdr->answer)) {
318  snprintf(workspace, sizeof(workspace), "%lf",
319  (double) (ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0));
320  } else {
321  ast_copy_string(workspace, "0", sizeof(workspace));
322  }
323 
324  if (!ast_strlen_zero(workspace)) {
325  value = workspace;
326  }
327  }
328 
329  if (!strcasecmp(cdrname, "duration") &&
330  (strstr(entry->type, "float") ||
331  strstr(entry->type, "double") ||
332  strstr(entry->type, "decimal") ||
333  strstr(entry->type, "numeric") ||
334  strstr(entry->type, "real"))) {
335 
336  snprintf(workspace, sizeof(workspace), "%lf",
337  (double) (ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0));
338 
339  if (!ast_strlen_zero(workspace)) {
340  value = workspace;
341  }
342  }
343 
344  ast_str_make_space(&escape, (valsz = strlen(value)) * 2 + 1);
345  mysql_real_escape_string(&mysql, ast_str_buffer(escape), value, valsz);
346 
347  ast_str_append(&sql1, 0, "`%s`", entry->name);
348  ast_str_append(&sql2, 0, "'%s'", ast_str_buffer(escape));
349  }
350  }
352 
353  ast_debug(1, "Inserting a CDR record.\n");
354  ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2));
355 
356  ast_debug(1, "SQL command as follows: %s\n", ast_str_buffer(sql1));
357 
358  if (mysql_real_query(&mysql, ast_str_buffer(sql1), ast_str_strlen(sql1))) {
359  ast_log(LOG_ERROR, "Failed to insert into database: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
360  mysql_close(&mysql);
361  connected = 0;
362  } else {
363  records++;
364  totalrecords++;
365  }
366  }
368  return 0;
369 }
static int records
Definition: cdr_mysql.c:84
static struct ast_str * ssl_cert
Definition: cdr_mysql.c:79
char * cdrname
Definition: cdr_mysql.c:100
static int calldate_compat
Definition: cdr_mysql.c:87
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int timeout
Definition: cdr_mysql.c:86
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
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_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
#define DATE_FORMAT
Definition: cdr_mysql.c:59
static ast_mutex_t mysql_lock
Definition: cdr_mysql.c:89
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
char * staticvalue
Definition: cdr_mysql.c:101
static struct ast_str * ssl_ca
Definition: cdr_mysql.c:79
static struct ast_str * password
Definition: cdr_mysql.c:77
static struct ast_str * dbtable
Definition: cdr_mysql.c:77
static struct ast_threadstorage sql2_buf
Definition: cdr_mysql.c:70
void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
Format a CDR variable from an already posted CDR.
Definition: cdr.c:3050
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
char * type
Definition: cdr_mysql.c:102
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct timeval answer
Definition: cdr.h:296
static time_t connect_time
Definition: cdr_mysql.c:83
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static struct ast_str * ssl_key
Definition: cdr_mysql.c:79
static void configure_connection_charset(void)
Definition: cdr_mysql.c:162
static struct ast_threadstorage sql1_buf
Definition: cdr_mysql.c:69
static int totalrecords
Definition: cdr_mysql.c:85
#define ast_strlen_zero(a)
Definition: muted.c:73
struct timeval start
Definition: cdr.h:294
static struct ast_str * dbname
Definition: cdr_mysql.c:77
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
static struct ast_threadstorage escape_buf
Definition: cdr_mysql.c:71
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static int connected
Definition: cdr_mysql.c:82
struct timeval end
Definition: cdr.h:298
static struct ast_str * dbsock
Definition: cdr_mysql.c:77
#define AS_OR(a, b)
Definition: strings.h:49
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct ast_str * dbuser
Definition: cdr_mysql.c:77
char * name
Definition: cdr_mysql.c:99
static struct ast_str * cdrzone
Definition: cdr_mysql.c:77
static struct ast_str * hostname
Definition: cdr_mysql.c:77
static int dbport
Definition: cdr_mysql.c:81
Definition: search.h:40
int error(const char *format,...)
Definition: utils/frame.c:999
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:78
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
static MYSQL mysql
Definition: cdr_mysql.c:109
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ reload()

static int reload ( void  )
static

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 736 of file cdr_mysql.c.

References my_unload_module().

Referenced by reload().

737 {
738  return my_unload_module(0);
739 }
static int my_unload_module(int reload)
Definition: cdr_mysql.c:383

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "MySQL 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_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .requires = "cdr", }
static

Definition at line 758 of file cdr_mysql.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 758 of file cdr_mysql.c.

◆ calldate_compat

int calldate_compat = 0
static

Definition at line 87 of file cdr_mysql.c.

Referenced by my_load_module(), and mysql_log().

◆ cdr_mysql_status_cli

struct ast_cli_entry cdr_mysql_status_cli[]
static
Initial value:
= {
{ .handler = handle_cli_cdr_mysql_status , .summary = "Show connection status of cdr_mysql" ,},
}
static char * handle_cli_cdr_mysql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cdr_mysql.c:111

Definition at line 158 of file cdr_mysql.c.

◆ cdrzone

struct ast_str * cdrzone = NULL
static

Definition at line 77 of file cdr_mysql.c.

Referenced by my_load_module(), and mysql_log().

◆ columns

struct columns columns = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ config

const char config[] = "cdr_mysql.conf"
static

Definition at line 75 of file cdr_mysql.c.

Referenced by my_load_module().

◆ connect_time

time_t connect_time = 0
static

Definition at line 83 of file cdr_mysql.c.

Referenced by handle_cli_cdr_mysql_status(), my_connect_db(), and mysql_log().

◆ connected

int connected = 0
static

◆ dbcharset

struct ast_str * dbcharset = NULL
static

Definition at line 77 of file cdr_mysql.c.

Referenced by aMYSQL_connect(), configure_connection_charset(), and my_load_module().

◆ dbname

struct ast_str * dbname = NULL
static

◆ dbport

int dbport = 0
static

◆ dbsock

struct ast_str * dbsock = NULL
static

Definition at line 77 of file cdr_mysql.c.

Referenced by handle_cli_cdr_mysql_status(), my_connect_db(), my_load_module(), and mysql_log().

◆ dbtable

struct ast_str * dbtable = NULL
static

Definition at line 77 of file cdr_mysql.c.

Referenced by handle_cli_cdr_mysql_status(), my_connect_db(), my_load_module(), and mysql_log().

◆ dbuser

struct ast_str * dbuser = NULL
static

◆ desc

const char desc[] = "MySQL CDR Backend"
static

◆ escape_buf

struct ast_threadstorage escape_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_buf , .custom_init = NULL , }
static

Definition at line 71 of file cdr_mysql.c.

Referenced by function_db_keys(), and mysql_log().

◆ hostname

struct ast_str* hostname = NULL
static

◆ mysql

MYSQL mysql = { { NULL }, }
static

◆ mysql_lock

ast_mutex_t mysql_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 89 of file cdr_mysql.c.

Referenced by mysql_log(), and reload().

◆ name

const char name[] = "mysql"
static

Definition at line 74 of file cdr_mysql.c.

Referenced by __aco_option_register(), __allocate_taskprocessor(), __ast_channel_alloc_ap(), _sip_show_peers_one(), acf_curl_helper(), acf_curl_write(), aco_option_register_deprecated(), action_atxfer(), action_blind_transfer(), action_cancel_atxfer(), action_getvar(), action_originate(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), add_notify(), add_rlmi_resource(), adsi_load(), adsi_message(), advanced_options(), aelsub_exec(), alias_name_cb(), alloc_new_parking_lot(), ao2_container_check(), ao2_container_unregister(), aoc_amount_str(), ast_bridge_snapshot_create(), ast_cc_monitor_count(), ast_channel_by_name_cb(), ast_channel_hash_cb(), ast_channel_yank(), ast_codec_get(), ast_get_chan_applicationmap(), ast_include_rename(), ast_jb_read_conf(), ast_monitor_change_fname(), ast_monitor_start(), ast_register_thread(), ast_rtp_lookup_mime_multiple2(), ast_set_callerid(), ast_setstate(), ast_sip_auth_vector_destroy(), ast_sip_default_outbound_endpoint(), ast_sip_for_each_aor(), ast_sip_location_create_contact(), ast_sip_presence_xml_find_node_attr(), ast_sip_report_failed_acl(), ast_sip_report_invalid_endpoint(), ast_sip_retrieve_auths(), ast_sip_subscription_get_header(), ast_sockaddr_stringify_port(), ast_stream_codec_prefs_parse(), AST_TEST_DEFINE(), ast_var_name(), ast_variable_lists_match(), ast_websocket_add_protocol(), ast_websocket_remove_protocol(), ast_websocket_server_add_protocol(), ast_websocket_server_remove_protocol(), ast_websocket_sub_protocol_alloc(), ast_xml_doc_item_hash(), ast_xmldoc_build_documentation(), ast_xmldoc_regenerate_doc_item(), ast_xmpp_client_config_alloc(), blacklist_read(), bridge_hash_cb(), build_calendar(), build_config_docs(), build_rlmi_body(), cache_update(), caller_id_to_str(), callerid_read(), cc_generic_agent_init(), cdr_object_alloc(), cdr_object_get_by_name_cb(), cdr_object_select_all_by_name_cb(), change_monitor_action(), channel_hash(), channel_read_rtcp(), channel_snapshot_base_create(), channel_snapshot_caller_create(), channel_snapshot_connected_create(), channel_spy(), check_expr(), check_user_full(), clear_config_maps(), cli_complete_registration(), cli_tps_ping(), cli_tps_reset_stats(), conference_bridge_hash_cb(), config_opt_cmp(), config_opt_hash(), config_option_destroy(), count_agents_cb(), destroy_pval(), dial_exec_full(), do_immediate_setup(), do_pause_or_unpause(), dtls_handler(), dump_ies(), dump_prov_ies(), endpoint_lookup(), fac2str(), fax_session_tab_complete(), find_calendar(), find_channel_parking_lot_name(), find_context(), find_macro(), find_option_cb(), find_user_realtime(), forward_message(), function_amiclient(), get_chan_by_ast_name(), get_cid_name(), get_codecs(), get_esc(), get_name_and_number(), get_outbound_endpoint(), handle_cli_misdn_show_channels(), handle_cli_mobile_search(), handle_cli_status(), handle_cli_test_locales(), handle_manager_bridge_tech_suspend(), handle_manager_show_events(), handle_redirect(), handle_showchan(), handle_tcptls_connection(), headers_to_vars(), hook_callback(), iax2_codec_pref_string(), initial_notify_task(), is_registered_cb(), jb_debug_output(), jingle_endpoint_alloc(), jingle_endpoint_cmp(), jingle_endpoint_hash(), jingle_interpret_content(), jingle_interpret_google_transport(), jingle_request(), leave_voicemail(), load_config(), load_module(), lua_get_variable(), lua_get_variable_value(), lua_set_variable(), lua_set_variable_value(), match_agent(), media_info_cmp(), media_info_hash(), menu_hash_cb(), mgcp_call(), mgcp_hangup(), minivm_notify_exec(), misdn_cfg_get_config_string(), misdn_cfg_get_name(), misdn_hangup(), msg_to_json(), multi_object_blob_to_ami(), multi_user_event_to_json(), my_load_module(), my_unload_module(), ooh323_call(), ooh323_indicate(), parking_create_dynamic_lot(), parking_lot_cfg_alloc(), parse_name_andor_addr(), parse_sip_options(), parse_uri(), party_id_write(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_helper(), pbx_builtin_setvar_multiple(), peek_read(), phone_call(), phone_request(), play_message_callerid(), populate_cache(), print_bc_info(), protocol_hash_fn(), proxy_from_config(), publisher_start(), push_callinfo(), pvalAppCallSetAppName(), pvalCatchSetExtName(), pvalContextSetName(), pvalESwitchesAddSwitch(), pvalExtenSetName(), pvalLabelSetName(), pvalMacroCallSetMacroName(), pvalMacroSetName(), pvalSwitchesAddSwitch(), pvalVarDecSetVarname(), realtime_multi_mysql(), realtime_mysql(), realtime_peer_get_sippeer_helper(), record_serializer(), register_verify(), release_chan(), reload(), reload_module(), send_callinfo(), serialize_showchan(), set_hangup_source_and_cause(), set_message_vars_from_req(), set_var_handler(), setup_env(), show_config_description(), show_sounds_cb(), sip_acf_channel_read(), sip_msg_send(), sip_outbound_registration_perform(), sip_prepare_socket(), sip_prune_realtime(), sip_queue_hangup_cause(), skel_level_alloc(), skel_level_hash(), skinny_newcall(), sla_add_trunk_to_station(), sla_build_station(), sla_build_trunk(), sla_find_station(), sla_find_trunk(), softhangup_exec(), sorcery_config_open(), sorcery_destructor(), sorcery_field_default_handler(), sorcery_realtime_open(), start_monitor_action(), stasis_app_device_state_delete(), stasis_app_device_states_to_json(), state_alloc(), state_notify_build_xml(), stop_monitor_action(), threadstorage_init(), tps_hash_cb(), transmit_registerrej(), transport_state2str(), transport_tls_cipher_handler(), tzload(), tzparse(), unistim_indicate(), unistim_new(), unload_dynamic_module(), unload_module(), update_call_counter(), update_connectedline(), user_hash_cb(), vars_to_headers(), vm_allocate_dh(), vmsayname_exec(), websocket_client_handshake_get_response(), wizard_apply_handler(), xmldoc_build_final_response(), xmldoc_build_list_responses(), xmpp_cli_create_collection(), xmpp_cli_create_leafnode(), xmpp_cli_delete_pubsub_node(), xmpp_cli_list_pubsub_nodes(), xmpp_cli_purge_pubsub_nodes(), and xpidf_allocate_body().

◆ password

struct ast_str * password = NULL
static

◆ records

int records = 0
static

◆ sql1_buf

struct ast_threadstorage sql1_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql1_buf , .custom_init = NULL , }
static

Definition at line 69 of file cdr_mysql.c.

Referenced by mysql_log().

◆ sql2_buf

struct ast_threadstorage sql2_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql2_buf , .custom_init = NULL , }
static

Definition at line 70 of file cdr_mysql.c.

Referenced by mysql_log().

◆ ssl_ca

struct ast_str* ssl_ca = NULL
static

Definition at line 79 of file cdr_mysql.c.

◆ ssl_cert

struct ast_str * ssl_cert = NULL
static

Definition at line 79 of file cdr_mysql.c.

Referenced by my_connect_db(), my_load_module(), and mysql_log().

◆ ssl_key

struct ast_str * ssl_key = NULL
static

Definition at line 79 of file cdr_mysql.c.

Referenced by my_connect_db(), my_load_module(), and mysql_log().

◆ timeout

int timeout = 0
static
Examples:
/tmp/asterisk-shallow/main/app.c.

Definition at line 86 of file cdr_mysql.c.

Referenced by __analog_ss_thread(), __ast_pbx_run(), __init_manager(), _sip_tcp_helper_thread(), _skinny_message_set(), acf_jabberreceive_read(), action_timeout(), action_waitevent(), aMYSQL_connect(), analog_ss_thread(), ast_app_getdata(), ast_app_getdata_full(), ast_parked_call_payload_create(), ast_readstring_full(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_serializer_pool_create(), ast_serializer_shutdown_group_join(), ast_smdi_md_message_wait(), ast_smdi_mwi_message_wait(), cache_lookup_internal(), cache_save(), cache_save_hint(), chan_pjsip_pvt_dtor(), check_rtp_timeout(), conf_load_config(), conf_run(), config_parse_variables(), control_dial_args_alloc(), dahdi_chan_conf_default(), destroy_all_channels(), dial_exec_full(), endpt_send_request(), fax_detect_attach(), find_cache(), generic_fax_exec(), handle_autohangup(), handle_getdata(), handle_getoption(), handle_speechrecognize(), httpd_helper_thread(), jb_debug_output(), launch_asyncagi(), manager_park(), mgcp_ss(), misdn_check_l2l1(), mp3_exec(), my_connect_db(), my_load_module(), mysql_log(), originate_exec(), page_exec(), parked_call_payload_from_parked_user(), pbx_builtin_waitdigit(), pbx_builtin_waitexten(), play_moh_exec(), read_exec(), readexten_exec(), rtcp_debug_test_addr(), rtp_check_timeout(), set_t38timeout(), sip_check_authtimeout(), sip_tcptls_read(), sla_process_timers(), softmix_mixing_loop(), speech_background(), timed_read(), transmit_audio(), transmit_t38(), and waitfor_exec().

◆ totalrecords

int totalrecords = 0
static

Definition at line 85 of file cdr_mysql.c.

Referenced by handle_cli_cdr_mysql_status(), and mysql_log().

◆ unload_strings

struct unload_strings unload_strings = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static