Question on adding custom code to start of "from-internal" context

This is a question for any FreePBX/Asterisk dialplan experts in the crowd.

Let’s suppose you want to add some code at the very start of the “from-internal” context. I realize you can create your own “from-internal” context in extensions_override_freepbx.conf but the pitfall there is that if the original from-internal ever changes, your “override” from-internal won’t track it.

The original from-internal is as follows (comments removed):

[from-internal]
include => from-internal-noxfer
include => from-internal-xfer
include => bad-number ; auto-generated

The two contexts mentioned in the includes are as follows:

[from-internal-noxfer]
include => from-internal-noxfer-custom
include => from-internal-noxfer-additional ; auto-generated
[from-internal-xfer]
include => from-internal-custom
include => from-internal-additional ; auto-generated
exten => s,1,Macro(hangupcall)
exten => h,1,Macro(hangupcall)

Now if a call gets transferred, it calls from-internal-xfer rather than from-internal. So if I want to do something (set a variable, perhaps) regardless of whether a call is directly dialed from an extension or transferred, I assume I could do this in extensions_custom.conf:

[from-internal-noxfer-custom]
exten => s,1,Macro(setmyvariable)
(… what goes here, if anything? …)
[from-internal-custom]
exten => s,1,Macro(setmyvariable)
(… what goes here, if anything? …)

Basically what I want to do in the -custom contexts is return to the normal from-internal call flow after the call to the macro returns. But since this was called using an include, I’m not sure what I’m supposed to do - since is not a macro or subroutine call, it doesn’t “return”, correct? So on the next line after the macro call, would it be more correct to:

  1. Just end the context with no additional statement, and the original from-internal-whichever context will continue to the next include?
  2. Insert the next line from the original context (“include => from-internal-whichever-additional”)
  3. Insert a goto that jumps to whatever would have been the next thing included in the original context ("exten _.,1,Goto(from-internal-whichever-additional,${exten},1)

Or something else entirely?

I just get a little confused on the differences between includes, macros, and gosubs, and even the Asterisk: TFOT book doesn’t offer a lot of clarity on the subject (other than to note that generally speaking, you can only use the s extension in a macro).

Also, would it make any difference if, instead of calling a macro in my -custom contexts, I did something specific if a specific extension were called? For example, something like:

[from-internal-noxfer-custom]
exten -> 234,1,Set(__ALERT_INFO=Bellcore-r3)

Would the fact that it had found a match for extension 234 basically stop the processing there if I simply ended my -custom context at that point? I suspect it would, which is part of why this is a bit murky to me.

…and I’m unsure what you’re trying to achieve.

The easiest, and future-proof way, to do what you suggest above (set __alert_info when someone calls extension 234) would be this:

1: Renumber xtn 234 to be 99234 (or something different). Set the CID for it to be 234, so no-one sees ‘99234’.
2: Create this in extensions_custom:

[from-internal-custom]
exten => 234,1,Set(__ALERT_INFO=Bellcore-r3)
exten => 234,n,Goto(from-internal,99234,1)

Asterisk also used to have a mis-feature where you could override dialplans:

[from-internal-custom]
include => test-thing
exten => 555,1,NoOp(I am in from-internal-custom 1)
exten => 555,n,NoOp(I am in from-internal-custom 2)
exten => 555,n,NoOp(I am in from-internal-custom 3)

[test-thing]
exten => 555,1,NoOp(I am in test-thing 1)
exten => 555,n,NoOp(I am in test-thing 2)
exten => 555,n,NoOp(I am in test-thing 3)
exten => 555,n,NoOp(I am in test-thing 4)
exten => 555,n,NoOp(I am in test-thing 5)
exten => 555,n,NoOp(I am in test-thing 6)

This doesn’t seem to work any more. Or I may have the wrong end of the stick. The lines above result in this:

– Executing [[email protected]:1] NoOp(“SIP/200-00000006”, “I am in from-internal-custom 1”) in new stack
– Executing [[email protected]:2] NoOp(“SIP/200-00000006”, “I am in from-internal-custom 2”) in new stack
– Executing [[email protected]:3] NoOp(“SIP/200-00000006”, “I am in from-internal-custom 3”) in new stack
– Executing [[email protected]:4] NoOp(“SIP/200-00000006”, “I am in test-thing 4”) in new stack
– Executing [[email protected]:5] NoOp(“SIP/200-00000006”, “I am in test-thing 5”) in new stack
– Executing [[email protected]:6] NoOp(“SIP/200-00000006”, “I am in test-thing 6”) in new stack

Rob, thanks for the explanation, however I must admit I am more confused than ever.

The setting of the ALERT_INFO variable was just an example of doing “something”. My real question was regarding the correct way to return to the original context after you have done “something.”

As an example, from-internal first does
include => from-internal-noxfer
but after that statement, there’s another include:
include => from-internal-xfer

My assumption was that there must be some set of circumstances under which the second include would be executed, otherwise there’s no reason to have any includes beyond the first.

But let’s say that (hypothetically) you had something in from-internal-noxfer that would match the current value of the EXTEN variable. But for some reason, whatever that might be, you still wanted to come back and pick up where you had left off in from-internal, and run the from-internal-xfer context. Keep in mind that this is just hypothetically speaking, because I realize you probably wouldn’t do something like that in actual FreePBX code.

What I was attempting to determine was if and how you could return to the original context (from-internal in this example) and run through the rest of the includes, or whatever other code might be in that context. And I had thought you might do that in one of three ways:

  1. Just end the context with no additional statement. My thought was that this would probably NOT work if the value of EXTEN had been matched in a pattern in the first included context, but I wasn’t sure about that.

  2. Insert the next line from the original context. In other words, once there had been a match, you’d abandon all hope of returning to the original (from-internal in this hypothetical) and just duplicate any additional includes you might need within the first included context.

  3. Insert a goto that jumps to whatever would have been the next thing included in the original context. If we had gone into the from-internal-noxfer context and for whatever reason, from there you wanted to jump to from-internal-xfer, rather than duplicate the include you’d use a Goto (example: "exten _.,1,Goto(from-internal-xfer,${exten},1).

Those are the only ways that really make sense to me, but they can’t all be correct. And now it appears you’re saying that none of those will work, which would actually not surprise me.

FreePBX, at least, does still have the file extensions_override_freepbx.conf, which allows you to define your own from-internal context and add code if I want, but even that can get tricky, and as I say, the only real problem with doing that is that if you guys change the original from-internal context then any override code could suddenly “break” things.

I apologize if I am explaining this poorly. In my head I understand exactly what I’m getting at but in trying to write out an explanation I feel as though I’m not really conveying the one question I’m really asking, which is, is there a way within an "include"d context to return to the original context that called the “include” in the first place, and just continue processing with the next line AFTER the that “include”? I THINK you are telling me that’s simply not possible, right?

(Sample contexts:)

[my_main_context]
; I want to run the code in the first include
include => my_first_include
; Then I want to run the code in the second include
include => my_second_include

[my_first_include]
exten => 555,1,NoOp(I am in my_first_include)
; Now what do I put here to return to my_main_context and run my_second_include?

If that’s not clear enough, then again I apologize, but I don’t know how else to explain it.

use another context in your extensions and then in the extensions_custom.conf make a goto from-internal