12/01/2007

@ Προγραμματισμός - Λογική στο Dialplan

Στο Asterisk, λειτουργίες ή προγράμματα μπορούν να υλοποιηθούν είτε εξωτερικά, μέσω ενός AGI script, είτε εσωτερικά, μέσω συναρτήσεων, μεταβλητών και εφαρμογών στο dialplan. Σε αυτή τη δημοσίευση θα ασχοληθούμε με την προσθήκη εσωτερικής λογικής στο dialplan χρησιμοποιώντας τα παραπάνω εργαλεία, ενώ με την AGI λογική θα ασχοληθούμε εις βάθος σε επόμενη δημοσίευση.


Pattern Matching

Η έννοια του pattern matching έχει να κάνει με την αντιστοίχηση ενός αλφαρηθμιτικού με κάποιο συμβολισμό. Γενικά, ένας ειδικός χαρακτήρας, όπως είναι η τελεία (.) ή το γράμμα Χ, μπορεί να χρησιμοποιηθεί για να παραστήσει έναν ή περισσότερους χαρακτήρες. Στο Asterisk η δυνατότητα αυτή, μας επιτρέπει να γενικεύσουμε τους κανόνες που θα ακολουθηθούν για πλήθος από extensions, αντί να τους ορίζουμε κάθε φορά ξεχωριστά. Με αυτόν τον τρόπο μπορούμε ουσιαστικά να χειριστούμε κάθε πιθανή extension που μπορεί να εισάγει ο χρήστης σε λίγες μονάχα γραμμές του dialplan (ιδιαίτερα χρήσιμο όταν το Asterisk μπορεί να κάνει κλήσεις προς το δημόσιο τηλεφωνικό δίκτυο όπως στο mini-PBX.)

exten => _pattern,προτεραιότητα,εφαρμογή

Μία pattern, δηλώνεται στο Asterisk ξεκινώντας με την κάτω παύλα (_) ακολουθούμενη από τα κριτήρια σύγκρισης που θέλουμε να ταιριάξουμε.

Τα κριτήρια σύγκρισης που διαθέτει το Asterisk είναι τα:

Συμβολισμός

Επεξήγηση

Παράδειγμα

Χ

Αντιστοιχεί σε οποιοδήποτε ψηφίο από το 0 έως το 9

exten => _11Χ,1,Answer
Θα ταιριάξει στις
extensions 110 έως 119

Ζ

Αντιστοιχεί σε οποιοδήποτε ψηφίο από το 1 έως το 9

exten => _11Χ,1,Answer
Θα ταιριάξει στις
extensions 111 έως 119

Ν

Αντιστοιχεί σε οποιοδήποτε ψηφίο από το 2 έως το 9

exten => _11Χ,1,Answer
Θα ταιριάξει στις
extensions 112 έως 119

[145]

Αντιστοιχεί στα ψηφία 1,4,5

exten => _11[179],1,Answer
Θα
ταιριάξει στις extensions 111,117,119

[1-4]

Αντιστοιχεί στα ψηφία 1 έως 4 (δηλαδή στα 1,2,3,4)

exten => _11[0-2],1,Answer
Θα
ταιριάξει στις extensions 110,111,112

.(τελεία)

Αντιστοιχεί σε οποιοδήποτε ψηφίο για μία ή περισσότερες φορές

Exten => _11.,1,Answer
Θα ταιριάξει με οποιαδήποτε
extension ξεκινάει με τα νούμερα 11


Εξετάζοντας το pattern _0030ΧXXXXXXXXX που χρησιμοποιήθηκε στο παράδειγμα του mini-PBX βλέπουμε ότι επαληθεύεται από οποιοδήποτε 14ψήφιο νούμερο ξεκινάει με τα ψηφία 0030. Αυτό σημαίνει ότι αν κάποιος (υποθέτουμε ότι έχει πρόσβαση στο context mini-pbx-outgoing) πληκτρολογήσει 0030 και δέκα ακόμη ψηφία θα εκτελεστεί αυτή η extension. Γνωρίζουμε ότι τα τηλέφωνα στην Ελλάδα αποτελούνται από δέκα νούμερα και ότι ο διεθνής κωδικός της Ελλάδας είναι 0030. Φτιάξαμε λοιπόν ένα pattern που μας επιτρέπει να ταυτίσουμε όλα τα πιθανά ελληνικά τηλεφωνικά νούμερα (σταθερά και κινητά). Αν υποθέσουμε ότι δε θέλουμε να δώσουμε τη δυνατότητα στους χρήστες μας να καλέσουν σε κινητό τηλέφωνο τότε θα έπρεπε να αλλάξουμε το pattern μας σε _00302XXXXXXXXX. H προσθήκη του ψηφίου 2 απαγορεύει την κλήση σε κινητό αφού δε θα επαληθευτεί το pattern για τα νούμερα κινητών τηλεφώνων (003069ΧΧΧΧΧΧΧΧ).


Μεταβλητές

Προηγουμένως, αναφερθήκαμε στις global μεταβλητές οι οποίες δηλώνονται στο context [globals] του Asterisk dialplan, ισχύουν καθολικά στο Asterisk και καλούνται με το συμβολισμό ${ΟΝΟΜΑ_ΜΕΤΑΒΛΗΤΗΣ}. Εκτός από τις global μεταβλητές το Asterisk έχει τη δυνατότητα αποθήκευσης και ανάκτησης τιμών και από έναν άλλον τύπο μεταβλητών, τις channel μεταβλητές. Μια channel μεταβλητή, είναι μια μεταβλητή η οποία έχει ισχύ για τη διάρκεια της κλήσης στην οποία δημιουργήθηκε, μετά το τέλος της οποίας παύει να υπάρχει.

Μία channel μεταβλητή ορίζεται μέσα στο dialplan, μέσω τις εφαρμογής Set(),

exten => extension,προτεραιότητα,Set(ΟΝΟΜΑ_ΜΕΤΑΒΛΗΤΗΣ=Τιμή)

Και η τιμή της ανακτάται στο dialplan με τη χρήση του συμβολισμού ${ΟΝΟΜΑ_ΜΕΤΑΒΛΗΤΗΣ}, όπως είδαμε προηγουμένως και για τις global μεταβλητές.


Παρόλο που η τιμή μίας μεταβλητής μπορεί να είναι οποιοσδήποτε χαρακτήρας εκτός των [ ] “ \ $ που είναι δεσμευμένοι, είναι καλή πρακτική, όταν η τιμή δεν είναι νούμερο, να την περικλείουμε σε “ “. Δηλαδή:

exten => 001,1,Set(CITY=”Athens”)

Αν θέλουμε να χρησιμοποιήσουμε κάποιον από τους δεσμευμένους χαρακτήρες στην τιμή μία μεταβλητής τότε θα πρέπει να προηγείται το σύμβολο “\”. Για παράδειγμα :

exten => 001,1,Set(DOLLAR_SIGHN=\$)
exten => 001,2,NoOp(${DOLLAR_SIGHN})

Υπάρχουν επίσης πολλές προκαθορισμένες channel μεταβλητές οι οποίες μπορούν να χρησιμοποιηθούν στο Asterisk και περιγράφονται στο αρχείο /doc/README.variables (ή στο /doc/channelvariables.txt για την έκδοση 1.4) των πηγαίων αρχείων που κατεβάσαμε. Κάποιες από αυτές είναι:

  • ${ANSWEREDTIME}: Κρατάει την τιμή των δευτερολέπτων που έχουν περάσει απ’ τη στιγμή που ξεκίνησε η κλήση.
  • ${EPOCH}: Η τρέχουσα ώρα σε μορφή UNIX (δευτερόλεπτα που έχουν περάσει από την 1η Ιανουαρίου 1970)
  • ${CHANNEL}: Το όνομα του τρέχοντος καναλιού κλήσης
  • ${CONTEXT}: Το όνομα του τρέχοντος context
  • ${PRIORITY}: Το νούμερο της τρέχουσας προτεραιότητας
  • ${ΕΧΤΕΝ}: Η extension που πληκτρολογήθηκε από το χρήστη
  • ${INVALID_EXTEN}: Χρησιμοποιείται σε συνδυασμό με την ειδική extension i και περιέχει την εσφαλμένη extension που πληκτρολογήθηκε από το χρήστη.
  • ${ENV(VARIABLENAME)}: Περιέχει την τιμή της μεταβλητής συστήματος (λειτουργικού) VARIABLENAME.
  • ${DIALSTATUS}: Ανάλογα με την κατάσταση της κλήσης, η μεταβλητή παίρνει τις τιμές ANSWER, NOANSWER, BUSY, CONGESTED, κ.λ.π.

Παρόλο που στην τρέχουσα έκδοση του Asterisk υπάρχουν πολλές προκαθορισμένες channel μεταβλητές οι οποίες κρατάνε σημαντικά στοιχεία όπως: το νούμερο του καλούντα (${CALLERIDNUMBER}), το όνομα του καλούντα (${CALLERIDNAME}), την τρέχουσα ώρα, ημερομηνία (${TIMESTAMP}, ${DATETIME}) κ.α. Η εξέλιξη του Asterisk δείχνει ότι οι δημιουργοί του θα σταματήσουν να τις αναπτύσσουν και τελικά θα αποσύρουν τη χρήση τους. Η νέα τάση που υπάρχει στο Asterisk είναι η χρήση συναρτήσεων τις οποίες θα εξηγήσουμε σε επόμενη δημοσίευση.

Στο παράδειγμα του mini-PBX χρησιμοποιήσαμε την προκαθορισμένη channel μεταβλητή ${EXTEN}, η τιμή της οποίας είναι ίση με το ακριβές νούμερο το οποίο ταίριαξε σε κάποιο pattern. Για να καταλάβουμε ακριβώς τη λειτουργία της ${EXTEN}, μπορούμε στο dialplan του mini-PBX, να κάνουμε την παρακάτω αλλαγή:

;exten => _0030ΧXXXXXXXXX,1,Dial(SIP/${EXTEN}@{VOIPDISCOUNT},,r)
exten
=> _0030ΧXXXXXXXXX,1,SayDigits(${EXTEN})
exten
=> _0030ΧXXXXXXXXX,2,Hangup

Σώζουμε το extensions.conf και γράφουμε την εντολή reload στην κονσόλα του Asterisk. Αν πληκτρολογήσουμε κάποιο ελληνικό τηλεφωνικό νούμερο πλέον, Θα ακούσουμε τα ψηφία τα οποία έχουν αποθηκευτεί στην ${EXTEN}, τα ψηφία, τα οποία εμείς πληκτρολογήσαμε.

Συχνά είναι χρήσιμο να έχουμε πρόσβαση σε ένα τμήμα των ψηφίων της ${EXTEN}, Για παράδειγμα αν επιθυμούμε να μάθουμε μόνο το άγνωστο νούμερο το οποίο πληκτρολογήθηκε, χωρίς τον κωδικό 0030 ο οποίος είναι προκαθορισμένος. Αυτό επιτυγχάνεται καλώντας την ${EXTEN} ως: ${EXTEN:x[:y]}, όπου x είναι το νούμερο τον ψηφίων που θέλουμε να αφαιρέσουμε από την αρχή ή -x το νούμερο τον ψηφίων που θέλουμε να αφαιρέσουμε από το τέλος και προαιρετικά y το μήκος των ψηφίων που επιθυμούμε να προσπελάσουμε μετά από x ψηφία. Έτσι γράφουμε:

Για να ακούσουμε το άγνωστο νούμερο(ΧΧΧΧΧΧΧΧΧΧ):
exten => _0030ΧXXXXXXXXX,1,SayDigits(${EXTEN:4})

Για να ακούσουμε την προεπιλογή(0030):
exten => _0030ΧXXXXXXXXX,1,SayDigits(${EXTEN:-10})

Για να ακούσουμε τα τρία πρώτα ψηφία μετά την προεπιλογή
exten => _0030ΧXXXXXXXXX,1,SayDigits(${EXTEN:4:3})


Η εφαρμογή Goto() και Ετικέτες

Ήδη από το mini-PBX είδαμε ότι κάποιοι κανόνες ακολουθούνται κατά τη διάρκεια μίας κλήσης, και κάποιες αποφάσεις παίρνονται ανάλογα με συγκεκριμένα κριτήρια. Για να μπορέσει το σύστημά να αλληλεπιδράσει με τους χρήστες θα πρέπει να είναι προγραμματισμένο με τέτοιο τρόπο ώστε να μπορεί να παίρνει κάποιες λογικές αποφάσεις ανάλογα με τις εισόδους του χρήστη. Θα αλλάξουμε το context mini-pbx-incoming ως εξής:

[mini-pbx-incoming]
exten => ${LINE},1,Answer()
exten => ${LINE},2,Background(custom/my-menu)
exten => ${LINE},3,WaitExten(5)

exten => 1,1,Dial(${SIP-USER},20,r)
exten => 1,2,Playback(vm-nobodyavail)
exten => 1,3,Goto(mini-pbx-incoming,${LINE},2)

exten => 2,1,Dial(${IAX-USER},20,r)
exten => 2,2,Playback(vm-nobodyavail)
exten => 2,3,Goto(mini-pbx-incoming,${LINE},2)

exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(mini-pbx-incoming,${LINE},2)
exten => t,1,Playback(vm-goodbye)
exten
=> t,2,Hangup()

Παραπάνω χρησιμοποιείται ένας προσαρμοσμένος χαιρετισμός που δημιουργήθηκε για τις ανάγκες του παραδείγματος και τοποθετήθηκε στο φάκελο /var/lib/asterisk/sounds/custom. Με την εφαρμογή Background(), το Asterisk περιμένει να δεχτεί είσοδο από το χρήστη και αναπαραγάγει το αρχείο ήχου “my-menu”, το οποίο ζητάει από τον καλούντα να πληκτρολογήσει “1” αν επιθυμεί να συνδεθεί με τον sip-user ή “2” αν επιθυμεί να συνδεθεί με τον iax-user. Στη συνέχεια περιμένει με την WaitExten() άλλα 5 δευτερόλεπτα για είσοδο.

Ανάλογα με την είσοδο (1 ή 2), μέσω της Dial() καλείται ο αντίστοιχος χρήστης. Αν ο χρήστης απαντήσει στην κλήση τότε δημιουργείται το κανάλι επικοινωνίας και τα δύο άκρα αρχίζουν και ανταλλάζουν πακέτα φωνής. Αν περάσουν 20 δευτερόλεπτα και ο χρήστης δεν απαντήσει την κλήση, τότε μέσω της εφαρμογής Goto() η κλήση πάει στο context [mini-pbx-incoming], στην extension ${LINE}, στη δεύτερη προτεραιότητα, δηλαδή στην εφαρμογή Background() για να επαναληφθεί η παραπάνω διαδικασία.

Η εφαρμογή Goto() συντάσσεται ως: Goto(προορισμός)

O προορισμός μπορεί να είναι:

  • Μία προτεραιότητα μέσα στην ίδια extension (π.χ. 2)
  • Μία extension και μία προτεραιότητα μέσα στο ίδιο context (π.χ. 111,2)
  • Ένα context, μια extension και μία προτεραιότητα (π.χ. internal,111,2)
  • Μία ετικέτα (π.χ. (Menu))

Τέλος, αν ο χρήστης εισάγει κάτι διαφορετικό από 1 ή 2 τότε μεταφέρεται στην ειδική extension i όπου ακούει το μήνυμα “pbx-invalid” και μεταφέρεται πάλι στην Background(), ενώ αν δεν εισάγει τίποτα κατά τη διάρκεια της Background() και της WaitExten(), τότε θα μεταφερθεί στην ειδική extension t όπου θα ακούσει το μήνυμα goodbye, και θα κλείσει η γραμμή.

Αν ακολουθήσουμε τη συμβολική n αρίθμηση των προτεραιοτήτων, τότε τα πράγματα περιπλέκονται κάπως για την Goto(). Εφόσον δεν γνωρίζουμε το ακριβές νούμερο της κάθε προτεραιότητας, θα πρέπει με κάποιο τρόπο να μπορέσουμε να σηματοδοτήσουμε τα σημεία στα οποία επιθυμούμε να μεταφερθούμε. Η σηματοδότηση των σημείων στο dialplan επιτυγχάνεται με τη χρήση των ετικετών (labels). To παραπάνω παράδειγμα εκφρασμένο με την ειδική n προτεραιότητα και τη χρήση ετικετών γίνεται:

[mini-pbx-incoming]
exten => ${LINE},1,Answer
exten => ${LINE},n(Menu),Background(custom/my-menu)
exten => ${LINE},n,WaitExten(5)

exten => 1,1,Dial(${SIP-USER},20,r)
exten => 1,n,Playback(vm-nobodyavail)
exten => 1,n,Goto(mini-pbx-incoming,${LINE},Menu)

exten => 2,1,Dial(${IAX-USER},20,r)
exten => 2,n,Playback(vm-nobodyavail)
exten => 2,n,Goto(mini-pbx-incoming,${LINE},Menu)

exten => i,1,Playback(pbx-invalid)
exten => i,n,Goto(mini-pbx-incoming,${LINE},Menu)
exten => t,1,Playback(vm-goodbye)
exten
=> t,n,Hangup

To αποτέλεσμα είναι ακριβώς το ίδιο και για τις 2 μεθόδους. Ο τρόπος με τον οποίο σηματοδοτήθηκε το σημείο που επιθυμούμε να μεταφερθούμε ήταν με την προσθήκη της ετικέτας (Menu). Αντί να χρησιμοποιούμε συγκεκριμένους αριθμούς λοιπόν, μπορούμε να χρησιμοποιήσουμε λέξεις οι οποίες βοηθάνε πολύ στην αναγνωσιμότητα του dialplan και την αποσφαλμάτωσή του. Η μέθοδος αυτή, είναι επίσης ανεκτική σε αλλαγές χωρίς να χρειαστεί να αλλάζουμε κάθε φορά αριθμήσεις στις προτεραιότητες.


Η εφαρμογή Gotoif()

Ας υποθέσουμε ότι στο παραπάνω παράδειγμα δε θέλουμε ο χρήστης να μπορεί να επιστρέψει πάνω από τέσσερις φορές στο ηχητικό menu. Αυτό θα μπορέσει να υλοποιηθεί με τη χρήση της εφαρμογής GotoIf(). Με την GotoIf() έχουμε τη δυνατότητα να εξετάσουμε την ορθότητα μίας έκφρασης και ανάλογα με το αποτέλεσμα (αληθές ή ψευδές) να κατευθυνθούμε στον ανάλογο προορισμό. Μια έκφραση αποτελείται από δύο συγκρίσιμα μεγέθη (αριθμούς, αλφαριθμητικά, εκφράσεις) και έναν τελεστή σύγκρισης( =, >, <, >=, <=, !=, |, &).

Η GotoIf() συντάσσεται ως:
GotoIf(έκφραση:προορισμός1,προορισμός2)

Για να μπορέσουμε λοιπόν να ορίσουμε ένα μέγιστο αριθμό προσπαθειών που θα μπορεί ο χρήστης να επαναλάβει τη διαδικασία του Menu, θα ορίσουμε μία global μεταβλητή RETRIES=0, την οποία θα αυξάνουμε κατά 1, κάθε φορά που θα επιχειρείται σύνδεση με τις extensions 1,2,i. Όσο η μεταβλητή RETRIES είναι μικρότερη ή ίση του 4, τότε ο καλών θα επιστρέφει στο κεντρικό menu, ενώ σε αντίθετη περίπτωση θα κατευθυνθεί στην ειδική extension t όπου θα τερματιστεί η κλήση, όπως φαίνεται παρακάτω:

[mini-pbx-incoming]
exten => ${LINE},1,Answer

exten => ${LINE},n,SetGlobalVar(RETRIES=0)
exten => ${LINE},n(Menu),Background(custom/my-menu)
exten => ${LINE},n,WaitExten(5)

exten => 1,1,Dial(${SIP-USER},20,r)
exten => 1,n,SetGlobalVar(RETRIES=${RETRIES} + 1)
exten => 1,n,Playback(vm-nobodyavail)
exten => 1,n,GotoIf($[${RETRIES} <= 4]?${LINE},Menu:t,1)

exten => 2,1,Dial(${IAX-USER},20,r)
exten => 2,n,SetGlobalVar(RETRIES=${RETRIES} + 1)
exten => 2,n,Playback(vm-nobodyavail)
exten => 2,n,GotoIf($[${RETRIES} <= 4]?${LINE},Menu:t,1)

exten => i,1,Playback(pbx-invalid)
exten => i,n,SetGlobalVar(RETRIES=${RETRIES} + 1)
exten => i,n,GotoIf($[${RETRIES}
<= 4]?${LINE},Menu:t,1)
exten => t,1,Playback(vm-goodbye)
exten
=> t,n,Hangup


mini-PBX += mini-IVR + mini-ACD

Στην υλοποίηση που εξετάσαμε για τη χρήση της Goto(), παρόλο που δεν αναφέρθηκε, έχει σχηματιστεί μία αρχική μορφή ενός ACD συστήματος, όπου ο καλών έχει τη δυνατότητα να επιλέξει με ποιόν επιθυμεί να συνδεθεί. Πατώντας πάνω σε αυτήν την υλοποίηση, θα ενσωματώσουμε στο σύστημά μας, και IVR λειτουργίες προσφέροντας κάποιες πληροφορίες μέσω ηχογραφημένων μηνυμάτων .

Σαν παράδειγμα πραγματικού κόσμου, θα υποθέσουμε ότι οι χρήστες iax-user και sip-user έχουν έναν κινηματογράφο, και θέλουν να παρέχουν ηχογραφημένες πληροφορίες για την ταινία που προβάλλεται σήμερα καθώς και για την επόμενη. Οι χαιρετισμοί και οι πληροφορίες θα παρέχονται στο φάκελο /var/lib/asterisk/sounds/custom από τα παρακάτω αρχεία ήχου:

  • Main-Menu.wav: Για να συνδεθείτε με τον sip-user πληκτρολογήστε 1, για να συνδεθείτε με τον iax-user πληκτρολογήστε 2, για να ακούσετε πληροφορίες για ταινίες που προβάλλονται πληκτρολογήστε 3.
  • cinema-menu.wav: Για να ακούσετε πληροφορίες για την ταινία που προβάλλεται σήμερα πληκτρολογήστε 1, για να ακούσετε πληροφορίες για την ταινία που προβάλλεται αύριο πληκτρολογήστε 2
  • movie-current.wav & movie-next.wav: Σε αυτά τα αρχεία περιέχονται οι ηχογραφημένες πληροφορίες (τίτλος, διάρκεια, ώρα έναρξης προβολής, κ.λ.π.) για την ταινία που προβάλλεται και την επόμενη.

Οι IVR λειτουργίες θα παρέχονται από ένα καινούργιο context ([mini-ivr-cinema]), στο οποίο ο καλών θα έχει πρόσβαση μέσω του incoming context και της εφαρμογής Goto() όπως φαίνεται παρακάτω.

[mini-pbx-incoming]
;
To menu επαναλαμβάνεται μέχρι ο χρήστης να εισάγει δεδομένα.
exten =>
${LINE},1,Answer
exten =>
${LINE},2,Background(custom/Main-Menu)
exten =>
${LINE},3,WaitExten(5)
exten =>
${LINE},4,Goto(2)

exten => 1,1,Dial(${SIP-USER})
exten => 1,2,Playback(vm-nobodyavail)
exten => 1,3,Goto(${LINE},2)

exten => 2,1,Dial(${IAX-USER})
exten => 2,2,Playback(vm-nobodyavail)
exten => 2,3,Goto(${LINE},2)

; Με την Goto() επιτυγχάνεται μεταφορά σε άλλο context
exten => 3,1,Goto(mini-ivr-cinema,s,1)

exten => i,1,Goto(${LINE},2)

[mini-ivr-cinema]
exten => s,1,Background(custom/cinema-menu)
exten => s,2,WaitExten(5)
exten => s,3,Goto(1)

exten => 1,1,Playback(custom/movie-current)
exten => 1,2,Wait(2)
exten => 1,3, Goto(
s,1)

exten => 2,1,Playback(custom/movie-next)
exten => 2,2,Wait(2)
exten => 2,3, Goto(
s,1)

; Λανθασμένη είσοδος στέλνει τον καλούντα πίσω στο κεντρικό menu
exten => i,1,Goto(mini-pbx-incoming,
(${LINE},1)


Συναρτήσεις (Functions)

Εκτός από τις εφαρμογές, οι δημιουργοί του Asterisk έχουν προσθέσει, από την έκδοση 1.2 και έπειτα, τις συναρτήσεις. Η προσθήκη των συναρτήσεων και ο τρόπος χρήσης τους, δίνουν σαφείς ενδείξεις πως η σύνταξη του dialplan κατευθύνεται προς μία προγραμματιστική λογική.

Οι συναρτήσεις τροφοδοτούν το Asterisk με δυνατότητες εξελιγμένων πράξεων και υπολογισμών όπως είναι για παράδειγμα η εξαγωγή MD5 checksums, η χρήση ανεπτυγμένων μαθηματικών εκφράσεων όπως η ύψωση δύναμης, ο υπολογισμός μήκους αλφαριθμητικών, η επεξεργασία των στοιχείων αναγνώρισης κλήσεων, χρονικοί υπολογισμοί, κ.α. Όλα τα παραπάνω είναι δυνατόν να συνδυαστούν με σκοπό να παρέχουν ακόμα ποιο εξελιγμένες μεθόδους επεξεργασίας.

Σε αντίθεση με τις εφαρμογές, οι συναρτήσεις δεν δηλώνονται απευθείας στο dialplan. Δηλώνονται μέσα σε μία εφαρμογή (π.χ. Set()) και επιστρέφουν κάποια τιμή (π.χ. Read(), ΝoOp()).

Μια συνάρτηση στο dialplan δηλώνεται ως:
ONOMA_ΣΥΝΑΡΤΗΣΗΣ(όρισμα)
π.χ. exten => 123, 1, Set(CALLERID(name)=”John Doe”)

Και καλείται με παρόμοιο τρόπο με αυτόν των μεταβλητών, ως:
${ΟΝΟΜΑ_ΣΥΝΑΡΤΗΣΗΣ(όρισμα)}
π.χ. exten => 123, 1, NoOp(${CALLERID(all)})

Οι συναρτήσεις παρέχουν επίσης δυνατότητες ενθυλάκωσης:
${ΟΝΟΜΑ_ΣΥΝΑΡΤΗΣΗΣ(${ΟΝΟΜΑ_ΣΥΝΑΡΤΗΣΗΣ(όρισμα)})}
π.χ. exten => 123, 1, NoOp(${LEN(${CALLERID(all)})})

Στα παραπάνω παραδείγματα χρησιμοποιήσαμε τις συναρτήσεις LEN() και CALLERID() . Στο πρώτο παράδειγμα, δηλώθηκέ στο Asterisk ότι το όνομα John Doe θα χρησιμοποιηθεί στην αναγνώριση κλήσης. Στο δεύτερο παράδειγμα κατά τη διάρκεια της κλήσης, θα τυπωθεί στην κονσόλα του Asterisk το όνομα και το νούμερο του καλούντα, με το νούμερο κλεισμένο μέσα στα σύμβολα < > (π.χ. John Doe <123456789>). Τέλος στο τρίτο παράδειγμα, η τιμή της συνάρτησης CALLERID(all) ενθυλακώνετε στη συνάρτηση LEN() και τυπώνεται στην κονσόλα του Asterisk το μήκος (ακέραιος αριθμός) του αλφαρηθμιτικού CALLERID(all).

Δεν υπάρχουν σχόλια: