Modifying CDR Values From A Hangup Extension In Asterisk 13

Home » Asterisk Users » Modifying CDR Values From A Hangup Extension In Asterisk 13
Asterisk Users 6 Comments

I’m trying to migrate from Asterisk 1.8 to Asterisk 13 and can’t figure this one out. I’m pretty sure the question has been already asked, but I failed to find a solution.

Can you modify CDR values in an h-extension?

My cdr.conf contains:

[general]
enable=yes
unanswered=yes
endbeforehexten=yes
initiatedseconds=no
batch=no

The diaplan contains a simple “h” extension

exten => h,1,NoOp(${CDR(userfield)})
exten => h,n,Set(CDR(userfield)=changed)
exten => h,n,NoOp(${CDR(userfield)})

In the same context I execute:
exten => 10,1,Set(CDR(userfield)=empty)
exten => 10,n,Dial(SIP/10)

The “h” extension outputs two lines with userfield set to “empty”. I
would expect the second one to be “changed”. It seems that I can read the CDR values, but I can’t change them. Is it a bug or a design thing?
Am I missing something?

6 thoughts on - Modifying CDR Values From A Hangup Extension In Asterisk 13

  • Unfortunately, no.

    Well… I’m not sure 🙂

    As the guy who signed himself up for the dubious honour of porting the CDR
    code to Asterisk 13 – and trying to figure out a consistent way to make it work – I err’d on the side of extreme caution. That is, if someone could make a mess of things, I should probably try to keep it from happening.

    A CDR can be finalized in a variety of ways:
    – Due to someone leaving a bridge
    – Due to a channel being hung up
    – Due to the CDR being forked

    Of those, modifying values is generally dangerous only in the “fork”
    scenario, as it may result in a CDR that a user ‘ended’ being modified. This is a concern when, as updating a value on a CDR walks the entire chain of CDRs, for all CDRs related to the channel:

    for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
    ao2_lock(cdr);
    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
    struct varshead *headp = NULL;

    if (it_cdr->fn_table == &finalized_state_fn_table) {
    continue;
    }
    if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
    headp = &it_cdr->party_a.variables;
    } else if (it_cdr->party_b.snapshot
    && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
    headp = &it_cdr->party_b.variables;
    }
    if (headp) {
    set_variable(headp, name, value);
    }
    }
    }
    ao2_iterator_destroy(it_cdrs);

    Currently, the fact that the CDR is in the finalized state is what prevents that value from being updated on CDRs that are effectively “closed.”

    Now, all of that being said: this is one of those cases where the current behaviour – which is handling an extreme edge case – feels worse than ignoring that edge case. It’s not like we let folks update “core” CDR
    values in any case, so you aren’t in any danger of changing the billsec on a forked CDR. The worst that happens is you update the userfield on forked
    & closed CDRs when you didn’t think it would update, in which case I
    suppose you could just use another field. Or read it first and append it from the dialplan.

    I’d be fine if you’d like to open an issue for it. If you have a patch ready that modifies the behaviour, feel free to post it for review on Gerrit as well [1].

    [1] https://wiki.asterisk.org/wiki/display/AST/Code+Review

  • Hi,

    Reading this old thread, may I ask if keeping hangup handlers from updating CDR values still enforced in Asterisk 15 ?
    If positive, would it be very complex to add in Asterisk, a configuration option allowing a system administrator to list in cdr.conf, the CDR fields allowed to be updated in hangup handlers ?

    I’m planning to store some RTCP stats. Saving them in CDR(userfield) would be perfect.

    Cheers

    2015-08-10 15:05 GMT+02:00 Matthew Jordan :

  • As a complement to my previous post, may I add that I observed the following behaviours:

    1. On one system (Debian Stretch/asterisk 13.19 compiled from source), hangup causes are correctly saved in a custom CDR column.

    2. On an other system (Debian Stretch/packaged asterisk), some rtcp stats are not-correctly saved in a custom CDR column (I also tried unsuccessfully with userfield column).

    In both cases:
    – CDR updates are triggered by a hangup handler pushed with CHANNEL(hangup-handler-push).
    – CDR are saved through ODBC i, aMariaDB or Postgres database.

    Toughts ?

    2018-02-21 0:07 GMT+01:00 Olivier :

  • Hello,

    Digging a bit further, having a local cdr_custom CSV seems to make updatings work !
    I did have enough time to properly test this and become more affirmative but it seems to depend on active CDR backend;

    2018-02-21 22:19 GMT+01:00 Olivier :