1. บทเริ่ม     
     Asterisk dialplan เป็นกลไกของระบบที่จะควบคุม call flow ตามที่เราต้องการ
     dialplan จะอยู่ในไฟล์ /etc/asterisk/extensions.conf   dialplan ประกอบด้วย
     4 ส่วนหลักๆ คือ contexts, extensions, priority และ applications

2. Contexts
     Context คือ section ย่อยของ dialplan   context เป็นกลุ่มของ extensions
     extensions ใน context หนึ่ง จะแยกจากกันอย่าเด็ดขาดจาก extensions ใน
     context อื่นๆ     context จะมีรูปแบบ ดังนี้

     [context-name1]
     exten => xxx,1,app1()
     exten => xxx,n,app2()
     ...
     ...
     [context-name2]
     exten => 123,1,app1()
     extex => 123,n,app2()
     ...
     ...

     extensions ที่ถัดจาก context ใดๆ ก็จะอยู่ใน context นั้น จนกว่าจะเริ่ม context ใหม่
     ชื่อ context จะประกอบด้วย A-Z, a-z, 0-9, - (hyphen), _ (underscore)
     ตัวอย่างเช่น 
          [incoming]
          [outbound-sip-trunk]
          [iax_trunk] เป็นต้น
     อย่าใช้ [globals] หรือ [general] เพราะ [general] จะใช้กำหนดเรื่องทั่วไปของ dialplan ส่วน 
     [globals] จะกำหนด global variables ซึ่งเราจะเรีบนรู้ต่อไป

     ชื่อ context ยาวได้ถึง 79 ตัวอักษร !!!   มีเวลาก็ลองทดสอบดู !!!

3. Extensions
     Extension คือ step ในการทำงานของระบบ   เมื่อมี call เข้ามาระบบต้องเช็คว่า call จัดอยู่ใน context ใด
     ระบบก็จะใช้ extensions ใน context นั้นๆ ในการ process โดยจะทำตาม priority ที่เราจะกล่าวถึงต่อไป
     รูปแบบของ extension
          exten => name,priority,application
     ตัวอย่าง
          exten => 2000,1,Answer()
          extension name = 2000
          priority = 1
          application = Answer()

     s extension (start extension)
          ในกรณีที่มี incoming call มาจาก trunks เช่น PSTN (TOT เป็นต้น), SIP trunk (Voip providers)
          calls เหล่านี้จะไม่มีข้อมูล extension (เลขหมายภายใน) ปลายทาง   ดังนั้นจะต้องมี
          extension พิเศษรับ calls เหล่านี้ นั่นคือ extension s

          exten => s,1,Answer()
          exten => s,n,App1()
          exten => s,n,App2()
          ...
          ...

     i extension (invalid extension)
          ในบางกรณีระบบต้องการรับ input จากผู้โทร   ถ้าผู้โทรกด input ที่นอกเหนือจากที่ระบบต้องการ 
          call นั้นจะถูกส่งไปที่ i extension เพื่อ run app ที่แจ้งให้ผู้โทรทราบว่ากดผิด (เช่น ระบบ IVR)

          exten => i,1,App1()

     t extension (timeout extension)
          ในกรณีที่ระบบต้องการ input จากผู้โทร   แต่ผู้โทรไม่กด input ใดๆ จนกะทั่ง timeout ระบบ
          ก็จะส่ง call นั้นไปยัง t extension เพื่อ run app ที่กำหนดไว้ต่อไป (เช่นระบบ IVR)

          exten => t,1,App2()

     extension wildcards
          [1236-9]     หมายถึง 1 หรือ 2 หรือ 3 หรือ 6 หรือ 7 หรือ 8 หรือ 9   ตัวใดตัวหนึ่งเพียงตัวเดียวเท่านั้น
          X                หมายถึง 0 ถึง 9   ตัวใดตัวหนึ่งเพียงตัวเดียวเท่านั้น
          Z                หมายถึง 1 ถึง 9   ตัวใดตัวหนึ่งเพียงตัวเดียวเท่านั้น
          N                หมายถึง 2 ถึง 9   ตัวใดตัวหนึ่งเพียงตัวเดียวเท่านั้น
          .                 หมายถึง   ตัวเลขอะไรก็ได้หนึ่งตัวหรือมากกว่าหนึ่งตัวก็ได้

          exten => 20XX,1,Answer()

          20XX จะหมายถึง 2000 ถึง 2099   เป็นต้น

4. Priority
     แต่ละ extension อาจจะมีหลาย steps     priority คือ ลำดับของ steps   ดูตัวอย่าง
          [incoming]
          exten => 2000,1,Answer()
          exten => 2000,2,Playback()
          exten => 2000,3,Hangup()

     ระบบจะ process context incoming ตามลำดับ priority คือ 1,2,3
     
     ถ้าเราเรีบงลำดับใหม่
          [incoming]
          exten => 2000,3,Hangup()
          exten => 2000,2,Playback()
          exten => 2000,1,Answer()

     ระบบก็จะทำงานเหมือนเดิมตามตัวอย่างข้างบน คือ ดูลำดับ priority แล้วจะไล่ทำ
     Answer(), Playback() และ Hangup()

     อย่างไรก็ตามถ้าใน context มีหลายๆ steps แล้วเราต้องการแก้ไขโดยการ
     เพิ่มหรือลด steps เราก็ต้องแก้ไข priority ใหม่ทั้ง context ทำให้ไม่สะดวก
     เราจึงนิยมเขียนแบบ unnumbered priorities คือ

          [incoming]
          exten => 2000,1,Answer()
          exten => 2000,n,Playback()
          exten => 2000,n,Hangup()

     n = next ระบบจะทำ priority 1 แล้วจะทำบรรทัดถัดไป ดังนั้นเราสามารถเพิ่มหรือลด
     steps ได้โดยไม่ต้องเปลี่ยน priority

5. Applications
     Application คือ โปรแกรมที่ทำงานต่างๆ เช่น Answer() จะเป็น app ที่ตอบรับ call
     ที่เข้ามาที่ channel,   Playback(soundfile) จะเป็น app ที่เล่น soundfile เพื่อให้ผู้ที่
     โทรมารับทราบข้อมูล,   Hangup() เป็น app ที่วางสาย   จะเห็นว่าบาง app จะต้อง
     argument ตัวอย่างเช่น   Playback(soundfile)   argument คือ soundfile (ไม่ต้องมี
     file extension)

6. มาดูตัวอย่าง
     ถ้าคุณต้องการทดลองตามตัวอย่าง คุณจะต้องมีอย่างน้อย 2 extensions และ 1 trunk
     จะดูตามบทความในตอนที่ 5 ก็ได้   sip.conf มี extensions 2000, 2001 และ 1 SIP
     trunk ติดต่อกับ voip provider

     [from-sip]                                                         ; context สำหรับโทรภายใน และโทรออก
     exten => 2000,1,Answer()
     exten => 2000,n,Dial(SIP/2000,20)
     exten => 2000,n,Hangup()

     exten => 2001,1,Answer(0)
     exten => 2001,n,Dial(SIP/2001,20)
     exten => 2001,n,Hangup()

     exten => _0Z.,1,Dial(SIP/voip/${EXTEN},30)
     exten => _0Z.,2,Hangup     
   
     ====================================================

     _ (underscore)   บอกให้ระบบทราบว่าที่ตามมาจะเป็น extension wildcards
     _0Z.     เป็น extension wildcards
     SIP/voip/${EXTEN}     หมายถึงโทรออกที่ trunk ชื่อ voip (definded ใน sip.conf)
                                     ${EXTEN} หมายถึงเลขหมายปลายทางที่ผู้โทรกดเพื่อโทรออก

ยังไม่จบ   ยังมีต่อ   แล้วเจอกันใหม่