[Home]

Summary:ASTERISK-29166: CDR_PROP, setting party_a, and expectations
Reporter:Kevin Harwell (kharwell)Labels:
Date Opened:2020-11-16 11:46:34.000-0600Date Closed:
Priority:TrivialRegression?No
Status:Open/NewComponents:CDR/General Functions/func_cdr
Versions:16.14.1 18.0.1 Frequency of
Occurrence
Constant
Related
Issues:
Environment:Attachments:
Description:The [CDR_PROP|https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Function_CDR_PROP] function seemingly allows one to specify which channel is to be _party_a_. However in practice this does not seem to be the case. Or at least it allows picking in such a limited capacity to be of almost no use.

So this is kind of a two-parter:

1) Figure out the use case(s) for when _party_a_ can be set via the function, and actually effect a record. If found then update the documentation. If possible fix any bugs related to setting _party_a_ on a given channel.

2) Potentially make it so setting _party_a_ using the function overrides even the dialer/dialed.

To the second part, that's more of a new feature and after some preliminary code perusal possibly quite invasive. As is, a dialing channel is always _party_a_ and the dialed channel is _party_b_. In order to override this behavior one would have to "swap" the _party_a_ and _party_b_ snapshots on the cdr structure. Finding the various places to do that is not trivial, and a basic swap probably has unforeseen circumstances (we are talking about CDRs here after all).

As a side note, I put Asterisk 12.0.0. as an affected version since it seems like things have been this way since the rewrite.

Current CDR "spec":

https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+CDR+Specification
Comments:By: Ross Beer (rossbeer) 2021-06-24 10:23:06.249-0500

Revisiting this, could a CDR_PROP option be added to keep the CDR 'open' and accounting 'end' time based on the 'party_b' channel lifetime. Therefore only finalise the CDR once the 'party_b' channel has hung up. A lock would also be handy to not update any of the data within the CDR apart from 'end' time.

Having this feature would resolve issues with CDRs created when a call transfer happens and ends both of the potentially chargeable CDRs along time before the channels are hung up.

Looking at the code, not totally understanding the logic, if 'CDR_PROP(party_a)' was set on the outgoing channel should this be taken into consideration here:

{noformat}
/*!
* \brief Check to see if a CDR needs to move to the finalized state because
* its Party A hungup.
*/
static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
{
if (ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
&& is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN)) {
cdr_object_finalize(cdr);
}

if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
&& cdr->fn_table != &finalized_state_fn_table) {
cdr_object_transition_state(cdr, &finalized_state_fn_table);
}
}
{noformat}

Could the above be modified to only call 'cdr_object_finalize(cdr);' if both channels are hung up?

By: Ross Beer (rossbeer) 2021-07-07 06:06:14.049-0500

Looking at [the below code|https://github.com/asterisk/asterisk/blob/6818c3d1d274dd8da973e693e3d98b565a762818/main/cdr.c#L1203-L1208], should the following be changed:

{noformat}
/* Try the Party A flag */
if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
return left;
} else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
return right;
}
{noformat}

The second evaluation appear to not take the left into consideration?

{noformat}
/* Try the Party A flag */
if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
return left;
} else if (!ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
return right;
}
{noformat}

By: Sean Bright (seanbright) 2021-07-07 08:16:36.829-0500

I believe you are correct. Feel free to submit a review.

By: Ross Beer (rossbeer) 2021-07-15 03:24:09.184-0500

Sean thank you for submitting a patch to fixed the 'party a' setting. After testing this still doesn't appear to set the outbound channel to 'party a' as the code appears to prefer the dialled channel to only ever be 'party b'.

The issue asterisk currently has with CDRs is that the 'party b' channel is often the chargeable call, however when a transfer occurs the CDR is ended too soon and therefore it is not possible to account for the whole call length as the following CDRs are corrupt and contain no data about the original calls. This is made worse if two outbound call legs are transfers to each other. This could be classed as a vulnerability in asterisk and present in FreePBX.

Therefore reading documentation the 'party a' feature should be the way around the above issue, if the 'b' channel is set as the master the CDR should continue until the 'b' channel is hung up instead of the 'a' channel which is the default behaviour.