Accessing variable on calling channel

Is there any way to access a variable on the parent channel?

I have played with MASTER_CHANNEL and gotten it work, but the problem is MASTER_CHANNEL is 2 levels up. In other words, I have two Dial(Local/…/n)'s inbetween. I only want to go up to the middle one. I looked through the list of functions but I don’t see anything applicable. Most are related to subroutines and accessing variables in the same channel but down the stack.

Basically, here is a simple example that illustrates the concept:
[context-a]
exten => s,1,Set(CDR(myvar)=1)
same => n,Dial(Local/ext@context-b/n,g)
same => n,Hangup()

[context-b]
exten => s,1,Read(digits)
; set CDR(myvar) on the calling channel to {digits} same => n,Dial(SIP/somethingelse/{digits},g)
same => n,Hangup(${HANGUPCAUSE})

In this case, I am trying to set a CDR variable on the calling channel, and I can’t think of another way to do this as CDR is not accessible after the channel hangs up and returns execution flow to the parent channel. So, how can I access one channel up instead of all the way to the top? Basically, looking for something like PARENT_CHANNEL() instead of MASTER_CHANNEL(), where I could specify the # of channels up to go - similar to the relevant subroutine local peek function.

Any ideas?

https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Function_SHARED

I think there is a system variable, something like BRIDGE_PEER, which provides this information where you are likely to need it, as to the parent channel. Otherwise, copy ${CHANNEL} to a variable with underscore prefixes.

Thanks, David! I’ll look into BRIDGE_PEER.

Regarding, ${CHANNEL}, how would I use that? Even if I know the channel name, how does one modify variables on an arbitrary channel? The SHARED() function cannot be used because that is a separate variable space, so it would not let me get access to the actual channel variables, let alone CDR variables.

You can only get read only access to the actual channel variables.

You need to modify your code so that you use the shared variable for all uses in the parent channel.

How would that be possible, exactly? CDR variables are not modify-able after Dial() returns execution to the calling channel, so I cannot do any “post-processing” in the dialplan. I have to be able to directly modify the CDR variable. Can you think of a way around this?

I missed the CDR part. Those are not channel variables; CDR is a function.

CDRs have been re-implemented since I had any detailed knowledge, but you used to be able to force out a CDR in the h extension. Also you could enable CDRs on the called channel and write your information in one of those.

It seems that can’t be done anymore:

CDRs can only be modified before the bridge between two channels is torn down. For example, CDRs may not be modified after the Dial application has returned.
https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Function_CDR

Which h extension are we talking about here, the called channel (the one without CDR)? I actually have a GoTo in the calling channel so the h extension would not get executed.

If you are continuing on the original channel, this may be difficult.

In the original implementation, at least, there was some jiggery pokery for CDRs in the caller’s h extension. There were actually two CDRs that got swapped around when running the h extension, and you could force a modified one out during that extension, even though the other one would get output normally. However, I think it has all changed.

Also, note that at one stage the aim was to replace CDRs with CEL. I think in the end too many people didn’t move over and they had to rewrite CDRs to behave a bit more like people needed, but I suspect that they still can’t handle complex cases well.

Looking at your example, you are actually using local channels, and the channel that is running dialplan is not the B side channel for the original Dial, so you are even more remote. I suspect underscores are the only way of connecting back, but would suggest that you use the CDR from the local channel and merge it with data from the original channel in your analysis software.

Why do you need a local channel? The example doesn’t seem to need one, but that might be because you simplified it.

You’re right, it was a simple example. In practice, I use Local channels extensively in the dialplan, for reasons that would be difficult to elaborate here. I’m also forced to the use the /n option most of the time to prevent optimization or everything gets screwed up.

In this case, the local channel is a channel-agnostic wrapper around the dial in that local channel. For instance:

[local]
exten => s,1,Dial(SIP/something)

This is one such channel. However, I might have hundreds of these that dial SIP endpoints, other local endpoints, IAX2 endpoints, DAHDI endpoints, whatever.

Regardless, I hang up immediately with the hangup cause code. The calling channel is typically either a direct call to an FX line, tie line, etc. and so in that channel, I then go to a different context to handle the DIALSTATUS (e.g. play reorder if the trunk was busy). In other cases, I may be doing Automatic Route Selection - Deluxe, where if one trunk is busy, I choose a different trunk. In both cases, whatever is calling these end local channels is handling all the CDR. This parent channel is itself spawned from another local channel, which is created using a call file, in a confbridge, by another local channel that was finally called by the original hardware endpoint, but that’s all besides the point.

Part of the rationale for local channels is they “insulate” the CDR, which is necessary in Asterisk. Basically, what I mean is you need to do a Dial(Local/…/n) , do all my CDR there, and then spawn another Dial(Local/…/n) to the actual call itself. Otherwise, if I just did a GoTo(), and then, say, entered a ConfBridge(), the CDR would get all split up.

CEL is not useful to me. I do traditional billing, where all that matters is the start time, the answer time, and the end time. There is no notion of transfers, those are separate calls. Whether the call enters a confbridge is completely irrelevant. The switch is setup to handle billing like a traditional POTS switch, so all of these VoIP concepts have no bearing on anything. Only the answered time matters. So, “simplistic” CDR actually works great for me, generally speaking, because I need nothing more than that and with custom CDR variables, it’s perfect.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.