[asterisk-users] Modifying CDR values from a hangup extension in Asterisk 13

Olivier oza.4h07 at gmail.com
Wed Feb 21 15:19:28 CST 2018


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 <oza.4h07 at gmail.com>:

> 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 <mjordan at digium.com>:
>
>>
>> On Tue, Aug 4, 2015 at 9:16 AM, Filip Jenicek <fjenicek at kerio.com> wrote:
>>
>>> With endbeforehexten=no I actually get two CDR entries. One for the call
>>> and a second one for the "h" extension.
>>> "","13","10","sip-locals","""13"" <13>","SIP/13-00000006","SIP/1
>>> 0-00000007","Dial","SIP/10","2015-08-04 06:28:44","2015-08-04
>>> 06:28:45","2015-08-04 06:28:47",3,1,"ANSWERED","DOCU
>>> MENTATION","1438669724.6","empty"
>>> "","13","h","sip-locals","""13"" <13>","SIP/13-00000006","","NoOp","changed","2015-08-04
>>> 06:28:47","2015-08-04 06:28:47","2015-08-04 06:28:47",0,0,"ANSWERED","DOCU
>>> MENTATION","1438669724.6","changed"
>>> The first one contains the call itself. There are durations, CDR
>>> variables set during the call, etc.
>>> The second one contains only things configured in the "h" extension.
>>>
>>> With endbeforehexten=yes, the cdr contains:
>>> "","13","10","sip-locals","""13"" <13>","SIP/13-00000006","SIP/1
>>> 0-00000007","Dial","SIP/10","2015-08-04 06:28:44","2015-08-04
>>> 06:28:45","2015-08-04 06:28:47",3,1,"ANSWERED","DOCU
>>> MENTATION","1438669724.6","empty"
>>> There is only the call, nothing from the "h" extension.
>>>
>>> I forgot to mention that I'm using Asterisk 13.1-cert2. Modifying CDR
>>> records in the "h" extension used to work fine with Asterisk 1.8.
>>>
>>> By analyzing the code I must confirm that the endbeforehexten option
>>> behaves exactly according to its description:
>>>  As each CDR for a channel is finished, its end time is updated
>>>  and the CDR is finalized. When a channel is hung up and hangup
>>>  logic is present (in the form of a hangup handler or the
>>>  <literal>h</literal> extension), a new CDR is generated for the
>>>  channel. Any statistics are gathered from this new CDR. By enabling
>>>  this option, no new CDR is created for the dialplan logic that is
>>>  executed in <literal>h</literal> extensions or attached hangup handler
>>>  subroutines. The default value is <literal>yes</literal>, indicating
>>>  that a CDR will be generated during hangup logic.</para>
>>>
>>> I tried to delay the "h" extension by several seconds and I found out,
>>> that the CDR record is sent to the cdr backend later. Unfortunately, it is
>>> not modifiable from the "h" extension, because the cdr_object is already in
>>> the finalized table.
>>>
>>> Is there a way how to modify the CDR without hacking the code?
>>>
>>>
>> Unfortunately, no.
>>
>>
>>> How bad idea is it to comment the (it_cdr->fn_table ==
>>> &finalized_state_fn_table) tests in ast_cdr_setuserfield and ast_cdr_setvar
>>> and thus allow the "h" extension write to a finalized CDR?
>>>
>>>
>> 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.
>>
>>
>>
>>> Is there any chance the feature was left out by an accident and if so,
>>> is there a plan to add it again?
>>>
>>>
>>> My extensions.conf:
>>> exten => h,1,NoOp(${CDR(userfield)})
>>> exten => h,n,Set(CDR(userfield)=changed)
>>> exten => h,n,NoOp(${CDR(userfield)})
>>> exten => h,n,System(sleep 5)
>>> exten => h,n,NoOp(${CDR(userfield)})
>>> exten => 10,1,Set(CDR(userfield)=empty)
>>> exten => 10,n,Dial(SIP/10)
>>>
>>> Detailed log:
>>> http://pastebin.com/fZ9RAhL4
>>>
>>>
>>>
>> 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
>>
>>
>>
>>>
>>> On 08/03/2015 04:36 PM, jg wrote:
>>>
>>>
>>> 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?
>>>
>>> I am not working with h-extensions myself, but the docs (
>>> <https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Configuration_cdr>
>>> https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Configuration_cdr)
>>> say something like this:
>>>
>>> endbeforehexten
>>> <https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Configuration_cdr#Asterisk13Configuration_cdr-general_endbeforehexten>
>>>
>>> Boolean
>>>
>>> 1
>>>
>>> false
>>>
>>> Don't produce CDRs while executing hangup logic
>>>
>>> This would indicate that at least writing is disabled.
>>>
>>> jg
>>>
>>>
>>>
>>>
>>> --
>>> _____________________________________________________________________
>>> -- Bandwidth and Colocation Provided by http://www.api-digital.com --
>>> New to Asterisk? Join us for a live introductory webinar every Thurs:
>>>                http://www.asterisk.org/hello
>>>
>>> asterisk-users mailing list
>>> To UNSUBSCRIBE or update options visit:
>>>    http://lists.digium.com/mailman/listinfo/asterisk-users
>>>
>>
>>
>>
>> --
>> Matthew Jordan
>> Digium, Inc. | Director of Technology
>> 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
>> Check us out at: http://digium.com & http://asterisk.org
>>
>> --
>> _____________________________________________________________________
>> -- Bandwidth and Colocation Provided by http://www.api-digital.com --
>> New to Asterisk? Join us for a live introductory webinar every Thurs:
>>                http://www.asterisk.org/hello
>>
>> asterisk-users mailing list
>> To UNSUBSCRIBE or update options visit:
>>    http://lists.digium.com/mailman/listinfo/asterisk-users
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-users/attachments/20180221/93233c59/attachment.html>


More information about the asterisk-users mailing list