[asterisk-users] Simple CDRs

Steve Murphy murf at digium.com
Wed Jan 7 12:01:33 CST 2009


The continuing discussion on a future "Simple CDR" mode of generation...
from which I will extract the info and add a section to the
overall CDR spec I'm developing...

For newcomers, "Simple CDR" mode would not break the conversations
into legs at all. Each CDR would simply record the total time 
spent alive. It would start when the channel got created. It would 
end, and the CDR get posted, when the channel got hung up and 
destroyed. It might have been transferred, parked, put on hold
a hundred times in the process, but this wouldn't matter.

It's all in the CDR fields, now, really, as the conversation
continues...


On Wed, 2009-01-07 at 02:56 +0000, Grey Man wrote:
> On Tue, Jan 6, 2009 at 3:53 PM, Steve Murphy <murf at digium.com> wrote:
> > As to Answers, we have to start getting pedantic; if A is an exten,
> > then the first answer will be when B answers. But if A is an incoming
> > call via, say a dahdi fxo interface, or an incoming sip invite, then
> > an s exten is going to get run, and usually the PBX runs the answer()
> > app, and this will usually be the first answer. Now, I can use heuristics
> > to override this first answer if a dial occurs, but... if multiple dials
> > occur, this heuristic would tend to record the last answer; if we
> > override only Answer() in the 's' exten, then we would only record
> > the first answer... is this more like it?
> 
> That sounds a bit dangerous to me. If you go down the path of setting
> the answer time based on dial plan applications or events you'll need
> to understand and modify every dial plan application that can answer a
> call. To me it would seem a lot simpler to do the
> override/modification in each channel or even better even lower in
> ast_channel. A channel has to have a very clearly defined definition
> of answer and hangup whereas dial plan applications don't.
> 

Hadn't thought along that line before: classifying the *kinds* of
Answer.
But we may not have to bother.... In this mode, a single CDR could
cover several dial attempts and their corresponding "answers"....
incoming caller A could, during his lifetime in Asterisk, dial
several users, say via assisted xfers, and have the targets hang up
first, leaving his channel intact. It doesn't make sense to store an
outgoing dial result in the originating channel CDR....

What if, instead, we record the disposition of the dial in the created
channel CDR? A channel comes into existence only once. For external
incoming
calls into the PBX, the disposition is pretty uninteresting, because
we'd
not create the channel if the disposition wasn't ANSWERED... (well, at
least
in the DAHDI world, maybe not so much in the voip world)... but,
once asterisk dials B in A's behalf, we could record all the dialing
action
in the CDR for B; It's src/dest related fields could record the dial
from
A to B; the disposition would be FAIL/BUSY/NOANSWER/etc... 

> > Oh, and BUSY/NO ANSWER/FAIL for a non-s exten, would also override
> > an ANSWER on exten s, BTW...
> >
> > And, would it be proper to include all dial attempts? My guess is
> > that you would *NOT* want to see any dial attempts in this mode. Well,
> > at least, in this particular case, if A *tries* to dial B, but B
> > doesn't answer, then since A is a live channel, we would record
> > it's life in the system. When A hangs up, we would see the NO ANSWER
> > disposition, and the destination of B, right? If A tried to dial a
> > group, and nobody answered, the destination would be a random member
> > of that group, the args to the Dial command would record the other
> > members, usually.
> 
> I liked you previous approach where all call attempts were recorded
> and there was a config option to opt out of CDRs for non-answered
> calls for people that didn't want them. When the Dial command
> specifies multiple destinations then there should be one CDR for each
> destination that is dialled irrespective of whether it is answered or
> not. A disposition of something like CANCELLED could be set for the
> dial legs that Asterisk cancels after the first one is answered.
> 
> As an example consider the standard call scenario where a user calls
> into Asterisk and the dialplan forwards the call to 3 destinations:
> 
> User A --> Asterisk: Dial(SIP/x&SIP/y&SIP/z) --> SIP/y answers
> 
> That should generate 4 CDRs:
> 
> 1. A to Asterisk which is answered,
> 2. Asterisk to X which is cancelled,
> 3. Asterisk to Y which is answered,
> 4. Asterisk ti Z which is cancelled.
> 

I like the CANCELLED idea.... another disposition!

OK, if you set the unanswered=yes, like I have it now, you'd see
the CDR's with CANCELLED, otherwise, you would only see the... wait...
this brings up some pretty tangled issues. If I'm going to explain
channel creation for dialing... especially when you dial more than one
target at once...

Let's say you do your examp, but we add exten dev SIP/w to the 
list for variety; 
suppose:

W just plain doesn't ANSWER
X is offline, so it's FAIL;
Y gets answered;
Z is busy

If you have unanswered = yes, then you'd expect to see:

1. A to Asterisk which is answered (by the dialplan)
2. Asterisk to X which is FAIL
3. Asterisk to Y which is answered,
4. Asterisk to Z which is BUSY
5. Asterisk to W which is cancelled

But if you have unanswered = no, then I guess you'd just see:
1. A to Asterisk which is answered (by the dialplan),
2. Asterisk to X which is FAIL
3. Asterisk to Y which is answered,
4. Asterisk to Z which is BUSY

or would unanswered = no also suppress #2 and #4?

And, if no one answers any call, we'd see (with unanswered = yes)

1. A to Asterisk which is answered (by the dialplan)
2. Asterisk to X which is FAIL
3. Asterisk to Y which is NO ANSWER,
4. Asterisk to Z which is BUSY
5. Asterisk to W which is cancelled

and, if unanswered = no, then we get: ?

1. A to Asterisk which is answered (by the dialplan)
2. Asterisk to X which is FAIL
3. Asterisk to Y which is NO ANSWER,
4. Asterisk to Z which is BUSY

Since there was no single winner, would we suppress 2,3,and 4
as well as 5? As if no call were made at all? Why are we 
prejudiced against just CANCELLED?

All I know is, if we are going to record NO ANSWER for calls (or want
to),
then we'd have to report them for all the losers if there is more than
one target for the dial... 

Since incomplete calls (are not)/(may not be)  interesting to billing do
we
just drop everything but ANSWERED when unanswered = no?


> > OK, gotcha. Now, let's talk about the fields in current/future CDRs,
> > and see which you consider relevant?
> 
> The core fields I would put into the Asterisk CDRs are:
> 
> - uniqueid: A GUID/UUID that cannot be changed and is critical for billing,

In my previous message, I proposed that we could add some config options
that would define uniqueid/linkedid behavior, let's get explicit:

unique_append_ident=<string>

The <string> would be appended to the unique id/linked id when it
goes "out the door"; This would allow you to tack on a system name
or ip or whatever to every uniqueid/linkedid as it goes into the db/log
file/whatever; if you had several systems logging to the same db,
you could guarantee that the id's were unique across systems that way.

unique_append_uuid = yes
  would append the uuid (all 36 bytes of it)
  to the uniqueID/linkedid. This uuid is calculated once per Asterisk
  invocation;

unique_append_uuid = per_channel
  would append the uuid (all 36 bytes of it)
  to the uniqueID/linkedid. This uuid is calculated once per
  channel created.

Will this suffice?


> - calldirection: 0 for a call Asterisk receives and 1 for a call
> Asterisk initiates,

Interesting. How exactly do we calculate this? How do we tell 
an incoming FXO call from an incoming FXS call? The FXS lines
will get special attention from asterisk; dialtone is generated,
we are waiting for an extension in the dialplan. FXO calls 
start at the 's' extension... the channel driver, I guess, knows
the diff... but higher up?  And I've been reminded that the
FXO isn't automatically mean that the call is incoming... and
vice-versa,
so... this is logic external to CDRs, methinks? As to 
SIP, I guess anything that's not a SIP peer (via sip.conf) is an 
incoming call? All the time? Guaranteed?

> - accountcode (user modifiable)
> - clid: The channel identifier of the call originator equivalent to
> the A number on a traditional telco CDR,

Actually, the underlying CEL interface will report ANI, DNIS, etc.
so all these fields are available. I think it would be wise to 
report (or at least allow) all these values.

> - dst: The destination of the call equivalent to the B number on a
> traditional telco CDR,

I think this is the destination exten. 

You might want to add the channel, dstchannel, which record the
originator/target device info.


> - starttime: The time Asterisk first receives or initiates a call,


> - progresstime: The time Asterisk first receives or generates a
> progress indication,

This is useful? I'd have to add this every driver; some may not 
provide it (maybe)... this is pretty deep-down stuff. How is it
useful?


> - answertime: The time a call is answered,
> - endtime: The time a call is hungup or cancelled,
> - duration: endtime - starttime,
> - billsec: endtime - answertime,
> - disposition: ANSWERED, TIMEOUT, CANCELLED, HUNGUP and maybe others,

ANSWERED, NO_ANSWER, FAILED, BUSY, CANCELLED I understand,
but you'll have to explain HUNGUP...

While we are at it, how about hangupcause? Hangup originator?


> - userfield (user modifiable): General purpose field for any custom
> CDR info needed by Asterisk users.
> 
> Some extra fields that I think would also be very (if not very very)
> useful to people:
> 
> - remoteip: The remote IP address of the call where relevant. For an
> incoming call the originator's IP address, for an outgoing call the
> desitanation IP address.Apart from being very useful information it
> would also be one piece of information useulf in identifying brute
> force or DoS attacks,
> 

This would be good info from the voip related protocols... it seems
reasonable to add this, but I kinda wonder how hard this will be to
coax from the channel drivers... I have to look and see if this stored
on the channel... never played with it before.

> - linkedid: Where there is a logical link between different calls such
> as an incoming call generating an outgoing call this field could be a
> common UUID/GUID.This field is not as important as the core ones so if
> there are situations where it becomes ambiguous or doesn't make sense
> it could be ignored,
> 
> - channel: The data that was passed to the channel driver for a call.

you probably mean the lastapp/lastdata fields here. I think we may
need to look at these fields a little closer. There are several places
in the code where a dial-type-operation is performed, but the Dial() app
is not called to do it... followme, queues, call files, ami originate,
places like that. It might be good to have the method of making the
call recorded in the CDR in the lastapp field; like queue#Dial
park#Dial,
CallFile#Dial, etc.

Also, you left out the "party" field... If A calls in, and dials B,
(well, asterisk dials B in A's behalf), and B xfers A to C, then,
wouldn't you be at all interested in the fact, that even tho B called
C, it was A that spent all the time on the line? Eh, I guess it wouldn't
really matter, would it? If C was in Namibia, would B always be billed
for the call, or would anyone ever be tempted to bill A's dept for that
call? (Assuming, I guess, that A & B are both internal)...



murf

> 
> Regards,
> 
> Greyman.

-- 
Steve Murphy <murf at digium.com>
Digium
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3227 bytes
Desc: not available
Url : http://lists.digium.com/pipermail/asterisk-users/attachments/20090107/69e0c82f/attachment.bin 


More information about the asterisk-users mailing list