Vừa rồi chúng ta đã xây dựng các dịch vụ riêng rẽ, vấn đề cần đặt ra là phải liên kết các dịch vụ trong hệ thống và tạo các ngữ cảnh cho các thuê bao nội bộ trong việc gọi đến và đi ứng với mỗi thuê bao. Trong hệ thống sẽ tạo các dial plan chính ứng với 3 loại điện thoại được sử dụng trong hệ thống đó là: analogphone
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 140 -
tham gia vào mạng IP, điện thoại sử dụng giao thức SIP và điện thoại sử dụng giao thức IAX.
Trước hết cần tạo ra ngữ cảnh gọi đến đối với thuê bao nội bộ, vì các thuê bao nội bộ không chỉ đơn thuần sử dụng chuyển mạch thông thường mà còn tích hợp các dịch vụ, do vậy việc cấu hình phải kết hợp kèm các dịch vụ. Giả sử khi có một số gọi đến thuê bao nội bộ nào đó, trước hết chúng ta cần xét xem thuê bao đó có kích hoạt dịch vụ DND hay không?Kế đến chúng ta phải xét xem thuê bao có kích hoạt chuyển cuộc gọi hay không, nếu có thì phải thực hiện dịch vụ, nếu không thì thực hiện chuyển mạch bình thường. Bởi vì mỗi thuê bao sử dụng giao thức khác nhau thì việc cấu hình đôi khi có sự khác biệt. Vì vậy ở đây chúng ta sẽ tạo ra 3 ngữ cảnh: [local_IAX] - ứng với ngữ cảnh gọi đến đối với điện thoại sử dụng giao thức IAX, [local_SIP]- ứng với ngữ cảnh gọi đến đối với điện thoại sử dụng giao thức SIP, [local_analog] - ứng với ngữ cảnh gọi đến đối với điện thoại analog. Việc cấu hình trong file /etc/asterisk/extensions.conf được thực hiện như sau:
[local_IAX]
exten => _3xx,1,Set(COUNT1=${EXTEN})
exten => _3xx,n,gotoif($[${DB(dnd/${EXTEN})} = 1]?NBSY1:N1) exten => _3xx,n(N1),set(GROUP()=${CALLERID(num)})
exten => _3xx,n,Set(GROUP()=${EXTEN})
exten => _3xx,n,NoOP(Group count is ${GROUP_COUNT()}, group is ${GROUP()}, exten is ${EXTEN})
exten => _3xx,n,GotoIf($[${GROUP_COUNT()} > 1]?BSY:NBSY) exten => _3xx,n(NBSY),Set(TEMP=${DB(CFIM/${COUNT1})}) exten => _3xx,n,GotoIf(${TEMP}?IM:NIM)
exten => _3xx,n(IM),GotoIf($[${TEMP} < 201]?CS2:IM2) exten => _3xx,n(IM2),GotoIf($[${TEMP} < 401 ]?CS1:CS3)
exten =>_3xx,n(CS1),Dial(IAX2/${TEMP}/@${TEMP},20,tT) ; Chuyển tức thời exten => _3xx,n,Goto(exithandling,s-${DIALSTATUS},1)
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 141 -
exten => _3xx,n,Goto(exithandling,s-${DIALSTATUS},1) exten => _3xx,n(CS3),goto(out,${TEMP},1)
exten => _3xx,n,Goto(exithandling,s-${DIALSTATUS},1)
exten => _3xx,n(NIM),NoOp("Khong chuyen tuc thoi, thuc hien binh thuong") exten => _3xx,n,Dial(IAX2/${EXTEN},3,rtT) ; exten => _3xx,n,Goto(exithandling,s-${DIALSTATUS},1) ; exten => _3xx,n(BSY),goto(exithandling,s-BUSY,1) exten => _3xx,n(NBSY1),goto(exithandling1,s-BUSY,1) [local_analog] exten => _1xx,1,Set(COUNT1=${EXTEN}) exten => _1xx,n,set(GROUP()=${CALLERID(num)})
exten => _1xx,n,gotoif($[${DB(dnd/${EXTEN})} = 1]?NBSY2:N2)
exten => _1xx,n(N2),NoOP(Group count is ${GROUP_COUNT()}, group is ${GROUP()}, exten is ${EXTEN})
exten => _1xx,n,Set(TEMP=${DB(CFIM/${COUNT1})}) exten => _1xx,n,GotoIf(${TEMP}?IM1:NIM1)
exten => _1xx,n(IM1),GotoIf($[${TEMP} < 201]?CS2:IM2) exten => _1xx,n(IM2),GotoIf($[${TEMP} < 401 ]?CS1:CS3)
exten => _1xx,n(CS1),Dial(IAX2/${TEMP}/@${TEMP},20,tT) ; Chuyển tức thời exten => _1xx,n,Goto(exithandling,s-${DIALSTATUS},1)
exten => _1xx,n(CS2),Dial(SIP/${TEMP},20,tT)
exten => _1xx,n,Goto(exithandling,s-${DIALSTATUS},1) exten => _1xx,n(CS3),goto(out,${TEMP},1)
exten => _1xx,n,Goto(exithandling,s-${DIALSTATUS},1)
exten => _1xx,n(NIM1),NoOp("Khong chuyen tuc thoi, thuc hien binh thuong") exten => _1xx,n,Dial(SIP/${EXTEN},20,rtT) ;
exten => _1xx,n,Goto(exithandling,s-${DIALSTATUS},1) ; exten => _1xx,n(NBSY2),goto(exithandling1,s-BUSY,1)
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 142 -
[local_SIP]
exten => _2xx,1,Set(COUNT1=${EXTEN})
exten => _2xx,n,set(GROUP()=${CALLERID(num)})
exten => _2xx,n,gotoif($[${DB(dnd/${EXTEN})} = 1]?NBSY2:N2)
exten => _2xx,n(N2),NoOP(Group count is ${GROUP_COUNT()}, group is ${GROUP()}, exten is ${EXTEN})
exten => _2xx,n,Set(TEMP=${DB(CFIM/${COUNT1})}) exten => _2xx,n,GotoIf(${TEMP}?IM1:NIM1)
exten => _2xx,n(IM1),GotoIf($[${TEMP} < 201]?CS2:IM2) exten => _2xx,n(IM2),GotoIf($[${TEMP} < 401 ]?CS1:CS3)
exten => _2xx,n(CS1),Dial(IAX2/${TEMP}/@${TEMP},20,tT) ; Chuyển tức thời exten => _2xx,n,Goto(exithandling,s-${DIALSTATUS},1)
exten => _2xx,n(CS2),Dial(SIP/${TEMP},20,tT)
exten => _2xx,n,Goto(exithandling,s-${DIALSTATUS},1) exten => _2xx,n(CS3),goto(out,${TEMP},1)
exten => _2xx,n,Goto(exithandling,s-${DIALSTATUS},1)
exten => _2xx,n(NIM1),NoOp("Khong chuyen tuc thoi, thuc hien binh thuong") exten => _2xx,n,Dial(SIP/${EXTEN},3,rtT) ;
exten => _2xx,n,Goto(exithandling,s-${DIALSTATUS},1) ; exten => _2xx,n(NBSY2),goto(exithandling1,s-BUSY,1) [exithandling]
; this is just my exit handler. the important thing is in queue-to-agent context exten => s-NOANSWER,1,NoOP(There was no answer to call from
${CALLERID(num)})
exten => s-NOANSWER,n,Set(TEMP=${DB(CFAS/${COUNT1})}) exten => s-NOANSWER,n,GotoIf(${TEMP}?AS:NAS)
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 143 -
exten => s-NOANSWER,n(IM2),GotoIf($[${TEMP} < 401 ]?CS1:CS3)
exten => s-NOANSWER,n(CS1),Dial(IAX2/${TEMP}/@${TEMP},30,tT) ; Chuyển tức thời) exten => s-NOANSWER,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-NOANSWER,n(CS2),Dial(SIP/${TEMP},30,tT) exten => s-NOANSWER,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-NOANSWER,n(CS3),goto(out,${TEMP},1) exten => s-NOANSWER,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-NOANSWER,n(NAS),VoiceMail(${COUNT1}@default) exten =>s-NOANSWER,n,playback(vm-goodbye) exten => s-NOANSWER,n,Wait(2) exten => s-NOANSWER,n,Hangup()
exten => s-BUSY,1,NoOP(There was no answer to call from ${CALLERID(num)}) exten => s-BUSY,n,Set(TEMP=${DB(CFBS/${COUNT1})})
exten => s-BUSY,n,GotoIf(${TEMP}?BS2:NBS2)
exten => s-BUSY,n(BS2),gotoIf($[${TEMP} < 201]?CS2:IM2);Chuyển khi không trả lời
exten => s-BUSY,n(IM2),GotoIf($[${TEMP} <401 ]?CS1:CS3)
exten => s-BUSY,n(CS1),Dial(IAX2/${TEMP}/@${TEMP},30,tT) ; Chuyển tức thời) exten => s-BUSY,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-BUSY,n(CS2),Dial(SIP/${TEMP},30,tT) exten => s-BUSY,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-BUSY,n(CS3),goto(out,${TEMP},1) exten => s-BUSY,n,Goto(exithandling1,s-${DIALSTATUS},1) exten => s-BUSY,n(NBS2),VoiceMail(${COUNT1}@default) exten => s-BUSY,n,playback(vm-goodbye) exten => s-BUSY,n,Wait(2)
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 144 -
exten => s-BUSY,n,Hangup()
exten => s-CHANUNAVAIL,1,NoOP(Channel navailable, call from ${CALLERID(num)})
exten => s-CHANUNAVAIL,2,goto(exithandling,s-BUSY,1)
exten => s-CONGESTION,1,NoOP(Congestion, call from ${CALLERID(num)}) exten => s-CONGESTION,2,Hangup
exten => s-ANSWER,1,NoOP(Answered and completed call from ${CALLERID(num)})
exten => s-ANSWER,2,Hangup [exithandling1]
; this is just my exit handler. the important thing is in queue-to-agent context exten => s-NOANSWER,1,NoOP(There was no answer to call from
${CALLERID(num)})
exten => s-NOANSWER,n(NAS),VoiceMail(${COUNT1}@default) exten => s-NOANSWER,n,playback(vm-goodbye)
exten => s-NOANSWER,n,Wait(2) exten => s-NOANSWER,n,Hangup()
exten => s-BUSY,1,NoOP(Extension busy, call from ${CALLERID(num)}) exten => s-BUSY,n(NBS2),VoiceMail(${COUNT1}@default)
exten => s-BUSY,n,playback(vm-goodbye) exten => s-BUSY,n,Wait(2)
exten => s-BUSY,n,Hangup()
exten => s-CHANUNAVAIL,1,NoOP(Channel navailable, call from ${CALLERID(num)})
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 145 -
exten => s-CHANUNAVAIL,2,goto(exithandling,s-BUSY,1) exten => s-ANSWER,1,NoOP(Answered and completed call from ${CALLERID(num)})
exten => s-ANSWER,2,Hangup
Kế đến, chúng ta phải xây dựng ngữ cảnh gọi đi cho các thuê bao, tùy vào ý tưởng và nhu cầu của thuê bao mà người quản trị cho phép thuê bao sử dụng dịch vụ nào. Ví dụ, thuê bao này có thể sử dụng dịch vụ DND nhưng thuê bao khác lại không, tất cả đều có thể thực hiện trong dial plan. Ở trong hệ thống này giả sử các thuê bao đều sử dụng tất cả các dịch vụ được xây dựng. Ta giả sử trong hệ thống thuê bao 200 và 300 đều có thể gọi ra ngoài bằng 2 line PSTN còn thuê bao 100 chỉ được phép sử dụng line X100P của hệ thống. Tất cả các thuê bao đều có thể gọi ra ngoài internet do nhà cung cấp dịch vụ VoIP cung cấp. Tạo ra hai ngữ cảnh [out] và [out1] tương ứng với ý tưởng trên. Việc cấu hình trong file /etc/asterisk/extensions.conf được thực hiện như sau:
[out]
exten => _8.,1,Dial(SIP/${EXTEN:1}@mysipprovider,30,rtT) exten => _9.,1,SET(COUNT1=${EXTEN})
exten => _9.,n,Dial(SIP/${EXTEN:1}@9,20) exten => _9.,n,Goto(s-${DIALSTATUS\,1) exten => s-NOANSWER,1,Hangup()
exten => s-BUSY,1,Dial(Zap/1/${COUNT1:1}) exten => s-CHANUNAVAIL,1,Noop(No Answer) exten =>s-CHANUNAVAIL,2,hangup() include=>parkedcalls include=>DND include=>Parked include=>Meetme include=>pickup
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 146 -
include=>mailbox include=>F_INM include=>F-BSY include=>F-NSWR include=>local_analog include=>local_IAX include=>local_SIP [out1] exten => _8.,1,Dial(SIP/${EXTEN:1}@mysipprovider,30,rtT) exten => _9.,1,Dial(Zap/1/${EXTEN:1}) include=>parkedcalls include=>DND include=>Parked include=>Meetme include=>pickup include=>mailbox include=>F_INM include=>F-BSY include=>F-NSWR include=>local_analog include=>local_IAX include=>local_SIP
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 147 -
KẾT LUẬN
Sau một thời gian nghiên cứu và thực hiện, phần lý thuyết cũng như việc cấu hình các dịch vụ của tổng đài mềm Asterisk được chúng em thực hiện khá đầy đủ và chi tiết. Cụ thể:
* Phần lý thuyết:
- Tìm hiểu tổng quan về công nghệ VoIP
- Tìm hiểu hệ thống asterisk, cách cài đặt và cấu hình và các dịch vụ liên quan.
* Phần thực hiện:
- Thực hiện mô hình ứng dụng thực tế: cuộc gọi trong nội mạng và cuộc gọi ra ngoài PSTN và ngược lại.
- Cấu hình hầu hết các dịch vụ mà một tổng đài IP hiện đại có sẵn như: IVR, voicemail, fordward, transfer, conference, call pickup, call parking, DISA, do not disturb, Asterisk realtime architecture, Call detail record.
* Khả năng ứng dụng của đề tài: cung cấp ứng dụng cho các công ty vừa
và nhỏ là rất lớn
* Hạn chế: do hạn chế về thiết bị cũng như thời gian chuẩn bị nên trong mô
hình thực hiện đôi lúc xảy ra các sự cố sau:
- Đôi khi xảy ra trễ giữa đầu cuối với đầu cuối
- Việc ngắt kết nối với PSTN đôi lúc gặp trục trặc do chức năng của gateway.
* Hướng phát triển đề tài: nghiên cứu phát triển và thực hiện các mô hình
đa site. Xây dựng dịch vụ tính cước cho doanh nghiệp. Đây là mô hình sử dụng nhiều trong thực tế đối với các công ty lớn có nhiều chi nhánh.
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 148 -
TÀI LIỆU THAM KHẢO Tiếng Việt:
1. Công nghệ VoIP và các giải pháp nâng cao chất lượng dịch vụ - NXB Bưu điện.
2. Công nghệ thoại IP và ứng dụng trên mạng viễn thông Việt Nam – Tổng Cục Bưu Điện Việt Nam
Tiếng Anh:
1. O'Reilly - Asterisk The Future Of Telephony 2005Voice over IP Fundamentals (2nd Edition), Cisco Press, 2006
2. IP Telephony (2nd Edition), Cisco Press, 2006
3. Packt Publishing.Building.Telephony.Systems.with.Asterisk.2006 4. VoIP for Dummies by Timothy Kelly
Một số trang web tham khảo:
http://www.asteriskguru.com/tutorials/asterisk_voip_ipphone.html http://my.opera.com/asteriskvn/blog/index.dml
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 149 -
PHỤ LỤC PHỤ LỤC 1: CÀI ĐẶT FEDORA CORE 5
Thực hiện khởi động từ đĩa cài Fedora Core 5, giao diện cài đặt sẽ như hình dưới:
Có thể mất một vài phút để kiểm tra đĩa cài Fedora Core 5. Chọn “Skip” để bỏ qua việc kiểm tra này.
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 150 -
Màn hình chào của Fedora Core 5 xuất hiện, nhấn “Next” để tiếp tục cài đặt.
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 151 -
Chọn chuẩn bàn phím, nên chọn là “English”
Nếu cài đặt Fedora trên một máy tính mới, chưa cài bất cứ hệ điều hành nào khác thì sẽ chọn “yes” để format toàn bộ ổ cứng và cài duy nhất hệ điều hành Fedora Core 5 nên máy tính.
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 152 -
Tiếp tục sẽ là quá trình lập các phân vùng dành cho việc cài đặt Fedora Core 5.
Tiếp đến là quá trình cài đặt địa chỉ IP, chấp nhận lựa chọn mặc định , nhấn “Next” để tiếp tục:
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 153 -
Chọn múi giờ
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 154 -
Tiếp theo là bước chọn các gói để cài, chọn những gói cần thiết tuỳ vào mục đích sử dụng, ở đây để có thể cài đặt máy tính trở thành Asterisk Server, ta nên chọn 2 lựa chọn là “Web Server” và “Software Development”.
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 155 -
Nhấn “Next” để bắt đầu quá trình cài đặt
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 156 -
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 157 -
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 158 -
PHỤ LỤC 2: MỘT SỐ CÂU LỆNH SỬ DỤNG TRONG MYSQL VÀ PHP
Mysql:
SET PASSWORD FOR: Tạo mật khẩu đăng nhập CREATE DATABASE: Tạo cơ sở dữ liệu
USE: Sử dụng cơ sở dữ liệu
SELECT * FROM: Hiển thị bảng dữ liệu
CREATE TABLE: Tạo bảng
INSERT INTO: Đưa dữ liệu vào bảng ;: Kết thúc câu lệnh
Php:
Echo: xuất dữ liệu
<head> </head>: Soạn tiêu đềđầu trang web <tile> </tile>: ghi dòng chữ tiêu đề
<style> </style>: tạo kiểu chữ cho trang web
<body> </body>: Soạn phần nội dung cho trang web <table> </table>: Tạo bảng
<TD> </TD>: Tạo tiêu đề cho bảng <TR> </TR>: Tạo dòng cho bảng
<? ?>: Mở đầu và kết thúc một chương trình con While, for: Câu lệnh điều kiện
If..else: Câu lệnh rẽ nhánh $: Tạo biến
Print: xuất dữ liệu
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 159 -
PHỤ LỤC 3: HƯỚNG DẪN SỬ DỤNG PHẦN MỀM BẮT GÓI ETHEREAL
Download phần mềm Ethereal hoặc phiên bản mới hơn được chuyển tên thành Wireshark và tiến hành cài đặt. Sau khi cài xong ta có giao diện Ethereal như hình bên dưới. Để tiến hành bắt gói ta vào giao diện Interface trên menu Capture:
Chọn card mạng cần capture gói tin:
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 160 -
Thực hiện việc lọc gói để xem cách thức hoạt động của cuộc gọi VoIP thông qua chức năng VoIP Calls ở menu Statistics:
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 161 -
Dùng chức năng Graph để tiến hành phân tích các bản tin trong cuộc gọi VoIP:
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 162 -
PHỤ LỤC 4: CÁC THUẬT NGỮ VIẾT TẮT:
A:
ACD: Automatic Call Distribution API: Application Program Interface AstDB: Asterisk Database
ATA: Analog Telephone Adaptors C:
CDR: Call Detail Record D:
DISA: Direct Inward System Access DND: Do Not Disturb
DTMF: Dual Tone Multi Frequency F:
FXO: Foreign Exchange Office FXS: Foreign Exchange Station I:
IAX: Inter Asterisk eXchange
ICMP: Internet Control Message Protocol IETF: Internet Engineering Task Force IP: Internet Protocol
ISDN: Intergrated Services Digital Network
ITU-T: International Telecommunications Union Telecommunication IVR: Interactive voice response
L:
LAN: Local Area Network M:
MCU: Multiple Control Unit
MGCP: Media Gateway Control Protocol N:
SVTH: NGUYỂN THANH HIẾU GVHD: Ths. PHẠM THỊ XUÂN PHƯƠNG NGUYỄN THANH PHƯỚC - 163 -
NAT: Network address translator O:
OSI: Opening System Interconnection P:
PBX: Private Branch eXchange PCM: Pulse Code Modulation
PSTN: Public Switched Telephone Network Q:
QoS: Quality of Service R:
RAS: Remote Access Services
RSA: Rehabilitation Services Administration RSVP: Resource Reservation Protocol RTP: Real Time Protocol
RTCP: Real-time Transport Control Protocol S:
SCN : Switched Circuit Network SIP: Session initation protocol T:
TCP: Transport Control Protocol TDM: Time Division Multiplexing U:
UAC: User Agent Client UAS: User Agent Server UDP: User Data Protocol V:
VoIP: Voice over Internet Protocol W: