Pattern Extension Not Working In Dialplan

Home » Asterisk Users » Pattern Extension Not Working In Dialplan
Asterisk Users 9 Comments

Hi,

I created a dummy dialplan where I ask the user to enter the age.

[macro-age]
exten => s,1,Background(my/age) ;;Play recorded message to enter age exten => s,n,WaitExten(10)
exten => _XX,1,Set(AGE=${EXTEN}) ;; this line is not executing, instead dialplan is terminating with error given below. exten => s,n,NoOp(${AGE})
exten => s,n,GotoIf($[${LEN(${AGE})} > 0]?notEmpty)
exten => s,n,Goto(s,1)
exten => s(notEmpty),n,Background(my/thank-you)
exten => s,n,Wait(1)

When I receive call and tries to enter the digits (86 lets say), it only accept just first digit and terminates even before considering second digit. Error message :
WARNING[5726][C-0000000a]: pbx.c:6696 __ast_pbx_run: Invalid extension
‘8’, but no rule ‘i’ or ‘e’ in context ‘testmacro’

Please suggest what might be wrong.

Anurag Rana http://newbie42.blogspot.in/

9 thoughts on - Pattern Extension Not Working In Dialplan

  • The first issue I see is you are attempting to insert your pattern match in the middle of your ‘s’ extension, That’s going to break your ‘s’ extension.

    The second issue is that you are matching on XX which will match two digits, You need to match on _X instead if you are attempting to match on the number 8.

    I recommend you look into ‘read’ instead of trying to do a pattern match.

  • Disregard that. I can’t even follow my own advice (‘dialplan show macro-age’). Don’t ‘intermingle’ extensions.

  • ​Thank you all for your suggestions.

    1. [macro-age] is a macro and not an extension badly named.

    2. I am able to use Read to fulfill the purpose but we can’t use Read()
    after Background(). To use read we need Playback() [ am I right?]. But Playback do not provide barge-in facility i.e. user have to listen whole message then only his inputs will be accepted and if he entered input during the time recording is played , the input will be lost. So if using Background() [which return the control immediately] I have to use _XX extension.

    3. So basically I want to create a dial-plan where user is asked to input multi-digit value and he can enter it without listening complete message
    (if the user knows the message already)​

  • UkVBRCBhcHBsaWNhdGlvbiBzaG91bGQgZG8gdGhlIGpvYiBmb3IgeW91DQpbU3ludGF4XVJlYWQo dmFyaWFibGVbLGZpbGVuYW1lWyZmaWxlbmFtZTJbJi4uLl1dWyxtYXhkaWdpdHNbLG9wdGlvbnNb LGF0dGVtcHRzWyx0aW1lb3V0XV1dXV0pDQppIG5vcm1hbGx5IHVzZSBmaXJzdCB0aHJlZSBhcmd1
    bWVudHMgaS5lLiB2YXJpYWJsZSBuYW1lLCBmaWxlbmFtZSB0byBwbGF5IGFuZCBtYXggZGlnaXRz DQp5b3UgbWlnaHQgY29uc2lkZXIgdXNpbmcgIndhaXRleHRlbiIgYmVmb3JlICJyZWFkIiB0aG91
    Z2gNClJnZHMNCg0KRnJvbTogYW51cmFncmFuYTMxMTg5QGdtYWlsLmNvbQ0KRGF0ZTogTW9uLCA4
    IFNlcCAyMDE0IDA5OjI5OjQ3ICswNTMwDQpUbzogYXN0ZXJpc2stdXNlcnNAbGlzdHMuZGlnaXVt LmNvbQ0KU3ViamVjdDogUmU6IFthc3Rlcmlzay11c2Vyc10gUGF0dGVybiBFeHRlbnNpb24gbm90
    IHdvcmtpbmcgaW4gRGlhbHBsYW4NCg0K4oCLVGhhbmsgeW91IGFsbCBmb3IgeW91ciBzdWdnZXN0
    aW9ucy4NCjEuIFttYWNyby1hZ2VdIGlzIGEgbWFjcm8gYW5kIG5vdCBhbiBleHRlbnNpb24gYmFk bHkgbmFtZWQuDQoyLiBJIGFtIGFibGUgdG8gdXNlIFJlYWQgdG8gZnVsZmlsbCB0aGUgcHVycG9z ZSBidXQgd2UgY2FuJ3QgdXNlIFJlYWQoKSBhZnRlciBCYWNrZ3JvdW5kKCkuIFRvIHVzZSByZWFk IHdlIG5lZWQgUGxheWJhY2soKSBbIGFtIEkgcmlnaHQ/XS4gQnV0IFBsYXliYWNrIGRvIG5vdCBw cm92aWRlIGJhcmdlLWluIGZhY2lsaXR5IGkuZS4gdXNlciBoYXZlIHRvIGxpc3RlbiB3aG9sZSBt ZXNzYWdlIHRoZW4gb25seSBoaXMgaW5wdXRzIHdpbGwgYmUgYWNjZXB0ZWQgYW5kIGlmIGhlIGVu dGVyZWQgaW5wdXQgZHVyaW5nIHRoZSB0aW1lIHJlY29yZGluZyBpcyBwbGF5ZWQgLCB0aGUgaW5w dXQgd2lsbCBiZSBsb3N0LiBTbyBpZiB1c2luZyBCYWNrZ3JvdW5kKCkgW3doaWNoIHJldHVybiB0
    aGUgY29udHJvbCBpbW1lZGlhdGVseV0gSSBoYXZlIHRvIHVzZSBfWFggZXh0ZW5zaW9uLg0KMy4g U28gYmFzaWNhbGx5IEkgd2FudCB0byBjcmVhdGUgYSBkaWFsLXBsYW4gd2hlcmUgdXNlciBpcyBh c2tlZCB0byBpbnB1dCBtdWx0aS1kaWdpdCB2YWx1ZSBhbmQgaGUgY2FuIGVudGVyIGl0IHdpdGhv dXQgbGlzdGVuaW5nIGNvbXBsZXRlIG1lc3NhZ2UgKGlmIHRoZSB1c2VyIGtub3dzIHRoZSBtZXNz YWdlIGFscmVhZHkp4oCLCg0KLS0gCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwotLSBCYW5kd2lkdGggYW5kIENvbG9j YXRpb24gUHJvdmlkZWQgYnkgaHR0cDovL3d3dy5hcGktZGlnaXRhbC5jb20gLS0KTmV3IHRvIEFz dGVyaXNrPyBKb2luIHVzIGZvciBhIGxpdmUgaW50cm9kdWN0b3J5IHdlYmluYXIgZXZlcnkgVGh1
    cnM6CiAgICAgICAgICAgICAgIGh0dHA6Ly93d3cuYXN0ZXJpc2sub3JnL2hlbGxvCgphc3Rlcmlz ay11c2VycyBtYWlsaW5nIGxpc3QKVG8gVU5TVUJTQ1JJQkUgb3IgdXBkYXRlIG9wdGlvbnMgdmlz aXQ6CiAgIGh0dHA6Ly9saXN0cy5kaWdpdW0uY29tL21haWxtYW4vbGlzdGluZm8vYXN0ZXJpc2st dXNlcnMgCQkgCSAgIAkJICA

  • You would be better off jumping to a new context and building up your number, digit-by-digit as it is entered, in a channel variable.

    In your “s” extension, set your variable to an empty string; do a Background()
    and then WaitExten() for a digit to be entered. Have an extension _X to capture each digit and append it to the number so far. Then use a GotoIf() to jump to the WaitExten() statement if insufficient digits have been entered so far. You might also want a * extension to clear the number entered so far, if the user makes a mistake.

    If you need a written example, I might be able to dig something out later.

  • This is excerpted from a dialplan application I wrote. It’s actually a PIN
    entry but should be usable for any general purpose application. Sound files referred to will need to be created by you.

    [get_pin]
    exten => s,1,Set(pin=)
    exten => s,n,Set(PINLENGTH=4)
    exten => s,n(prompt),Background(ajs-enter_pin)
    ; Build up the PIN digit by digit. The WaitExten() will be cut short by any
    ; keystroke, so we can use a quite longish timeout. exten => s,n(nextdigit),WaitExten(30)
    exten => s,n,Playback(ajs-sorry_didnt_get)
    exten => s,n,GoToIf($[${LEN(${pin})}<1]?prompt:saysofar)
    exten => s,n(saysofar),Playback(ajs-digits_so_far)
    exten => s,n,SayDigits(${pin})
    exten => s,n,Goto(nextdigit)

    ; We need a “h” extension (for tidying up after ourselves) in this context;
    ; because the call may be placed from within this context.

    exten => h,1,NoOp(Clearing up)

    exten => *,1,Playback(ajs-start_again)
    exten => *,2,GoTo(get_pin,s,1)

    exten => #,1,Hangup()

    exten => _X,1,Set(pin=${pin}${EXTEN:0:1})
    exten => _X,n,NoOp(PIN so far is ${pin})
    exten => _X,n,GoToIf($[${LEN(${pin})}>=${PINLENGTH}]?got_all:need_more)
    exten => _X,n(need_more),GoTo(get_pin,s,nextdigit)
    ; We have all 4 digits ….. exten => _X,n(got_all),NoOp(PIN is ${pin})

  • ​Thanks. I will try it. Meanwhile I was trying below code.

    call goes to ‘test’ context and from there is passed to macro ‘age’. In ‘age’ macro when I am using any patter to accept even single digit, its not working. So instead of using pattern I hardcoded the extension, but still when I am pressing the key ‘2’ it is throwing below error. Please note that when diaplan execution is inside macro ‘age’, it searches the extension inside its parent context ‘test’…why? am I do something wrong?

    [test]
    exten=>s,1,Macro(age)

    [macro-age]
    exten=>s,1,Background(my/age)
    exten=>s,2,WaitExten(15)
    exten=>s,3,NoOp(${AGE})
    exten=>s,n,GotoIf($[${LEN(${AGE})} > 0]?notEmpty)
    exten=>s,n,Goto(s,1)
    exten=>s(notEmpty),n,Background(my/thank-you)
    exten=>s,n,Wait(1)

    exten=>2,1,(TEMP=${EXTEN}) ;; exten=>_X,1,(TEMP=${EXTEN}) is also not working exten=>2,n,Read(AGE,,1,10)
    exten=>2,n,Set(AGE=${${TEMP}*10+${AGE}})
    exten=>2,n,Goto(s,3)