German language improvements (bug #1606)
[asterisk/asterisk.git] / cdr.c
diff --git a/cdr.c b/cdr.c
index 20b3e2c..67acf10 100755 (executable)
--- a/cdr.c
+++ b/cdr.c
@@ -19,6 +19,9 @@
 #include <asterisk/cdr.h>
 #include <asterisk/logger.h>
 #include <asterisk/callerid.h>
+#include <asterisk/causes.h>
+#include <asterisk/options.h>
+#include <asterisk/utils.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -93,6 +96,8 @@ void ast_cdr_unregister(char *name)
                }
                i = i->next;
        }
+       if (option_verbose > 1)
+               ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s' CDR backend\n", name);
        ast_mutex_unlock(&cdrlock);
        if (i) 
                free(i);
@@ -102,7 +107,7 @@ void ast_cdr_free(struct ast_cdr *cdr)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (!cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' not posted\n", chan);
                if (!cdr->end.tv_sec && !cdr->end.tv_usec)
@@ -127,7 +132,7 @@ void ast_cdr_start(struct ast_cdr *cdr)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (cdr->start.tv_sec || cdr->start.tv_usec)
@@ -140,7 +145,7 @@ void ast_cdr_answer(struct ast_cdr *cdr)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (cdr->disposition < AST_CDR_ANSWERED)
@@ -155,7 +160,7 @@ void ast_cdr_busy(struct ast_cdr *cdr)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (cdr->disposition < AST_CDR_BUSY)
@@ -163,11 +168,46 @@ void ast_cdr_busy(struct ast_cdr *cdr)
        }
 }
 
+void ast_cdr_failed(struct ast_cdr *cdr)
+{
+       char *chan; 
+       if (cdr) {
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
+               if (cdr->posted)
+                       ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
+                       cdr->disposition = AST_CDR_FAILED;
+       }
+}
+
+int ast_cdr_disposition(struct ast_cdr *cdr, int cause)
+{
+       int res = 0;
+       if (cdr) {
+               switch(cause) {
+                       case AST_CAUSE_BUSY:
+                               ast_cdr_busy(cdr);
+                               break;
+                       case AST_CAUSE_FAILURE:
+                               ast_cdr_failed(cdr);
+                               break;
+                       case AST_CAUSE_NORMAL:
+                               break;
+                       case AST_CAUSE_NOTDEFINED:
+                               res = -1;
+                               break;
+                       default:
+                               res = -1;
+                               ast_log(LOG_WARNING, "We don't handle that cause yet\n");
+               }
+       }
+       return res;
+}
+
 void ast_cdr_setdestchan(struct ast_cdr *cdr, char *chann)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                strncpy(cdr->dstchannel, chann, sizeof(cdr->dstchannel) - 1);
@@ -178,7 +218,7 @@ void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data)
 {
        char *chan; 
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (!app)
@@ -219,8 +259,8 @@ int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c)
        char *num, *name;
        char tmp[AST_MAX_EXTENSION] = "";
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
-               if (strlen(cdr->channel)) 
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
+               if (!ast_strlen_zero(cdr->channel)) 
                        ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan); 
                strncpy(cdr->channel, c->name, sizeof(cdr->channel) - 1);
                /* Grab source from ANI or normal Caller*ID */
@@ -260,7 +300,7 @@ void ast_cdr_end(struct ast_cdr *cdr)
 {
        char *chan;
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (!cdr->start.tv_sec && !cdr->start.tv_usec)
@@ -275,6 +315,8 @@ char *ast_cdr_disp2str(int disposition)
        switch (disposition) {
        case AST_CDR_NOANSWER:
                return "NO ANSWER";
+       case AST_CDR_FAILED:
+               return "FAILED";                
        case AST_CDR_BUSY:
                return "BUSY";          
        case AST_CDR_ANSWERED:
@@ -307,32 +349,55 @@ int ast_cdr_setaccount(struct ast_channel *chan, char *account)
        return 0;
 }
 
+int ast_cdr_setuserfield(struct ast_channel *chan, char *userfield)
+{
+       struct ast_cdr *cdr = chan->cdr;
+
+       if (cdr)
+               strncpy(cdr->userfield, userfield, sizeof(cdr->userfield) - 1);
+       return 0;
+}
+
+int ast_cdr_appenduserfield(struct ast_channel *chan, char *userfield)
+{
+       struct ast_cdr *cdr = chan->cdr;
+
+       if (cdr)
+       {
+               int len = strlen(cdr->userfield);
+               strncpy(cdr->userfield+len, userfield, sizeof(cdr->userfield) - len - 1);
+       }
+       return 0;
+}
+
 int ast_cdr_update(struct ast_channel *c)
 {
        struct ast_cdr *cdr = c->cdr;
        char *name, *num;
        char tmp[AST_MAX_EXTENSION] = "";
        /* Grab source from ANI or normal Caller*ID */
-       if (c->ani)
-               strncpy(tmp, c->ani, sizeof(tmp) - 1);
-       else if (c->callerid)
-               strncpy(tmp, c->callerid, sizeof(tmp) - 1);
-       if (c->callerid)
-               strncpy(cdr->clid, c->callerid, sizeof(cdr->clid) - 1);
-       else
-               strcpy(cdr->clid, "");
-       name = NULL;
-       num = NULL;
-       ast_callerid_parse(tmp, &name, &num);
-       if (num) {
-               ast_shrink_phone_number(num);
-               strncpy(cdr->src, num, sizeof(cdr->src) - 1);
+       if (cdr) {
+               if (c->ani)
+                       strncpy(tmp, c->ani, sizeof(tmp) - 1);
+               else if (c->callerid && !ast_strlen_zero(c->callerid))
+                       strncpy(tmp, c->callerid, sizeof(tmp) - 1);
+               if (c->callerid && !ast_strlen_zero(c->callerid))
+                       strncpy(cdr->clid, c->callerid, sizeof(cdr->clid) - 1);
+               else
+                       strcpy(cdr->clid, "");
+               name = NULL;
+               num = NULL;
+               ast_callerid_parse(tmp, &name, &num);
+               if (num) {
+                       ast_shrink_phone_number(num);
+                       strncpy(cdr->src, num, sizeof(cdr->src) - 1);
+               }
+               /* Copy account code et-al */   
+               strncpy(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode) - 1);
+               /* Destination information */
+               strncpy(cdr->dst, c->exten, sizeof(cdr->dst) - 1);
+               strncpy(cdr->dcontext, c->context, sizeof(cdr->dcontext) - 1);
        }
-       /* Copy account code et-al */   
-       strncpy(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode) - 1);
-       /* Destination information */
-       strncpy(cdr->dst, c->exten, sizeof(cdr->dst) - 1);
-       strncpy(cdr->dcontext, c->context, sizeof(cdr->dcontext) - 1);
        return 0;
 }
 
@@ -354,7 +419,7 @@ void ast_cdr_post(struct ast_cdr *cdr)
        char *chan;
        struct ast_cdr_beitem *i;
        if (cdr) {
-               chan = strlen(cdr->channel) ? cdr->channel : "<unknown>";
+               chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
                if (cdr->posted)
                        ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
                if (!cdr->end.tv_sec && !cdr->end.tv_usec)
@@ -379,18 +444,20 @@ void ast_cdr_post(struct ast_cdr *cdr)
 
 void ast_cdr_reset(struct ast_cdr *cdr, int post)
 {
-       /* Post if requested */
-       if (post) {
-               ast_cdr_end(cdr);
-               ast_cdr_post(cdr);
+       if (cdr) {
+               /* Post if requested */
+               if (post) {
+                       ast_cdr_end(cdr);
+                       ast_cdr_post(cdr);
+               }
+               /* Reset to initial state */
+               cdr->posted = 0;
+               memset(&cdr->start, 0, sizeof(cdr->start));
+               memset(&cdr->end, 0, sizeof(cdr->end));
+               memset(&cdr->answer, 0, sizeof(cdr->answer));
+               cdr->billsec = 0;
+               cdr->duration = 0;
+               ast_cdr_start(cdr);
+               cdr->disposition = AST_CDR_NOANSWER;
        }
-       /* Reset to initial state */
-       cdr->posted = 0;
-       memset(&cdr->start, 0, sizeof(cdr->start));
-       memset(&cdr->end, 0, sizeof(cdr->end));
-       memset(&cdr->answer, 0, sizeof(cdr->answer));
-       cdr->billsec = 0;
-       cdr->duration = 0;
-       ast_cdr_start(cdr);
-       cdr->disposition = AST_CDR_NOANSWER;
 }