Lập trình trong Asterisk• Asterisk cho phép lập trình trong Diaplan để người dùng có thể thực hiện các yêu cầu của mình một cách nhanh chóng.. Asterisk sử dụng biến trong các đối số của
Trang 1BÀI 8 LẬP TRÌNH ỨNG DỤNG TỔNG
ĐÀI IP ASTERISK
CÔNG NGHỆ THOẠI IP
Trang 2Cấu hình tổng đài với CLI
• CLI - Command Line Interface
• Lệnh “ # asterisk –r” để kết nối vào Asterisk Console.
Trang 3Các lệnh cấu hình CLI
• Lệnh “# CLI> ?” và Lệnh “# CLI> help” giúp đỡ
xem thông tin các lệnh CLI
Ví dụ một số lệnh CLI
• Lệnh “# CLI> sip” xem và cấu hình có liên quan
đến giao thức SIP như extension và channel
• Lệnh “# CLI> sip show users” xem các users SIP trong Asterisk
• Lệnh “# CLI> dialplan” cấu hình Dialplan
• Lệnh “# CLI> dialplan add extension ” tạo các
Trang 4Lập trình trong Asterisk
• Asterisk cho phép lập trình trong Diaplan để người dùng có thể thực hiện các yêu cầu của mình một cách nhanh chóng.
• Biểu thức trong lập trình là sự kết hợp của các biến, các
toán tử và các hằng để tạo ra một kết quả.
• Biểu thức có thể dùng để kiểm tra biến, thực hiện các tính toán toán học, thay đổi string….
• Trong lập trình Asterisk, biểu thức luôn bắt đầu bằng ‘$’, biểu thức sau đó được đặt giữa 2 dấu ngoặc vuông.
$[expression]
$[${COUNT} / 2]
4
Trang 5Ví dụ lập trình trong Asterisk
Trang 6Asterisk sử dụng biến trong các đối số của application,
cú pháp được sử dụng như sau: ${TenBien}
TenBien chứa chuỗi ký tự alphanumeric do người
dùng đặt không phân biệt chữ hoa chữ thường
Ví dụ : ${TenBien} và ${TENBIEN} là như nhau,
nhưng với các biến có sẵn trong Asterisk phải gọi đúng tên biến vì có phân biệt chữ hoa chữ thường
Ví dụ : ${EXTEN} là biến sẵn có trong Asterisk nên
không thể gọi ${exten}.
Biến trong Asterisk
Trang 7Có 3 kiểu biến trong hệ thống Asterisk:
• Biến toàn cục (global variables) : được định nghĩa tại ngữ cảnh
[globals] hoặc được khai báo bằng lệnh SetGlobalVar Một khi được
định nghĩa, biến có thể được sử dụng bởi bất kỳ kênh nào tại bất kỳ thời điểm nào
• Biến kênh (channel variables) : được khai báo bằng lệnh Set, biến
kênh chỉ có hiệu lực bên trong kênh khai báo chúng Một khi kết thúc cuộc gọi biến kênh cũng sẽ không còn tồn tại nữa
• Biến môi trường (environment variables) : là biến mà Asterisk có thể truy cập biến môi trường của hệ điều hành linux Để truy cập biến
môi trường chúng ta dùng cú pháp : ${ENV(foo)}
Trong quá trình khai báo biến cần chú ý là: nếu khai báo biến toàn
cục và biến kênh cùng tên nhau thì giá trị của biến là biến kênh nhưng tại kênh khác nếu gọi tên biến toàn cục thì giá trị biến toàn cục có
Biến trong Asterisk
Trang 8Lệnh hoàn chỉnh trong Dialplan có dạng sau:
• Name (tên ký tự hoặc con số) của số nội bộ
• Priority (số thứ tự) : mỗi số nội bộ có thể bao gồm nhiều thứ tự thực hiện, mỗi thứ tự gọi là “priority”
• Application (or command) : thực hiện một ứng dụng cụ thể nào đó cho cuộc gọi exten => tương ứng với mỗi ứng dụng thực hiện exten=> giống
nhau cho mỗi dòng thực hiện trong Dialplan.
Lệnh trong Asterisk
Trang 9• Đây là phần quan trọng trong Diaplan tức là ứng dụng nào sẽ
được thực hiện trên mỗi dòng,
• Các ứng dụng như thực hiện quay số, trả lời cuộc gọi hay đơn
giản là nhấc máy, gác máy để biết thêm thông tin về các ứng dụng cũng như các thông số kèm theo dùng lệnh show
Aplications trên giao tiếp dòng lệnh của Asterisk.
• Background() : Ứng dụng này thực hiện phát một file âm thanh
và chờ nhận con số từ phím nhấn của máy điện thoại, sau khi nhận con số từ phím nhấn máy điện thoại, Asterisk sẽ ngắt phát thông điệp và xử lý chuyển đến số thứ tự priority tương ứng với con số nhận được
Hàm trong Asterisk
Trang 10- Hàm dùng để thực hiện các công việc giống nhau Sử dụng hàm giúp tiết kiệm thời gian và công sức Hàm trong Asterisk cho phép tính toán
độ dài string, ngày và giờ, check MD5,…
- Cú pháp của hàm như sau:
Trang 11Goto() : Là ứng dụng thực hiện nhảy từ context, extention,
priority hiện hành đến context, extention, priority được chỉ định trong ứng dụng goto().
Hàm trong Asterisk
Trang 12GotoIf () : giống như Goto() nhưng có xem xét điều kiện
Hàm trong Asterisk
Trang 13Read() : tiếp nhận dữ liệu nhập vào từ thuê bao.
Ví dụ hàm trong Asterisk
Trang 14- Biểu thức là sự kết hợp của các biến, phép toán và giá trị để có được một kết quả.
- Trong Asterisk, biểu thức luôn bắt đầu bằng dấu $ và được đặt trong cặp ngoặc [].
Ví dụ: COUNT = 5
$[${COUNT} + 1]
$[${COUNT} / 2]
- Khi Asterisk gặp một biểu thức trong một dialplan, nó sẽ thay thế các biến bằng giá trị, rồi thay thế các biểu thức bằng giá trị của các biểu thức đó.
Ví dụ: exten => 321,1,Set(COUNT=3)
exten => 321,2,Set(NEWCOUNT=$[${COUNT} + 1])
exten => 321,3,SayNumber(${NEWCOUNT})
Biểu thức
Trang 15Toán tử
Asterisk được viết trên C nên các toán tử trong nó cũng khá quen
thuộc, gồm có :
a Toán tử logic:
biểu thức1 | biểu thức2: toán tử or
biểu thức1 & biểu thức2: toán tử and
biểu thức1 {=, >, >=, <, <=, !=} biểu thức2: toán tử quan hệ, so sánh.
b Toán tử toán học:
‘+’, ‘-’, ‘*’, ‘/’, ‘%’
- Lưu ý là trong Asterisk chỉ tính toán trên các giá trị nguyên.
- Chúng ta cũng có thể dùng biểu thức chính quy (regular
expression) trong Asterisk.
Trang 17Hàm điều kiện
• Nhằm mục đích chính là đưa ra quyết định cho mỗi giá trị của biểu thức và hàm trong Asterisk
GotoIf GotoIfTime
1.GotoIf
• Ứng dụng GotoIf() tính toán giá trị của biểu thức,
hàm và đưa caller tới một đích có địa chỉ nào đó
(chuyển sang extension?, priority? ) dựa trên giá trị nhận được là true hay false
Trang 18• Cú pháp của GotoIf() như sau:
GotoIf(expression?destination1:destination2)
• Cấu trúc lựa chọn này, có lẽ lấy ra từ C nên cũng
không quá khó hiểu Giá trị được cho là false khi nó
là một chuỗi trống hay là giá trị 0, ngược lại là giá trị được cho là true Đích đến của nó có thể là một trong các điểm sau:
+ Priority trong cùng một extension
+ Extension và priority trong cùng một context.
+ Context, extension, priority
18
Trang 19• Ví dụ : minh họa cho hàm ứng dụng rẽ nhánh, kết hợp với hàm ứng dụng Goto() để đếm xuống 10 giá trị sau đó gác máy
Trang 2020
Nếu như GotoIf() là ứng dụng quyết định dựa trên giá trị của biểu thức nhận được thì GotoIfTime() lại đưa ra quyết định dựa trên ngày,giờ của hệ thống (để chia ra giờ làm việc, thời gian rảnh, ngày nghỉ … ) Cú pháp như sau:
Trang 23Định nghĩa một Macro
Định nghĩ một macro cũng gần giống như định nghĩa một context khác ở chỗ là thêm từ “macro-“ trước tên của macro đó (để phân biệt với extension)
[macro-name]
exten => s,1,Dial(${JOHN},10,r)exten =>s,2,VoiceMail(u101@default)
exten => s,102,VoiceMail(b101@default)
Trang 24Sử dụng Macro trong Dialplan
Dùng ứng dụng Macro(), ứng dụng này sẽ gọi một macro cụ thể nào nó Ví dụ như để gọi một voicemail macro, có thể làm như sau:
exten => 101,1,Macro(voicemail)
•Ứng dụng Macro cũng định nghĩa một số các biến
để sử dụng như sau:
${MACRO_CONTEXT}: Ngữ cảnh context mà macro được gọi
${MACRO_EXTEN}: Extention mà macro được gọi
${MACRO_PRIORITY}: Thứ tự (Priority) mà macro được gọi
${ARG n}: là thứ tự của đối số truyền vào
24
Trang 25Bằng cách sử dụng Argument để thay thế các thông số, ta
có thể sử dụng nó tại bất cứ đâu mà chỉ cần thay đổi argument tương ứng.
exten => 101,1,Macro(voicemail,${JOHN})
exten => 102,1,Macro(voicemail,${JANE})
exten => 103,1,Macro(voicemail,${JACK})
Trang 26Ví dụ Macro
Trang 28Chương trình con GoSub()
Cách khai báo chương trình con giống như khai báo ngữ cảnh(context), khai báo chương trình con hộp thư thoại như sau:
Trang 30 Chương trình con [subQuayso] trả về giá trị là trạng thái của hàm quay số Dial, giá trị trả về được lưu trong biến ${GOSUB_RETVAL} , do đó chúng ta có kết quả gọi chương trình con như sau:
30
Trang 31Asterisk với cơ sở dữ liệu
• Asterisk có khả năng tương tác với cơ sở dữ liệu khá linh hoạt
• AstDB (Asterisk database uses version 1 of the
Berkeley DB) là hệ cơ sở dữ liệu bên trong của
Asterisk hoạt động giống như Windows registry
Trang 32Lấy dữ liệu từ AstDB
- Để lấy giá trị từ cơ sở dữ liệu Asterisk và gán vào biến ta cũng dùng hàm set ()
exten => 456,1,Set(DB(test/count)=1)
exten => 456,2,Set(COUNT=${DB(test/count)})
exten => 456,3,SayNumber(${COUNT})
Các dòng lệnh trên lấy giá trị biến count trong family
“test”, gán vào một biến mới là COUNT, và đọc biến
COUNT bằng hàm gọi.
- Có thể kiểm tra giá trị của một khoá bằng lệnh
database get family key
- Để hiển thị toàn bộ nội dung AstDB, dùng lệnh
database show
Trang 33Sử dụng AstDB trong Dialplan
Có nhiều cách để sử dụng cơ sở dữ liệu Asterisk trong
Dialplan
Ví dụ: Đếm mẫu
- Lấy giá trị của một số (giá trị khoá count) từ cơ sở dữ liệu
và gán vào biến COUNT Nếu khoá này không tồn tại, hàm DBget() sẽ cho chúng ta quyền ưu tiên n+101, để có thể đặt giá trị thành 1 Quyền ưu tiên tiếp theo đưa chúng
ta về quyền ưu tiên 1.
exten => 678,1,Set(COUNT=${DB(test/count)})
exten => 678,102,Set(DB(test/count)=1)
exten => 678,103,Goto(1)
Trang 34Xoá dữ liệu từ AstDB
- Xoá một từ khoá, dùng lệnh Dbdel()
Hàm DBdel() xem cả họ và biến như một tham số
exten => 457,1,DBdel(test/count)
- Cũng có thể xoá toàn bộ nhóm biến bằng lệnh
DBdeltree() Hàm này lấy tham số là tên của nhóm biến
để xoá.
exten => 457,1,DBdeltree(test)
Trang 35Ví dụ sử dụng AstDB trong Dialplan
Gọi giá trị hiện tại của COUNT, và tăng COUNT lên
Trang 36Asterisk Gateway Interface
• Asterisk còn có thư viện Asterisk Gateway Interface (AGI, tương tự như CGI) - cơ chế kích hoạt ứng
dụng bên ngoài, cho phép viết kịch bản phức tạp với một số ngôn ngữ lập trình như:
• Java (thư viện Asterisk-java), Pascal (thư viện TPasAGI), Perl (thư viện Agispeedy, Asterisk Perl AGI), PHP (thư viện phpAGI), Python (thư viện Fats, PyAstre), C (thư
viện CAGI), v.v…
• AGI là phần giao tiếp với ngôn ngữ lập trình script
để thực hiện một số công việc của Asterisk từ bên
ngoài
Trang 37Asterisk Gateway Interface
• Asterisk Gateway Interface
(AGI) thực hiện giao tiếp
với các ứng dụng của
Asterisk nhằm giải quyết
các vấn đề trong Dialplan.
• Với AGI, người lập trình có
thể viết và phân phối độc
lập mà không cần tới source
code của Asterisk
Trang 38Asterisk Gateway Interface
• Thông thường, AGI
script được dùng để giao
tiếp với các cơ sở dữ liệu
•AGI script được viết trên
nhiều ngôn ngữ khác nhau
như: Perl, PHP, C, Python,
Java…
Trang 39Các nguyên tắc trong giao tiếp AGI
AGI script giao tiếp
với Asterisk thông qua
các kênh giao tiếp như
-STDIN
- STDOUT
-STDERR.
Trang 40Giao tiếp AGI
• Asterisk và AGI script giao tiếp với nhau theo một mô
hình được xác định trước.
• Khi một AGI script được thực thi, Asterisk sẽ gửi danh
sách các biến và giá trị của chúng tới AGI script Các biến
Trang 41Hoạt động của AGI
exten =>_X.,1,AGI(some_script_name.agi,param1,param2,param3)
Trang 42STDIN, STDOUT, STDERR
1 STDIN, STDOUT, STDERR là những kênh mà những
chương trình bên trong Unix dùng để nhận và gửi thông tin ra bên ngoài.
Trang 43Lập trình với AGI
• Một khi trong những lợi thế của việc sử dụng giao diện AGI là khả năng phát triển các ứng dụng độc quyền và nền tảng trong khi sử dụng một dually cấp giấy phép mở nguồn, PBX lõi
• AGI Script cho phép lập trình phát triển ứng dụng trong hệ thống Asterisk, làm gia tăng độ linh động của Asterisk trước các yêu cầu ngày càng cao của người dùng
• Trong khi bất kỳ thay đổi nào trên một mô-đun nội
bộ Asterisk hoặc ứng dụng phải được khởi động trở
Trang 44AGI và Asterisk
• Thư mục /var/lib/asterisk/agi-bin/ chứa các script của người dùng mà Asterisk có thể định vị sử dụng qua các ứng dụng AGI
• Thông tin giữa AGI và Asterisk thông qua giao tiếp STDOUT/STDIN
• STDOUT: AGI script gửi thông tin đến Asterisk
• STDIN: Asterisk gửi thông tin về AGI script
• STDERR: Thông tin lỗi
• Asterisk đã cung cấp cho lập trình viên rất
nhiều hàm liên quan đến AGI
Trang 45Giao tiếp AGI
Sau khi gửi các biến này, Asterisk sẽ gửi 1 dòng
trống báo hiệu hoàn tất việc gửi các biến, AGI
script bắt đầu xử lý các Dialplan
• Tại thời điểm này, AGI script gửi các dòng lệnh tới Asterisk thông qua kênh giao tiếp STDOUT
• Sau mỗi lệnh gửi đi, Asterisk sẽ phản hồi lại với AGI script cho biết lệnh nào đã được thực thi
Việc này sẽ được tiếp tục thực hiện trong thời gian tiếp theo
Trang 46AGI: luồng thông tin trao đổi
Trang 47exten => 9999,1,Answer()
exten => 9999,n,Set(CID=${CALLERID(num)})
exten => 9999,n,AGI(luachon.php)
Trang 48Ví dụ người dùng quay số với AGI App.
Trang 49Gọi một AGI script từ Dialplan
• Để sử dụng 1 AGI script trong Dialplan , ta
gọi lệnh AGI với đối số được truyền vào là tên của AGI script, ta có ví dụ như sau:
exten => 123,1,Answer( )
exten => 123,2,AGI(agi-test.agi)
• AGI script thường có đường dẫn mặc định
/var/lib/asterisk/agi-bin nhưng chúng ta cũng có thể tạo ra các đường dẫn riêng tới các AGI script của mình
Trang 50AGI – Internal functions
answer: Asserts answer
channel status: Returns status of the connected channel
control stream file: Send the given file, allowing playback to be controled by the
given digits, if any (Asterisk 1.2)
database del: Removes database key/value
database deltree: Removes database keytree/value
database get: Gets database value
database put: Adds/updates database value
exec: Executes a given Application (Applications are the functions you use to create
a dial plan in extensions.conf )
get data: Gets data on a channel
get option: Behaves similar to STREAM FILE but used with a timeout option
(Asterisk 1.2)
get variable: Gets a channel variable
hangup: Hangup the current channel
noop: Does nothing
receive char: Receives one character from channels supporting it
receive text: Receives text from channels supporting it
record file: Records to a given file
say alpha: Says a given character string (Asterisk 1.2)
say date: Say a date (Asterisk 1.2)
Trang 51AGI – Internal functions
(Asterisk 1.2)
"SET MUSIC ON default"
enable communication with TDDs
Trang 52AGI và Asterisk
• Thư mục /var/lib/asterisk/agi-bin/ chứa các script của người dùng mà Asterisk có thể định vị sử dụng qua các ứng dụng AGI
• Thông tin giữa AGI và Asterisk thông qua giao tiếp STDOUT/STDIN
• STDOUT: AGI script gửi thông tin đến Asterisk
• STDIN: Asterisk gửi thông tin về AGI script
• STDERR: Thông tin lỗi
• Asterisk đã cung cấp cho lập trình viên rất
nhiều hàm liên quan đến AGI
Trang 53exten => 9999,1,Answer()
exten => 9999,n,Set(CID=${CALLERID(num)})
exten => 9999,n,AGI(luachon.php)
Trang 54Một số dịch vụ trong Asterisk
• IVR Server cho phép thực hiện các cuộc gọi rẽ nhánh tuỳ theo
tương tác của người gọi, như hệ thống dịch vụ 1080
• Conference Server tạo các phòng hội nghị cho phép nhiều
người dùng cùng tham gia vào 1 cuộc gọi hội nghị;
• Voice Mail: tạo hộp thư thoại, cho phép khách hàng lựa chọn
hộp thư thoại tuỳ theo tương tác của người gọi;
• Ứng dụng phân phối cuộc gọi tự động ACD: phân phối cuộc
gọi tự động ACD (Automatic Call Distribution), dành cho các nhu cầu chăm sóc, hỗ trợ khách hàng hay tiếp nhận phản hồi
từ khách hàng
Trang 55Dịch vụ trả lời tự động IVR
Trang 57Conferencing với MeetMe( )
Ứng dụng này cho phép nhiều người có thể trao đổi nói chuyện với nhau như là khi họ đang ở trong cùng một địa điểm.
Một vài tiện ích chính của nó:
Khả năng tạo password bảo vệ cuộc hội thoại
Quản lý cuộc hội thoại
Lựa chọn muting option all ngoại trừ một người
Tạo phòng hội thoại static hoặc dynamic