Replace most uses of ast_register_atexit with ast_register_cleanup.
[asterisk/asterisk.git] / main / cdr.c
index dcee00d..5e24dae 100644 (file)
@@ -98,19 +98,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                                        </description>
                                </configOption>
                                <configOption name="unanswered">
-                                       <synopsis>Log calls that are never answered.</synopsis>
-                                       <description><para>Define whether or not to log unanswered calls. Setting this to "yes" will
-                                       report every attempt to ring a phone in dialing attempts, when it was not
-                                       answered. For example, if you try to dial 3 extensions, and this option is "yes",
-                                       you will get 3 CDR's, one for each phone that was rung. Some find this information horribly
-                                       useless. Others find it very valuable. Note, in "yes" mode, you will see one CDR, with one of
-                                       the call targets on one side, and the originating channel on the other, and then one CDR for
-                                       each channel attempted. This may seem redundant, but cannot be helped.</para>
-                                       <para>In brief, this option controls the reporting of unanswered calls which only have an A
-                                       party. Calls which get offered to an outgoing line, but are unanswered, are still
-                                       logged, and that is the intended behavior. (It also results in some B side CDRs being
-                                       output, as they have the B side channel as their source channel, and no destination
-                                       channel.)</para>
+                                       <synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
+                                       <description><para>
+                                       Define whether or not to log unanswered calls that don't involve an outgoing party. Setting
+                                       this to "yes" will make calls to extensions that don't answer and don't set a side B channel
+                                       (such as by using the Dial application) receive CDR log entries. If this option is set to
+                                       "no", then those log entries will not be created. Unanswered calls which get offered to an
+                                       outgoing line will always receive log entries regardless of this option, and that is the
+                                       intended behavior.
+                                       </para>
                                        </description>
                                </configOption>
                                <configOption name="congestion">
@@ -215,9 +211,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #define CDR_DEBUG(mod_cfg, fmt, ...) \
        do { \
-       if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
-               ast_verb(1, (fmt), ##__VA_ARGS__); \
-       } } while (0)
+               if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
+                       ast_verbose((fmt), ##__VA_ARGS__); \
+               } \
+       } while (0)
 
 static void cdr_detach(struct ast_cdr *cdr);
 static void cdr_submit_batch(int shutdown);
@@ -692,6 +689,8 @@ struct cdr_object {
                AST_STRING_FIELD(bridge);           /*!< The bridge the party A happens to be in. */
                AST_STRING_FIELD(appl);             /*!< The last accepted application party A was in */
                AST_STRING_FIELD(data);             /*!< The data for the last accepted application party A was in */
+               AST_STRING_FIELD(context);          /*!< The accepted context for Party A */
+               AST_STRING_FIELD(exten);            /*!< The accepted extension for Party A */
        );
        struct cdr_object *next;                /*!< The next CDR object in the chain */
        struct cdr_object *last;                /*!< The last CDR object in the chain */
@@ -1115,8 +1114,8 @@ static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
                ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
                ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
                ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
-               ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
-               ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
+               ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
+               ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
 
                /* Party B */
                if (party_b) {
@@ -1258,11 +1257,11 @@ static void cdr_object_finalize(struct cdr_object *cdr)
        /* tv_usec is suseconds_t, which could be int or long */
        ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
                        cdr->party_a.snapshot->name,
-                       cdr->start.tv_sec,
+                       (long)cdr->start.tv_sec,
                        (long)cdr->start.tv_usec,
-                       cdr->answer.tv_sec,
+                       (long)cdr->answer.tv_sec,
                        (long)cdr->answer.tv_usec,
-                       cdr->end.tv_sec,
+                       (long)cdr->end.tv_sec,
                        (long)cdr->end.tv_usec,
                        ast_cdr_disp2str(cdr->disposition));
 }
@@ -1297,7 +1296,7 @@ static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
                cdr->answer = ast_tvnow();
                /* tv_usec is suseconds_t, which could be int or long */
                CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
-                       cdr->answer.tv_sec,
+                       (long)cdr->answer.tv_sec,
                        (long)cdr->answer.tv_usec);
        }
 }
@@ -1353,6 +1352,17 @@ static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snaps
                cdr_object_check_party_a_hangup(cdr);
                return 0;
        }
+
+       /*
+        * Only record the context and extension if we aren't in a subroutine, or if
+        * we are executing hangup logic.
+        */
+       if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
+               || ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
+               ast_string_field_set(cdr, context, snapshot->context);
+               ast_string_field_set(cdr, exten, snapshot->exten);
+       }
+
        cdr_object_swap_snapshot(&cdr->party_a, snapshot);
 
        /* When Party A is originated to an application and the application exits, the stack
@@ -3373,6 +3383,10 @@ int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
                }
                new_cdr->fn_table = cdr_obj->fn_table;
                ast_string_field_set(new_cdr, bridge, cdr->bridge);
+               ast_string_field_set(new_cdr, appl, cdr->appl);
+               ast_string_field_set(new_cdr, data, cdr->data);
+               ast_string_field_set(new_cdr, context, cdr->context);
+               ast_string_field_set(new_cdr, exten, cdr->exten);
                new_cdr->flags = cdr->flags;
                /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
                 * the application to be changed on the new CDR if the
@@ -3502,7 +3516,7 @@ static int submit_scheduled_batch(const void *data)
        /* manually reschedule from this point in time */
 
        ast_mutex_lock(&cdr_sched_lock);
-       cdr_sched = ast_sched_add(sched, mod_cfg->general->batch_settings.size * 1000, submit_scheduled_batch, NULL);
+       cdr_sched = ast_sched_add(sched, mod_cfg->general->batch_settings.time * 1000, submit_scheduled_batch, NULL);
        ast_mutex_unlock(&cdr_sched_lock);
        /* returning zero so the scheduler does not automatically reschedule */
        return 0;