เทคนิคและวิธีการเขียน Asterisk Dialplan I ตอนที่ 4 (จบ)

Asterisk Opensource IP Pbx

เทคนิคและวิธีการเขียน Asterisk Dialplan I ตอนที่ 4 (จบ)

โพสต์โดย voip4share » 03 มี.ค. 2010 18:10

เทคนิค Asterisk Dialplan ตอนที่ 1
เทคนิค Asterisk Dialplan ตอนที่ 2
เทคนิค Asterisk Dialplan ตอนที่ 3

เทคนิคและวิธีการเขียน Asterisk Dialplan ตอนที่ 4

6. การใช้ตัวแปร (Variables)

เราใช้ตัวแปร Asterisk Dialplan เพื่อประโยชน์หลายประการ อาทิเช่น ช่วยลดการพิมพ์ข้อความเดิมซ้ำหลายครั้ง เพิ่มความชัดเจน หรือเพิ่ม Logic เข้าไปใน Dialplan ถ้าเคยเขียนโปรแกรมคอมพิวเตอร์มาบ้างเราก็

คงเข้าใจตัวแปรและการใช้งานตัวแปรบ้างนะครับ แต่ถ้าไม่เคยเขียนโปรแกรมมาเลยก็ไม่ต้องเป็นห่วง ผมจะอธิบายว่าตัวแปรคืออะไรและใช้งานยังไง

ลองนึกเปรียบเทียบตัวแปรว่าเป็นตู้คอนเทนเนอร์ที่ ณ เวลาหนึ่งก็เก็บสินค้าอย่างหนึ่ง เมื่อเวลาผ่านไปสินค้าอาจยังอยู่เหมือนเดิมโดยที่ปริมาณยังเท่าเดิมหรือลดลง หรือเปลี่ยนเป็นสินค้าอื่นแทน (แต่กรณีของตัวแปรสิ่ง ที่เราเก็บไว้เราเรียกว่า ค่า) กตัวอย่าง เราอาจจะสร้างตัวแปรที่มีชื่อว่า JOHN แล้วตั้งค่าให้มันเป็น DAHDI/1 จากนั้นเมื่อเราเขียน Dialplan เราก็อ้างถึงแชนแนลของ John ด้วยชื่อ JOHN ได้ แทนที่จะจำว่า John กำลังใช้แชนแนล DAHDI/1 การตั้งค่าให้แก่ตัวแปรก็ทำได้ง่ายๆเลยครับคือพิมพ์ชื่อของตัวแปร เครื่องหมาย = และก็ค่า แบบนี้

JOHN=DAHDI/1

ชื่อตัวแปรควรเขียนให้เป็นตัวใหญ่นะครับ (แต่ไม่ได้บังคับ) เพื่อให้ดูง่ายๆและรู้เลยว่ามันเป็นตัวแปร

การนำตัวแปรมาใช้งานเราก็แค่อ้างถึงชื่อของมันใน Dialplan ซึ่งการอ้างชื่อมีอยู่ 2 วิธีด้วยกัน คือ ถ้าต้องการใช้เฉพาะชื่อตัวแปรก็พิมพ์ชื่อตัวแปรตรงๆ เช่น JOHN แต่ถ้าต้องการ "ค่า" ของมันต้องใช้เครื่องหมาย $ ตามด้วยชื่อตัวแปรที่อยู่ในเครื่องหมาย [] มาดูตัวอย่างการอ้างถึงตัวแปรภายใน Application Dial() ครับ

exten => 555,1,Dial(${JOHN},,r)

ใน Dialplan ของเรา ที่ไหนก็ตามที่เราเขียน ${JOHN} จะทำให้ Asterisk แทนค่าของมันโดยอัตโนมัติด้วยค่าอะไรก็ตามที่ตั้งไว้ให้แก่ตัวแปรชื่อ JOHN ชื่อตัวแปรไม่จำเป็นต้องเป็นอักษรตัวใหญ่นะครับ แต่เพื่อทำให้แตกต่างไปจากชื่อ Application ก็เลยใช้เป็นตัวใหญ่

ใน Dialplan เราใช้ตัวแปรได้ 3 ประเภท ได้แก่ Global, Channel และ Environment มาดูรายละเอียดและตัวอย่างการใช้งานตัวแปรแต่ละแบบกันครับ

6.1 ตัวแปร Global (Global Variables)
บทบาทของตัวแปร Global ก็เป็นตามชื่อของมันเลยครับ ตัวแปร Global มีผลกับทุก Extension ในทุกๆ Context ตัวแปรแบบ Global มีประโยชน์คือเรียกใช้ที่ไหนก็ได้ใน Dialplan เพื่อทำให้เราอ่านและจัดการกับ Dialplan ได้ง่ายขึ้น ลองสมมติเล่นๆนะครับว่าเรามี Dialplan ที่ใหญ่พอสมควรและมีอยู่หลายร้อยครั้งที่เราอ้างถึงแชนแนล DAHDI/1 ต่อมาปรากฏว่า DAHDI/1 เสียใช้งานไม่ได้ เราต้องไปใช้แชนแนล DAHDI/2 เราต้องไปเปลี่ยน Dialplan ใช่มั๊ยครับ เปลี่ยนจาก DAHDI/1 เป็น DAHDI/2 หรือเปลี่ยนจาก /1 ไปเป็น /2 มีตั้งหลายร้อยที่ซึ่งเราจะต้องเปลี่ยน ไม่ใช่ง่ายๆเลยใช่มั๊ยครับและยังผิดพลาดได้ง่ายอีกต่างหาก

ถ้าเราตั้งตัวแปรแบบ Global ขึ้นมาและตั้งค่าให้มันเป็น DAHDI/1 ณ ตอนเริ่มต้น Dialplan แล้วอ้างอิงถึงค่าตัวแปรแทน เราก็เปลี่ยนแค่บรรทัดเดียว

การประกาศว่าเราจะใช้ตัวแปรแบบ Global จะประกาศไว้ใน context พิเศษที่ชื่อ [globals] ทำตอนเริ่มต้นของไฟล์ extensions.conf เลย หรือเราอาจจะประกาศในลักษณะการโปรแกรมได้ด้วยนะครับ โดยใช้ Application ที่ชื่อว่า SetGlobalVar() ลองมาดูตัวอย่างกัน

[globals]
JOHN=DAHDI/1

[internal]
exten => 123,1,SetGlobalVar(JOHN=DAHDI/1)

6.2 ตัวแปร Channel (Channel Variables)
ตัวแปร channel เป็นตัวแปรที่เกี่ยวข้องกับคอลที่กำลังเกิดขึ้นในขณะนั้น (เช่น Caller ID number) มันไม่เหมือนกับตัวแปร global ตรงที่ตัวแปรแบบ channel ถูกเซ็ตและมีค่าเฉพาะในช่วงระยะเวลาที่เกิดคอลปัจจุบันและมีค่ากับเฉพาะ channel ที่รองรับคอลนั้นเท่านั้น เมื่อคอลสิ้นสุดลงทั้งตัวแปร channel และค่าของมันก็จะหายไป

มีตัวแปรแบบ channel อยู่มากมายที่เรานำไปใช้งานใน Dialplan ได้เลย เพียงแค่อ้างถึงชื่อตัวแปรก็ใช้งานได้แล้ว ไม่ต้องประกาศชื่อตัวแปรเหมือนตัวแปร Global ดูรายละเอียดของแต่ละตัวแปรได้ในไฟล์ README.variables ในไดเร็คตอรี่ doc ของซอร์สโค๊ดนะครับ ตัวแปรบางตัว Asterisk ได้เซ็ตค่าให้เราแล้ว บางตัวเราต้องเซ็ตค่าเองนะครับ การเซ็ตค่าให้แก่ตัวแปร channel เราใช้ Application ชื่อ Set() ดังตัวอย่าง

exten => 123,1,Set(MAGICNUMBER=42)

นับจากนี้ไปผมจะค่อยๆเพิ่มการใช้งานตัวแปร channel ให้มากขึ้นเรื่อยๆ

6.3 ตัวแปร Environment
ตัวแปร enviromnent ใช้เมื่อต้องการเข้าถึงตัวแปร Environment ของระบบ Unix การอ้างถึงตัวแปรแบบนี้นะครับให้อ้างโดยใช้รูปแบบ ${ENV(var)} โดยที่ var เป็นตัวแปร Unix environment ที่เราต้องการจะเรียกใช้งาน ตัวแปรแบบนี้ไม่ค่อยเจอในการเขียน Dialplan ครับ

6.4 การใช้งานตัวแปร ใน Dialplan
ตอนนี้เราได้เรียนรู้เกี่ยวกับตัวแปรมาทั้งหมดแล้วนะครับว่ามีกี่แบบ แต่ละแบบใช้งานอย่างไร ต่อไปก็เอามาใช้ประโยชน์ในการเขียน Dialplan โดยอันดับแรกเราจะเพิ่มตัวแปรสำหรับยูสเซอร์ 2 คนที่เป็นตัวอย่างของเราคือ John และ Jane

[globals]
JOHN=DAHDI/1
JANE=SIP/jane

[incoming]
exten => s,1,Answer()
exten => s,2,Background(enter-ext-of-person)
exten => 101,1,Dial(${JOHN},10)
exten => 101,2,Playback(vm-nobodyavail)
exten => 101,3,Hangup()
exten => 101,102,Playback(tt-allbusy)
exten => 101,103,Hangup()
exten => 102,1,Dial(${JANE},10)
exten => 102,2,Playback(vm-nobodyavail)
exten => 102,3,Hangup()
exten => 102,102,Playback(tt-allbusy)
exten => 102,103,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()

[internal]
exten => 101,1,Dial(${JOHN},,r)
exten => 102,1,Dial(${JANE},,r)

มีการประกาศตัวแปรแบบ Global ชื่อ JOHN และ JANE พร้อมทั้งตั้งค่าให้ด้วย และใน Dialplan ก็เรียกใช้ตัวแปร 2 ตัวนี้อยู่หลายที่ การนำเอาค่าตัวแปรมาใช้งานก็อย่าลืมเขียนชื่อตัวแปรให้อยู่ภายในเครื่องหมาย ${} นะครับ เช่น ${JOHN} และ ${JANE}

7. Pattern Matching
ได้ลองทำตัวอย่าง Dialplan มาหลายตัวอย่างแล้วนะครับ ก็คงจะพอมองออกว่าเวลาเราจะโทรไปเบอร์ไหน ไปหาใคร เราก็ต้องเอาเบอร์ของคนนั้นมาใส่ไว้ใน Dialplan ทีนี้มาลองนึกดูเล่นๆนะครับ ถ้าเราจะโทรออกไปหาเบอร์ภายนอก เช่นเบอร์บ้าน เบอร์มือถือ โทรออกผ่านแชนแนลต่างๆเช่น DAHDI, SIP เป็นต้น เราก็ต้องเอาเบอร์ปลายทางมาใส่ไว้ใน Dialplan ด้วยเราถึงจะโทรไปหาเขาได้ แล้วเบอร์ปลายทางที่ว่ามันมีกี่เบอร์กันหล่ะครับ ? ผมว่าหลายล้านเบอร์ แล้ว Dialplan มันจะใหญ่สักขนาดใหนแล้วใส่เบอร์เข้าไปไหวเหรอครับ
การแก้ปัญหาที่ว่าต้องใส่ Extension ปลายทางจำนวนมากๆนี้ เราจะใช้เทคนิคที่เรียกว่า Pattern Matching ครับ ตอนที่เราคอนฟิก Extension เราก็ใส่เพียงแค่ส่วนใดส่วนหนึ่งของมันเท่านั้นไม่ต้องใส่จนครบทุกหลัก

7.1 รูปแบบของ Pattern Matching
การใช้งาน Pattern Matching นั้นนะครับ ตอนที่เราเขียน Extension เราไม่ต้องใส่ให้ครบทุกหลัก ใส่แค่หลักแรกๆก็พอแล้วใช้ตัวอักษรและตัวเลขมาเขียนรวมกันและขึ้นต้นด้วยเครื่องหมาย _ ซึ่งเครื่องหมายนี้จะบอก Asterisk ว่า Extension ที่มันเห็นนั้นเป็น Pattern Matching
แต่ถ้าเราลืมใส่เครื่องหมาย _ ข้างหน้า Asterisk จะคิดว่ามันเป็น Extension Name แล้วมันก็จะไม่ทำ Pattern Matching ให้นะครับ ดังนั้นอย่าลืม
หลังเครื่องหมาย _ เราสามารถใช้ตัวอักษรตัวใดตัว อาจใช้แค่ตัวเดียวหรือหลายๆตัวก็ได้ ดังต่อไปนี้

X แม็ตซ์กับตัวเลขอะไรก็ได้ ระหว่าง 0 ถึง 9
Z แม็ตซ์กับตัวเลขอะไรก็ได้ ระหว่าง 1 ถึง 9
N แม็ตซ์กับตัวเลขอะไรก็ได้ ระหว่าง 2 ถึง 9
[15-7] แม๊ตซ์กับช่วงตัวเลขที่ระบุ ในกรณีนี้แม๊ตซ์กับ 1,5,6 หรือ 7
. (เครื่องหมายจุด) เป็น Wildcad แม๊ตซ์กับตัวเลขอะไรก็ได้ กี่หลักก็ได้

ถ้าเราใช้ Wildcard โดยไม่ระวัง ก็อาจทำให้ Dialplan ทำงานไม่เป็นไปตามที่คาดหวังก็ได้นะครับ ดังนั้นเราควรใช้ Wildcard ใน Pattern Matching หลังจากที่เราได้แม๊ตซ์ตัวเลขให้มากที่สุดที่จะเป็นไปได้แล้วเท่านั้น ยกตัวอย่างเช่น Pattern Match แบบนี้ _. ไม่ควรใช้เลยนะครับ แต่จริงๆมันก็ใช้ได้นะครับเพียงแค่ Asterisk จะฟ้องเตือนให้เราเปลี่ยนใหม่ เปลี่ยนเป็น _X. แทนดีกว่าครับ

การใช้ Pattern Matching ใน Dialplan ก็ทำได้ง่ายๆครับ เพียงแค่วาง Pattern ไว้แทนตำแหน่ง Extension Name (หรือ Number) เช่น

exten => _NXX,1,Playback(auth-thankyou)

ในตัวอย่างนี้ Pattern จะแม็ตซ์กับ Extension 3 หลัก เริ่มจาก 200 ถึง 999 (ตัว N จะแทนกับตัวเลขใดๆระหว่าง 2 ถึง 9) และ X แต่ละตัวแทนตัวเลขระหว่าง 0 ถึง 9
ก็จะได้ว่าถ้ายูสเซอร์กด Extension 3 หลักระหว่าง 200 ถึง 999 เขาจะได้ยินเสียงพูดในไฟล์ auth-thankyou.gsm

สิ่งสำคัญอีกอย่างหนึ่งที่เราต้องรู้เกี่ยวกับการทำ Pattern Matching ก็คือ ถ้า Asterisk พบว่ามีหลาย Pattern ที่แม๊ตซ์กับ Extension ที่เรากด มันจะเลือกใช้ Pattern ที่มีตัวเลขแม๊ตซ์มากที่สุด ตัวอย่างเช่นถ้าเราสร้าง 2 Pattern แบบนี้

exten => _02888XXXX,1,Playback(digits/1)
exten => _028888XXX,1,Playback(digits/2)

ถ้ายูสเซอร์กด 028888888 Asterisk จะเลือกใช้ Extension ที่สองเพราะมันตรงมากกว่า

7.2 ตัวอย่าง Pattern Matching
มาดูตัวอย่าง Pattern Matching อีกสองสามตัวอย่าง มาลองแปลความหมายของแต่ละ Pattern กันครับว่ามันจะแม๊ตซ์กับอะไร อย่าเพิ่งดูเฉลยก่อนนะครับ เริ่มจาก
_NXXXXXX
ได้มั๊ยครับ Pattern นี้จะแม๊ตช์กับตัวเลขอะไรก็ได้ 7 หลัก ซึ่งที่หลักแรกมีค่าตั้งแต่ 2 ขึ้นไป ซึ่งตาม North American Numbering Plan แล้ว Pattern นี้จะแม๊ตซ์กับ Local Number

_1NXXNXXXXXX

ตัวอย่างนี้ยากขึ้นมาอีกนิด ซึ่งจะแม๊ตซ์ เลข 1 ตามด้วยรหัสพื้นที่ระหว่าง 200 ถึง 999 และตัวเลขใดๆอีก 7 หลักขึ้นต้นด้วย 2

_011.
ซึ่งจะแม็ตซ์กับเบอร์ใดๆที่ขึ้นต้นด้วย 011 และมีอีกอย่างน้อย 1 หลักตามหลัง

7.3 การใช้ตัวแปร ${EXTEN}
เรารู้มาว่า Pattern Matching มันแทนตัวเลขอะไรก็ได้ที่เข้าข่ายใน Pattern แล้ว ถ้าเราต้องการรู้ว่ายูสเซอร์กด Extension อะไร เราใช้ตัวแปรแบบ Channel ที่ชื่อว่า EXTEN ช่วยได้นะครับ แล้วเอา Application ที่ชื่อ SayDigits() อ่านออกมา

exten => _XXX,1,SayDigits(${EXTEN})

ในตัวอย่างนี้ SayDigits() จะอ่าน Extension 3 หลักที่เรากด

บางครั้งเราอาจมีความจำเป็นต้องตัดหลักแรกๆของ Extension ที่กดออก เช่นจะโทรออกไปสายนอกแต่ต้องกดตัวเลข Access Code เช่น 9 ก่อน เราต้องตัดเลข 9 ออกก่อนแล้วส่งเบอร์ที่เหลือไปยังแชนแนลที่ใช้โทรออก กรณีนี้เราให้ตัวแปร ${EXTEN} ช่วยได้นะครับ ตัวแปรนี้สามารถตัดตัวเลขข้างหน้า Extension กี่หลักก็ได้ที่เราต้องการ โดยใช้รูปแบบ ${EXTEN:x} โดยที่ x เป็นจำนวนหลักที่ต้องการตัดออก ยกตัวอย่างเช่นถ้า EXTEN มีค่าเป็น 9028888888 เมื่อเราใช้ ${EXTEN:1} จะทำให้ Extension กลายเป็น 028888888 มาดูตัวอย่างอื่นบ้างครับ

exten => _XXX,1,SayDigits(${EXTEN:1})

SayDigits() จะบอกเฉพาะเลข 2 หลักสุดท้าย

ถ้า x มีค่าเป็น - ก็จะหมายถึงตัวเลขตัวสุดท้าย (ขวามือสุด) ใน extension

exten => _XXX,1,SayDigits(${EXTEN:-1})

SayDigits() จะอ่านหลักสุดท้าย

ในทางตรงกันข้ามเราก็สามารถเติมตัวเลขไว้หน้า Extension ได้ด้วย เราเรียกว่า Prefix โดยใส่ตัวเลขที่ต้องการเติมเข้าไปไว้ข้างหน้า ${EXTEN} เช่น

exten => _90X.,1,SayDigit(66${EXTEN:1})

แล้วเรากด 9028888888 SayDigits() จะบอกว่าตัวเลขที่เรากดคือ 6628888888

8. สร้าง Dialplan ให้โทรออกไปภายนอกได้ (Outbound Dialing)

ตอนนี้เราก็ได้รู้จักประโยชน์ของ Pattern Matching แล้วนะครับ เราจะนำมาใช้สร้าง Dialplan ให้ยูสเซอร์โทรออกสายนอกได้ด้วย อันดับแรกให้เพิ่มตัวแปรไว้ที่ [globals] เพื่อที่เราจะเอาไปใช้งานเมื่อต้องระบุแชนแนลที่จะใช้โทรออกสายนอก

[globals]
JOHN=Zap/1
JANE=SIP/jane
OUTBOUNDTRUNK=DAHDI/4

ขั้นตอนต่อไปให้เพิ่ม Context สำหรับใช้โทรออกสายนอก ควรแยกให้อยู่คนละ Context กับยูสเซอร์ภายในนะครับ เพราะว่าเราสามารถเพิ่มการควบคุมได้ว่าใครมีสิทธิที่จะโทรออกไปสายนอกได้บ้างและโทรไปเบอร์อะไรได้บ้าง เบอร์ใน

ประเทศไทย หรือว่าต่างประเทศ

สร้าง Context สำหรับโทรภายในประเทศก่อนครับ ซึ่งในการโทรออกสายนอกนี้เราตั้งว่ายูสเซอร์ต้องกด 9 นำหน้าตามด้วยเบอร์

[outbound-local]
exten => _90X.,1,Dial(${OUTBOUNDTRUNK/${EXTEN:1})
exten => _90X.,2,Congestion()
exten => _90X.,102,Congestion

ถ้าเราใช้ IP Phone หรือ Softphone เราก็กด 9 ตามด้วยบอร์ปลายทางในประเทศไทยได้เลย เช่น 9028888888 จากนั้น Asterisk จะตัด 9 ออก แล้วส่ง 028888888 ออกไปยัง ${OUTBOUNDTRANK} ต่อไป แต่ถ้าเรามีการ์ด DAHDI พอร์ต FXS

และมีเครื่องโทรศัพท์ต่ออยู่ เมื่อเรายกหูขึ้นมาเราจะได้ยินเสียง Dial Tone เมื่อเรากด 9 เสียง Tone จะหยุดดัง ถ้าเราต้องการให้เสียงโทนดังไปตลอดจนกว่าจะกดเบอร์เสร็จ ให้ใส่บรรทัดนี้

ignorepat => 9

เพิ่มเข้าไปใน Context ด้วย ซึ่ง ignorepat เป็นไดเร็คทีฟ (Directive) ซึ่งจะบอก Asterisk ว่าให้จ่ายสัญญาณโทนออกมาอย่างต่อเนื่องแม้ว่ายูสเซอร์จะกด Pattern ตรงแล้วก็ตาม

ใน Dialplan เราได้เพิ่มตัวแปร global ที่มีชื่อว่า OUTBOUNDTRUNK ซึ่งเราจะใช้ตัวแปรนี้เลือกแชนแนลที่จะโทรออกสายนอก (Outbound call) นอกจากนั้นเรายังได้เพิ่ม Context สำหรับโทรออกไปสายนอกภายในประเทศอีกด้วย ใน Priority 1

เรารับ Extension ที่ยูสเซอร์กด ตัดเลข 9 หลักแรกออกด้วย ${EXTEN:1} และจากนั้นโทรไปยังเบอร์นั้นทางแชนแนล DAHDI/4 ที่เราตั้งไว้ในตัวแปร OUTBOUNDTRUNK
ถ้าโทรได้สำเร็จยูสเซอร์จะถูกบริดจ์เข้ากับแชนแนลที่ใช้โทรออก แต่ถ้าโทรไม่สำเร็จ (อาจเป็นเพราะว่าแชนแนลไม่ว่างหรือติดต่อเบอร์ปลายทางไม่ได้) ก็จะเรียกใช้ Application ที่ชื่อ Congestion() เราจะได้ยินเสียง Busy แบบเร็วๆ เรียกว่า Fast

Busy Signal หรือ Congestion tone เราก็จะรู้ว่าโทรไม่สำเร็จ

[outbound-local]
exten => _90X.,1,Dial(${OUTBOUNDTRUNK/${EXTEN:1})
exten => _90X.,2,Congestion()
exten => _90X.,102,Congestion

exten => 191,1,Dial(${OUTBOUNDTRUNK}/191)
exten => 199,1,Dial(${OUTBOUNDTRUNK}/199)

ต่อไปให้เพิ่ม Context สำหรับโทรทางไกลระหว่างประเทศ

[outbound-long-distance]
exten => _9[1-9]X.,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten => _9[1-9]X.,2,Congestion()
exten => _9[1-9]X.,102,Congestion()

ตอนนี้เราสร้างเพิ่มอีก 2 Context สำหรับโทรออกไปสายนอกทั้งในประเทศไทยและต่างประเทศ แต่ยูสเซอร์ภายในก็ยังมาใช้งานไม่ได้ ในหัวข้อต่อไปเราจะทำให้ยูสเซอร์ภายในโทรออกสายนอกได้

9. ไดเร็คทีฟ Includes
ตอนแรกๆของบทความผมเคยบอกว่า Context ทำให้ Dialplan แยกกันเป็นส่วนๆ ยูสเซอร์ที่อยู่คนละ Context ไม่สามารถโทรหากันได้ ไม่สามารถไปใช้แชนแนลที่อยู่ใน Context อื่นได้ แต่ตอนนี้ผมจะบอกว่าเราสามารถทำได้แล้ว โดยใช้ไดเร็คทีฟที่มีชื่อว่า include ซึ่งมันจะยอมให้เราเข้าไปใน Context อื่นได้ และในกรณีนี้เราจะใช้ include เพื่อทำให้ให้ยูสเซอร์ที่อยู่ใน Context [internal] โทรออกไปภายนอกได้ด้วย

รูปแบบการใช้งานไดเร็คทีฟ include คือ

include => context

โดยที่ context เป็นชื่อ Context อื่นที่เราต้องการ include เข้ามาไว้ใน Context ปัจจุบัน

เมื่อเรานำ Context อื่นมาไว้ภายใน Context ปัจจุบันที่เราอยู่ เราต้องคำนึงถึงลำดับที่เราจะ include มันเข้ามาด้วยนะครับ เพราะลำดับเป็นเรื่องสำคัญใน Asterisk มันจะพยายามแม๊ตซ์ Extension ที่อยู่ใน Context ปัจจุบันก่อน ถ้ามันหาไม่เจอมันก็จะไปหาจาก Context แรกสุดที่ถูก Include ถ้าหาไม่เจออีกก็จะไปหาจาก Context ต่อไปที่ถูก Include เข้ามาเช่นเดียวกัน

Dialplan ของเรามีอยู่ 2 Context ที่โทรออกไปภายนอกได้ แต่ยูสเซอร์ใน Context [internal] ยังไม่มีทางที่จะโทรออกไปภายนอกได้ ทางแก้ก็คือเราต้อง Include ทั้ง Context [outbound-local] และ [outbound-long-distance] มาไว้ใน [internal] ดังตัวอย่าง

[globals]
JOHN=Zap/1
JANE=SIP/jane
OUTBOUNDTRUNK=DAHDI/4

[incoming]
exten => s,1,Answer()
exten => s,2,Background(enter-ext-of-person)
exten => 101,1,Dial(${JOHN},10)
exten => 101,2,Playback(vm-nobodyavail)
exten => 101,3,Hangup()
exten => 101,102,Playback(tt-allbusy)
exten => 101,103,Hangup()
exten => 102,1,Dial(${JANE},10)
exten => 102,2,Playback(vm-nobodyavail)
exten => 102,3,Hangup()
exten => 102,102,Playback(tt-allbusy)
exten => 102,103,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()

[internal]
include => outbound-local
include => outbound-long-distance

exten => 101,1,Dial(${JOHN},,r)
exten => 102,1,Dial(${JANE},,r)

[outbound-local]
exten => _90X.,1,Dial(${OUTBOUNDTRUNK/${EXTEN:1})
exten => _90X.,2,Congestion()
exten => _90X.,102,Congestion

exten => 191,1,Dial(${OUTBOUNDTRUNK}/191)
exten => 199,1,Dial(${OUTBOUNDTRUNK}/199)

[outbound-long-distance]
exten => _9[1-9]X.,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten => _9[1-9]X.,2,Congestion()
exten => _9[1-9]X.,102,Congestion()

การเพิ่ม include เข้าไป 2 บรรทัดทำให้ยูสเซอร์ใน Context [internal] โทรออกไปภายนอกได้ และเราควรป้องกันไม่ได้ยูสเซอร์ที่โทรเข้ามาทาง Context [incoming] โทรออกไปสายนอกได้โดยไม่ Include [outbound-local] และ [outbound-long-distance] ไปไว้ใน [incoming] ไม่อย่างนั้นอาจจะมีบุคคลภายนอกแอบใช้ระบบของเราโทรออกไปสายนอก

โปรดรอติดตามภาค II ครับ
voip4share
Administrator
 
โพสต์: 656
ลงทะเบียนเมื่อ: 18 พ.ย. 2009 11:26
ที่อยู่: รามคำแหง กรุงเทพฯ

Re: เทคนิคและวิธีการเขียน Asterisk Dialplan I ตอนที่ 4 (จบ)

โพสต์โดย linglek » 16 มี.ค. 2010 01:18

สอนเรื่องการทำ humting บ้างได้ไหมครับ
linglek
 
โพสต์: 1
ลงทะเบียนเมื่อ: 16 มี.ค. 2010 00:51

Re: เทคนิคและวิธีการเขียน Asterisk Dialplan I ตอนที่ 4 (จบ)

โพสต์โดย voip4share » 16 มี.ค. 2010 09:26

ใช่ Hunting หรือเปล่าครับ เป็น Inbound Hunting ใช้ตอนรับสายเข้ามา ใช้เทคนิค Queues ซึ่งมีใน Asterisk อยู่แล้วเลยทำไม่ยาก และ Outbound Hunting ใช้ตอนเลือก Trunk โทรออก อันนี้ยากครับยิ่งถ้าจะทำเป็น Round Robin ด้วยแล้วยิ่งยากใหญ่ ไว้ผมจะเขียนเรื่อง Queues ก่อน
voip4share
Administrator
 
โพสต์: 656
ลงทะเบียนเมื่อ: 18 พ.ย. 2009 11:26
ที่อยู่: รามคำแหง กรุงเทพฯ

Re: เทคนิคและวิธีการเขียน Asterisk Dialplan I ตอนที่ 4 (จบ)

โพสต์โดย FamouS_Inw » 09 พ.ค. 2010 21:02

สอนเรื่องการเขียน AGI บ้างสิครับ กำลังศึกษาอยู่ครับ เช่น ใช้ AGI ทำงานร่วมกับ PHP และ ใน Dial plan จะดึงเอาค่าตัวแปรจาก PHP มาใช้ยังไงครับ
FamouS_Inw
 
โพสต์: 4
ลงทะเบียนเมื่อ: 09 เม.ย. 2010 17:44


ย้อนกลับไปยัง Asterisk SIP Server

ผู้ใช้งานขณะนี้

กำลังดูบอร์ดนี้: ไม่มีสมาชิกใหม่ และ บุคคลทั่วไป 2 ท่าน