Merge "Revert "AGI: Only defer frames when in an interception routine.""
[asterisk/asterisk.git] / cdr / cdr_tds.c
index 4fcccae..f3d0628 100644 (file)
@@ -59,12 +59,11 @@ CREATE TABLE [dbo].[cdr] (
 
 /*** MODULEINFO
        <depend>freetds</depend>
+       <support_level>extended</support_level>
  ***/
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include "asterisk/config.h"
 #include "asterisk/channel.h"
 #include "asterisk/cdr.h"
@@ -87,6 +86,7 @@ struct cdr_tds_config {
                AST_STRING_FIELD(table);
                AST_STRING_FIELD(charset);
                AST_STRING_FIELD(language);
+               AST_STRING_FIELD(hrtime);
        );
        DBPROCESS *dbproc;
        unsigned int connected:1;
@@ -149,7 +149,36 @@ retry:
        }
 
        if (settings->has_userfield) {
-               erc = dbfcmd(settings->dbproc,
+               if (settings->hrtime) {
+                       double hrbillsec = 0.0;
+                       double hrduration;
+
+                       if (!ast_tvzero(cdr->answer)) {
+                               hrbillsec = (double)(ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0);
+                       }
+                       hrduration = (double)(ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0);
+
+                       erc = dbfcmd(settings->dbproc,
+                                        "INSERT INTO %s "
+                                        "("
+                                        "accountcode, src, dst, dcontext, clid, channel, "
+                                        "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
+                                        "billsec, disposition, amaflags, uniqueid, userfield"
+                                        ") "
+                                        "VALUES "
+                                        "("
+                                        "'%s', '%s', '%s', '%s', '%s', '%s', "
+                                        "'%s', '%s', '%s', %s, %s, %s, %lf, "
+                                        "%lf, '%s', '%s', '%s', '%s'"
+                                        ")",
+                                        settings->table,
+                                        accountcode, src, dst, dcontext, clid, channel,
+                                        dstchannel, lastapp, lastdata, start, answer, end, hrduration,
+                                        hrbillsec, ast_cdr_disp2str(cdr->disposition), ast_channel_amaflags2string(cdr->amaflags), uniqueid,
+                                        userfield
+                       );
+               } else {
+                       erc = dbfcmd(settings->dbproc,
                                         "INSERT INTO %s "
                                         "("
                                         "accountcode, src, dst, dcontext, clid, channel, "
@@ -165,11 +194,40 @@ retry:
                                         settings->table,
                                         accountcode, src, dst, dcontext, clid, channel,
                                         dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
-                                        cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid,
+                                        cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_channel_amaflags2string(cdr->amaflags), uniqueid,
                                         userfield
                        );
+               }
        } else {
-               erc = dbfcmd(settings->dbproc,
+               if (settings->hrtime) {
+                       double hrbillsec = 0.0;
+                       double hrduration;
+
+                       if (!ast_tvzero(cdr->answer)) {
+                               hrbillsec = (double)(ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0);
+                       }
+                       hrduration = (double)(ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0);
+
+                       erc = dbfcmd(settings->dbproc,
+                                        "INSERT INTO %s "
+                                        "("
+                                        "accountcode, src, dst, dcontext, clid, channel, "
+                                        "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
+                                        "billsec, disposition, amaflags, uniqueid"
+                                        ") "
+                                        "VALUES "
+                                        "("
+                                        "'%s', '%s', '%s', '%s', '%s', '%s', "
+                                        "'%s', '%s', '%s', %s, %s, %s, %lf, "
+                                        "%lf, '%s', '%s', '%s'"
+                                        ")",
+                                        settings->table,
+                                        accountcode, src, dst, dcontext, clid, channel,
+                                        dstchannel, lastapp, lastdata, start, answer, end, hrduration,
+                                        hrbillsec, ast_cdr_disp2str(cdr->disposition), ast_channel_amaflags2string(cdr->amaflags), uniqueid
+                       );
+               } else {
+                       erc = dbfcmd(settings->dbproc,
                                         "INSERT INTO %s "
                                         "("
                                         "accountcode, src, dst, dcontext, clid, channel, "
@@ -185,8 +243,9 @@ retry:
                                         settings->table,
                                         accountcode, src, dst, dcontext, clid, channel,
                                         dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
-                                        cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid
+                                        cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_channel_amaflags2string(cdr->amaflags), uniqueid
                        );
+               }
        }
 
        if (erc == FAIL) {
@@ -299,11 +358,11 @@ static int execute_and_consume(DBPROCESS *dbproc, const char *fmt, ...)
        va_end(ap);
 
        if (dbfcmd(dbproc, buffer) == FAIL) {
-               free(buffer);
+               ast_free(buffer);
                return 1;
        }
 
-       free(buffer);
+       ast_free(buffer);
 
        if (dbsqlexec(dbproc) == FAIL) {
                return 1;
@@ -357,7 +416,7 @@ static int mssql_connect(void)
                goto failed;
        }
 
-       if (execute_and_consume(settings->dbproc, "SELECT 1 FROM [%s]", settings->table)) {
+       if (execute_and_consume(settings->dbproc, "SELECT 1 FROM [%s] WHERE 1 = 0", settings->table)) {
                ast_log(LOG_ERROR, "Unable to find table '%s'\n", settings->table);
                goto failed;
        }
@@ -382,6 +441,10 @@ failed:
 
 static int tds_unload_module(void)
 {
+       if (ast_cdr_unregister(name)) {
+               return -1;
+       }
+
        if (settings) {
                ast_mutex_lock(&tds_lock);
                mssql_disconnect();
@@ -391,8 +454,6 @@ static int tds_unload_module(void)
                ast_free(settings);
        }
 
-       ast_cdr_unregister(name);
-
        dbexit();
 
        return 0;
@@ -502,6 +563,13 @@ static int tds_load_module(int reload)
                ast_string_field_set(settings, table, "cdr");
        }
 
+       ptr = ast_variable_retrieve(cfg, "global", "hrtime");
+       if (ptr && ast_true(ptr)) {
+               ast_string_field_set(settings, hrtime, ptr);
+       } else {
+               ast_log(LOG_NOTICE, "High Resolution Time not found, using integers for billsec and duration fields by default.\n");
+       }
+
        mssql_disconnect();
 
        if (mssql_connect()) {
@@ -561,8 +629,10 @@ static int unload_module(void)
        return tds_unload_module();
 }
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "FreeTDS CDR Backend",
-               .load = load_module,
-               .unload = unload_module,
-               .reload = reload,
-              );
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "FreeTDS CDR Backend",
+       .support_level = AST_MODULE_SUPPORT_EXTENDED,
+       .load = load_module,
+       .unload = unload_module,
+       .reload = reload,
+       .load_pri = AST_MODPRI_CDR_DRIVER,
+);