Read vs regular extension matching

Hi,

This post is more to see if I am getting old and rusty with Asterisk.

I recently hired someone new and I am having him learn/experiment with Asterisk. I gave him this task

  1. Create a dialplan where a caller must press a randomly made up 3 digit pin.
  2. If they fail more than 3 times hangup.
  3. If they pass tell them good job and then play tt-monkeys.

Here is how I would do the code:

exten => 1234,  1,  Answer()
 same =>        n,  Set(FAILCOUNT=0)
 same =>        n,  Set(PIN=${RAND(1,9)})
 same =>n(enter-pin),Background(human-verify)
 same =>        n,  SayDigits(${PIN})
 same =>        n,  WaitExten(3)
 same =>        n,  Set(FAILCOUNT=$[${FAILCOUNT} + 1])
 same =>        n,  ExecIf($["${FAILCOUNT}" == "3"]?Hangup:Goto(enter-pin))

Exten => _X,    1,GotoIf($["${EXTEN}" == "${PIN}"]?success,1)
 same =>        n, PlayBack(cheater)
 same =>        n, goto(1234,enter-pin)

Exten => success, 1,  PlayBack(yay)

He used AI to help along. Both suggested to use READ. Here is what Claude suggested

; Generate a random 3-digit PIN (100-999)
exten => s,1,Set(PIN=${RAND(100,999)})
 same => n,Set(ATTEMPTS=0)
 same => n,Goto(prompt-pin,1)

; Prompt for PIN entry
exten => prompt-pin,1,Set(ATTEMPTS=$[${ATTEMPTS}+1])
 same => n,GotoIf($[${ATTEMPTS} > 3]?hangup-too-many-attempts,1)
 same => n,Playback(please-enter-your)
 same => n,SayNumber(3)
 same => n,Playback(digit)
 same => n,Playback(pin-number)
 same => n,Read(USER_PIN,beep,3,,1,10)
 same => n,GotoIf($["${USER_PIN}" = "${PIN}"]?success,1:incorrect-pin,1)

; Handle incorrect PIN
exten => incorrect-pin,1,Playback(invalid)
 same => n,Playback(try-again)
 same => n,Goto(prompt-pin,1)

; Handle successful PIN entry
exten => success,1,Playback(good-job)
 same => n,Playback(tt-monkeys)
 same => n,Hangup()

; Handle too many failed attempts
exten => hangup-too-many-attempts,1,Playback(im-sorry)
 same => n,Playback(goodbye)
 same => n,Hangup()

; Handle timeout or invalid input
exten => i,1,Playback(invalid)
 same => n,Goto(prompt-pin,1)

exten => t,1,Playback(goodbye)
 same => n,Hangup()

Is there a reason why AI saying to use Read and not use a “regular” dial plan? Am I “doing it wrong”?

Because it hasn’t been trained on enough examples of WaitExten, and/or because it had been trained on too many examples of more traditional programming constructs.

Your code matches 1 digits numbers, not 3 digit ones.

Probably also explains why ‘they’ don’t suggest the INC() function.

@david551 So that means that more people use reads vs using regular extensions then it must be more popular. I am wondering why? It seems easier and clearer to use extensions in place of READ

Many people come from a traditional programming background and try to program Asterisk using traditional constructs. I don’t know what proportion, but you definitely see that happening.

In AEL, the read() method is more concise.

// enter a random number using read()
context enter-random-number
        {
        s       => {
                answer();
                pin=${RAND(100,999)};
                for     (failcount=0; ${failcount} < 3; failcount=${INC(failcount)})
                        {
                        read(entered_number,pin_number&digits/${pin:0:1}&digits/${pin:1:1}&digits/${pin:2:1},3,,1,5);
                        if      (${entered_number} == ${pin})
                                {
                                playback(pin-number-accepted);
                                break;
                                }
                        };
                hangup();
                };
        };
// enter a random number using waitexten()
context enter-random-number
        {
        s       => {
                answer();
                failcount=0;
                pin=${RAND(100,999)};
                goto ask,1;
                };

        ask     => {
                if      (${failcount} > 3)
                        {
                        hangup();
                        };
                background(pin_number&digits/${pin:0:1}&digits/${pin:1:1}&digits/${pin:2:1});
                waitexten(5);
                };

        _xxx    => {
                if      (${EXTEN} == ${pin})
                        {
                        playback(pin-number-accepted);
                        hangup();
                        };
                failcount=${INC(failcount)};
                goto ask,1;
                };

        };

Another factor that will bias the LLMs is that code that gets posted tends to be from people who have problems, and even if fixes are posted, they will typically be a fix to the specific reason for failure, rather than a rework, using better techniques. People who understand dial patterns, and waitexten are more likely to to have understood how Asterisk works, so less likely to ask questions.

Generally the the experience on these forums is that LLMs get nearly every Asterisk question wrong; you are lucky to see a viable solution, rather than a pure hallucination.