Đồ án Hệ thống phần mềm tổng đài PBX mã nguồn mở SER và SEMS của viện nghiên cứu FOKUS - Đức, nghiên cứu phát triển dịch vụ trả lời tự động (IVR) cho hệ thống SER-SEMS

Hệ thống nghe nhạc theo yêu cầu: có 2 chế độ nghe là nghe ngẫu nhiên và nghe bài hát theo mã. Sau khi nghe lời chào, người dùng có thể nhấn phím 1 để nghe bài hát theo mã, hoặc nhấn phím 2 để nghe bài hát ngẫu nhiên. Có thể lưu thông tin mã số bài hát trong cơ sở dữ liệu, hoặc đơn giản nhất là lưu trữ trong file cấu hình của chương trình.

doc101 trang | Chia sẻ: oanh_nt | Lượt xem: 1373 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Đồ án Hệ thống phần mềm tổng đài PBX mã nguồn mở SER và SEMS của viện nghiên cứu FOKUS - Đức, nghiên cứu phát triển dịch vụ trả lời tự động (IVR) cho hệ thống SER-SEMS, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
h 32. lớp AmSession Chức năng: Thực thi các quá trình xử lý của một phiên. Một phiên sẽ được định nghĩa bởi Call_ID, From_Tag và To-Tag. Khi có một bản tin INVITE đến hệ thống, hệ thống sẽ dựa trên 3 tham số trên để xác định ra một phiên tương ứng. AmThread Hình 33. Sơ đồ thừa kế của AmThread Chức năng: Dùng để xử lý các Thread trong hệ thống. Nhìn vào sơ đồ trên, ta thấy rất nhiều class kế thừa từ AmThread, trong đó có cả AmSession. AmRtpReciver Chức năng: Là bộ phận nhận gói RTP từ tất cả các luồng. RtpReciver nhận gói RTP từ tất cả các luồng đã được đăng ký cho nó. Nó đặt các gói nhận được vào bộ nhớ của luồng. AmSessionContainer Hình 34. lớp AmSessionContainer Chức năng: Kiểm soát toàn bộ các phiên trong hệ thống. Là nơi đăng ký và lưu giữ các active session và dead session. Chỉ cần một session còn hoạt động thì đối tượng AmSessionContainer vẫn sẽ được tiếp tục kích hoạt. AmSipRequest Chức năng: Biểu diễn một SIP request Trường dữ liệu chính: string method // Phương thức của bản tin string user // Tên user string domain // Domain của hệ thống string dstip // Địa chỉ ip đích string port // SIP port của ISCC string from_uri // Địa chỉ URI từ đâu đến string from // Địa chỉ nguồn string to // Địa chỉ đích string callid // Call ID string from_tag // From_tag string to_tag // To_tag string route // Tuyến đường được lưu lại AmRtpAudio Hình 35. lớp AmRtpAudio Chức năng: Kết hợp một đối tượng AmRtpStream và một đối tượng AmAudio lại vào trong một phiên. AmRtpStream Chức năng : Cung cấp luồng RTP, giao diện lớp cao của RTP AmConfig Chức năng: Là hàm lưu giữ các giá trị config khởi tạo của hệ thống. Các giá trị config hiện thời của hệ thống được lưu trong một cấu trúc kiểu Struct. Cấu trúc AmConfig: Struct AmConfig{ Static string ConfigurationFile: //Tên file config chính Static string ModConfigPath; //Đường dẫn đến các file config của từng ứng dụng. Static string SocketName; //Tên của file unix socket cho request. Static string ReplySocketName; //Tên của file unix socket cho reply. Static string SersocketName; //Tên của file SER unix socket name. Static string SendMethod; //Phương thức trao đổi giữa SER và SEMS. Static string SmtpServerAddress; //Sau khi server start thì lưu địa chỉ IP của SMTP server vào biến này. Static int SmtpServerPort; //Cổng của SMTP server. Static string PluginPath; //Đường dẫn đến các plugins. Static string LocalIP; //Địa chỉ IP local của hệ thống. Static string PrefixSep; //Là ký tự chia cắt cho prefix của ứng dụng. Static string RtpLowPort; //Cổng Rtp thấp nhất trong local. Static string RtpHighPort; //Cổng Rtp cao nhất trong local. Static int MediaProcessorThreads;//Số Thread trong một session. Static int init(); //Hàm khởi tạo. Sẽ gán luôn IP cho SMTP server. Static int readConfiguration(); // Đọc global config file. Static int setSmtpPort(const string& port); //Hàm định cổng SMTP. } AmPlugin Chức năng: Chứa các plugin đã được load. Các tham số cấu hình core của ISME Plugin_config_path= Tham số này chỉ đường dẫn tới các file cấu hình của các ứng dụng Mặc định: Plugin_config_path= / usr/ local/ etc/ isme/etc fork = {yes|no } Tham số này chỉ ra rằng, ISME sẽ chạy trong chế độ daemon, nhân bản chương trình để thực hiện quá trình đa xử lý. Stderr={ yes| no} Chế độ gỡ rối, nếu không chạy chế độ daemon thì sẽ Loglevel= {error=0, warning=1, info=2, debug=3} Thiết lập mức log. Socket_name= Tham số này cho ta biết đường và tên file của unix socket, là nơi ISCC viết những bản tin vào. Mặc định: socket_name= / tmp/ isme_sock Reply_socket_name= Tham số này cho ta biết đường và tên file của unix socket, là nơi ta nhận những bản tin reply từ ISCC. Mặc định: reply_socket_name= / tmp/ isme_rsp_sock Iscc_socket_name= Tham số này cho ta biết đường và tên file unix socket của ISCC, là nơi ta viết bản tin. Mặc định: iscc_socket_name=/ tmp/ iscc_sock Plugin_path= Ta dùng tham số này để thiếp lập đường tới một plugin. Load_plugin= Tham số này cho ta biết các module được tải. Giữa các module được ngăn cách bởi dấu chấm phẩy. Nếu tham số này không có gì, thì tất cả các module trong plugin_path đều được tải. Smtp_server= Tham số này để thiết lập địa chỉ cho smtp server. Smtp_port= Thiết lập cổng cho smtp server. Media_processor_threads= Ta sử dụng tham số này, để điều chỉnh số thread sẽ được tạo ra để xử lý luồng media. Đối với những hệ thống xử lý đơn, ta thiết lập tham số này với giá trị bằng 1. Còn với hệ thống đa xử lý, ta thiết lập tham số này với giá trị cao hơn, tuỳ thuộc vào việc hệ thống đó có bao nhiêu khối xử lý. Với hệ thống xử lý đơn: media_processor_threads= 1 Listen=| Tham số này thông báo cho ISME về giao diện, nơi ISME giao tiếp với ISCC. ISME cần thông tin này để thiết lập chính xác contact header trong các cuộc gọi đi và quá trình đăng ký. Và tham số này sẽ phải được cấu hình để có giá trị đúng bằng giá trị của cấu hình “listen” trong iscc_isme.cfg Sip_port= Tham số này thông báo cho ISME về cổng, nơi mà nó nhận các bản tin từ ISCC của nó. ISME cần thông tin này để cấu hình đúng cho contact header trong các cuộc gọi đi và quá trình đăng ký. Và như với tham số listen, tham số này cũng được cấu hình cùng giá trị với “port” trong iscc_isme.cfg. Tham số này sẽ không cần đến khi không có cuộc gọi đi và quá trình đăng ký nào trong ISME. Mặc định: sip_port= 5060 Cấu hình SER - SEMS Cấu hình SER-SEMS để giao tiếp với nhau: Để có thể làm việc được chính xác, SEMS cần SER được cấu hình chạy ổn định và phù hợp, được sử dụng như một SIP stack của SEMS. SER-SEMS giao tiếp với nhau thông qua unix socket server. Mỗi bên sẽ làm việc như một server, cho phép giao tiếp ở cả hai phía. Ta cần phải config SER để có thể sử dụng ứng dụng server của SEMS, và SEMS sử dụng server của SER. Nếu bạn định chạy hơn một SER ở tại một host, chắc chắn là phải biết được chính xác SER nào được kết nối trực tiếp với SEMS. Cách tốt nhất là có một SER hoạt động chỉ như SIP stack cho SEMS. SER này có thể lắng nghe các bản tin SIP trên cổng 5070. Cấu hình ISME để sử dụng unix socket server của ISCC - Thay đổi file cấu hình của SER ( vị trí mặc định là : /usr/local/etc/ser/ser.cfg ) và tìm tham số cấu hình cho ‘unix_sock=’. Trong file cấu hình, nên có dạng sau : unix_sock=”/tmp/ser_sock”. Nếu tham số ‘unix_sock’ không tồn tại, điền vào. Nếu có giá trị khác cho tham số đấy, ta không cần thiết phải thay đổi nó, chỉ cần nhớ nó là được. Mở file config của SEMS ( vị trí mặc định là : /usr/local/etc/sems/sems.cfg ) và tìm tham số ‘ser_socket_name=’. Nó phải có cùng giá trị với ‘unix_sock=’ trong file cấu hình của SER, nhưng không có dấu “”. Với ví dụ của chúng ta thì nó là “ser_socket_name=/tmp/ser_sock”. Cấu hình socket trên SEMS để nhận được responses từ SER : “reply_socket_name=/tmp/sems_resp_sock”. Sau đó cấu hình socket của SEMS, sử dụng tham số “socket_name=” trong sems.cfg. Giá trị mặc định là : “socket_name=/tmp/sems_sock” Chuyển hướng một cuộc gọi tới ISME. Vì người gọi cần kết nối với SEMS, SER phải truyền mọi SIP message được truyền tới SEMS thông qua một unix socket. Cơ bản, SEMS cần lấy bản tin INVITE để bắt đầu một cuộc gọi, và một bản tin BYE để kết thúc cuộc gọi. SEMS đồng thời cũng phải quan tâm đến bản tin CANCEL. ACK được xử lý bởi SER và SEMS không cần thiết phải xử lý nó. Nếu ta muốn SEMS chú ý đến các tín hiệu DTMF tone được gửi thông qua các bản tin SIP INFO thì cũng phải truyền nó đến SEMS. Chuyển hướng cuộc gọi là một thao tác rất đơn giản. Ta chỉ cần gọi hàm t_write_unix() từ tm module, là cái mà ta cần phải load. Giống như SER cần chú ý về các giao dịch của request, ta cần phải gọi đến t_newtran() trước khi tiến hành ghi request vào trong socket sử dụng t_write_unix. Load tm module của ISCC : - Chèn các dòng sau đây vào file ser.conf trong khu vực ‘module loading’: loadmodule “/usr/local/lib/ser/modules/tm.so” Cấu hình tm để có thể truyền các reply tạm thời đến SEMS: modparam(“tm”, “pass_provisional_replies”,1) Chuyển hướng các bản tin SIP tới ISME: Chèn các dòng sau vào ser.cfg chỗ mà ta cần chuyển hướng cuộc gọi: # chọn bản tin để chuyển hướng: if ( method=="ACK" || method=="INVITE" || method=="BYE" || method=="CANCEL" ){ # chuyển tới chế độ stateful: if (!t_newtran()){ sl_send_reply("500","could not create transaction"); break; }; #ngăn timeout trên vị trí khác: t_reply("100","Trying - just wait a minute !"); if (method=="INVITE"){ # chuyển hướng cuộc gọi tới plug_in 'conference' # nếu URI bắt đầu với 100 if (uri=~"sip:100.*@") { # Thông số cấu hình của SEM 'socket_name=' # được thiết lập là /tmp/am_sock if(!t_write_unix("/tmp/am_sock","conference")) { t_reply("500","error contacting sems"); }; break; }; # chuyển hướng cuộc gọi tới plug_in 'announcement' # nếu URI bắt đâu với 200 if (uri=~"sip:200.*@") { if(!t_write_unix("/tmp/am_sock","announcement")) { t_reply("500","error contacting sems"); }; break; }; # không có dịch vụ này, chuyển hướng tới voicemail. # không quên tải AVPs để voicemail có địa chỉ mail của # người được gọi. load_avp("ruri","email",0); if(!t_write_unix("/tmp/am_sock","voicemail")) { t_reply("500","error contacting sems"); }; break; } else if (method=="BYE" || method="CANCEL") { # Sems sẽ sẵn sàng biết plug_in nào đang xử lý cuộc gọi đó # "bye" không có tên plug-in. # nó nói với Sems để kết thúc cuộc gọi. if(!t_write_unix("/tmp/am_sock","bye")) { t_reply("500","error contacting sems"); }; } else if (method=="ACK") { # absorb ACKs t_relay(); } }; Đối với những viễn cảnh phức tạp hơn, ta cũng có thể chuyển hướng REFERs tới SEMS sẽ cho phép ta có thể thực hiện một số ứng dụng phức tạp hơn như click-to-dial, hoặc là mời người khác gia nhập vào một conference. Truyền thêm tham số cho ISME: địa chỉ email cho voicemail AVP ( attribute value pairs ) có thể được nối vào một request khi mà nó được viết vào sems với t_write_req/t_write_unix sử dụng tw-append. AVPs có thể được load từ một database trước đó, thay đổi với avpops. Đây là một phương thức linh hoạt, ví dụ như là ngôn ngữ của một user có thể được lưu trữ trong database và file greeting và voicemail, SEMS phải lấy địa chỉ email của người được gọi. Vì địa chỉ email được lưu trong một database và SER đã có kết nối với database, địa chỉ email được tra khi mà bản tin INVITE request được xử lý và được chèn thêm vào một trường header extra ‘P-Email-Address’ trong request. Sau đó SEMS lấy địa chỉ từ header này. Các phần có liên quan đến vấn đề này trong SER sẽ giống như sau : # tải module “db” loadmodule "/usr/local/lib/ser/modules/mysql.so" # tải module “ avp” loadmodule "modules/avp/avp.so" loadmodule "modules/avpops/avpops.so" # configure avpops db connection modparam( "avpops", "avp_url", "mysql://ser:heslo@localhost/ser" ) modparam( "avpops", "avp_table", "subscriber" ) modparam( "avpops", "uuid_column", "id" ) # configure aliases, the number doesn't matter as long as there are no collisions) modparam( "avpops", "avp_aliases", "email=i:67 ; language=i:68" ) # scheme to access the database modparam( "avpops", "db_scheme", "email_scheme:table=subscriber;value_col=email_address;value_type=string") modparam( "avpops", "db_scheme", "language_scheme:table=subscriber;value_col=language;value_type=string") # configure tm to append this when tw_appent voicemail_headers is used modparam("tm", "tw_append", "voicemail_headers:P-Email-Address=avp[$email];P-Language=avp[$language]") # ... # in route section: # no service number, redirect to voicemail. avp_db_load( "$ruri", "$email/$email_scheme"); avp_db_load( "$ruri", "$language/$language_scheme"); if(!t_write_unix("/tmp/sems_sock","voicemail/voicemail_headers")) { t_reply("500","error contacting sems"); }; break; Cấu hình ở trên với bảng trong database có một cột ‘id’, một cột ‘username’, một cột ‘email_address’ và một cột ‘language’ trong bảng tên là ‘subcriber’. ----- subscriber -------------------------------- id(int,auto) username(str,null) domain(str,null) email_address(str,null) language(str,null) 1:Alice:iptel.org:alice@mymail.org:english 2:rco:iptel.org:rco@iptel.org:french 3:Alex:iptel.org:alex@iptel.org:german ----- subsciber end ------------------------------ Truyền các bản tin SIP INFO tới ISME sử dụng DTMF Cơ chế giống như sử dụng tw_append được sử dụng để truyền các header content_type, content-length và thân của bản tin INFO tới SEMS: modparam( "tm", "tw_append", "info_append:hdr[Content-Length];hdr[Content-Type];msg[body]") ... if (method=="INFO") { if(!t_write_unix("/tmp/sems_sock","sems/info_append")){ log("could not contact sems\n"); t_reply("500","could not contact media server"); }; } IVR Module Trong chương này: Giới thiệu về module IVR Cấu hình module IVR Các cách gọi module IVR khác nhau Một số tùy biến khi biên dịch Tóm tắt API của IVR Phát triển một ứng dụng IVR thế nào Một số ứng dụng phát triển trên IVR Với IVR module, những ứng dụng có thể được viết dựa vào Python scripts. Những ứng dụng này được thực thi giống như các ứng dụng C++ bằng cách thực thi các bộ event handler của một lớp và được thực thi bởi trình biên dịch nhúng Python. Hiện tại SEMS không hỗ trợ phát triển ứng dụng VoiceXML mà tập trung vào phát triển các ứng dụng script viết bằng Python hoặc Perl. Trong SEMS có tích hợp sẵn trình biên dịch Python. Các script được viết bằng Python, sau đó được dịch ra mã bytecode, khi khởi động SEMS, nó sẽ được nạp và khi có một ứng dụng IVR được gọi tới thì đoạn mã bytecode tương ứng sẽ được thực thi. Ngôn ngữ lập trình Python Python là một ngôn ngữ lập trình thông dịch được Guido van Rossum tạo ra năm 1990. Python được phát triển trong một dự án mã mở, do tổ chức phi lợi nhuận Python Software Foundation quản lý. Bản mới nhất hiện nay là Python 2.5 được phát hành vào 19 tháng 9, 2006. Python là một ngôn ngữ ổn định, lập trình ở mức cao, tạo kiểu động, hướng đối tượng và đa nền. Tất cả những đặc tính này đã giúp cho Python trở nên hấp dẫn đối với các lập trình viên. Python chạy trên mọi nền phần cứng và hệ điều hành, do đó nó hạn chế sự lựa chọn môi trường phát triển. Theo đánh giá của Eric S. Raymond, Python là ngôn ngữ có hình thức rất sáng sủa, cấu trúc rõ ràng, thuận tiện cho người mới học lập trình. Cấu trúc của Python còn cho phép người sử dụng viết mã lệnh với số lần gõ phím tối thiểu, như nhận định của chính Guido van Rossum trong một bài phỏng vấn ông. Ban đầu Python được phát triển để chạy trên nền Unix. Nhưng rồi theo thời gian, nó đã “bành trướng” sang mọi hệ điều hành: từ DOS, Mac OS, OS/2, Windows đến Linux và các hệ điều hành khác thuộc họ Unix. Đặc điểm Python được thiết kế để trở thành một ngôn ngữ dễ học, mã nguồn dễ đọc, bố cục trực quan, dễ hiểu, thể hiện qua các điểm sau Từ khóa: tăng cường sử dụng từ khóa tiếng Anh, số lượng từ khóa ít, dễ nhớ. Python phân biệt chữ hoa chữ thường Khối lệnh: trong các ngôn ngữ khác khối lệnh thường được đánh dấu bằng các cặp ký hiệu đóng và mở. Ví dụ trong C/C++ và Java, cặp {} được dùng để đóng và mở một khối lệnh. Python có một cách đặc biệt để đánh dấu vào và thoát khỏi một khối lệnh: đó là thụt sâu các câu lệnh trong khối vào so với các câu lệnh của khối cha chứa nó. Có thể dùng Tab để thụt vào hoặc dùng phím dấu cách với số ký tự cách là bội số của 4 (4, 8,..). Ví dụ giả sử có đoạn mã lệnh C như sau: #include //... delta = b * b – 4 * a * c; if (delta > 0) {     // Khối lệnh mới bắt đầu từ kí tự { đến }     x1 = (- b + sqrt(delta)) / (2 * a);     x2 = (- b - sqrt(delta)) / (2 * a);     printf("Phương trình có hai nghiệm phân biệt:\n");     printf("x1 = %f; x2 = %f", x1, x2); } thì trong ngôn ngữ Python, nó sẽ có dạng: import math delta = b * b – 4 * a * c if delta > 0:     # Khối lệnh mới, thụt vào đầu dòng     x1 = (- b + math.sqrt(delta)) / (2 * a)     x2 = (- b – math.sqrt(delta)) / (2 * a)     print "Phương trình có hai nghiệm phân biệt:"     print "x1 = ", x1, "; ", "x2 = ", x2 Các bản khác nhau của Python: Python được viết từ những ngôn ngữ khác, tạo ra những bản hiện thực khác nhau. Bản hiện thực Python chính, còn gọi là CPython, được viết bằng C, và được phân phối kèm một thư viện chuẩn lớn được viết hỗn hợp bằng C và Python. CPython có thể chạy trên nhiều nền và khả chuyển trên nhiều nền khác. Ngoài CPython, còn có hai hiện thực Python khác: Jython cho môi trường Java và IronPython cho môi trường .NET. Khả năng mở rộng: Python có thể được mở rộng, nếu ta biết sử dụng C, ta có thể dễ dàng viết và tích hợp vào Python nhiều hàm tùy theo nhu cầu. Các hàm này sẽ trở thành hàm xây dựng sẵn (built-in) của Python. Ta cũng có thể mở rộng chức năng của trình thông dịch, hoặc liên kết các chương trình Python với các thư viện chỉ ở dạng nhị phân (như các thư viện đồ họa do nhà sản xuất thiết bị cung cấp). Hơn thế nữa, ta cũng có thể liên kết trình thông dịch của Python với các ứng dụng viết từ C và sử dụng nó như là một mở rộng hoặc một ngôn ngữ dòng lệnh phụ trợ cho ứng dụng đó. Ngay bản thân module IVR của SEMS cũng thực hiện theo cách thức này: SEMS chuyển đổi một số phương thức và đối tượng từ ngôn ngữ C++ sang Python. Trình thông dịch: Python là một ngôn ngữ lập trình dạng thông dịch. Ưu điểm của thông dịch là giúp ta tiết kiệm thời gian phát triển ứng dụng vì không cần phải thực hiện biên dịch và liên kết. Trình thông dịch có thể được sử dụng để chạy file script, hoặc cũng có thể được sử dụng một cách tương tác. Ở chế độ tương tác, trình thông dịch Python tương tự shell của các hệ điều hành họ Unix, tại đó, ta có thể nhập vào một biểu thức tại một thời điểm rồi enter, và kết quả thực thi sẽ được hiển thị ngay lập tức. Đặc điểm này rất hữu ích cho người mới học, giúp họ nghiên cứu tính năng của ngôn ngữ; hoặc để các lập trình viên chạy thử mã trong suốt quá trình phát triển phần mềm. Hệ thống kiểu dữ liệu: Python sử dụng hệ thống kiểu duck typing, còn gọi là latent typing (hàm nghĩa: ngầm). Có nghĩa là, Python không kiểm tra các ràng buộc về kiểu dữ liệu tại thời điểm dịch, mà là tại thời điểm thực thi. Khi thực thi, nếu một thao tác trên một đối tượng bị thất bại, thì có nghĩa là, đối tượng đó không sử dụng một kiểu thích hợp. Python cũng là một ngôn ngữ định kiểu mạnh. Nó cấm mọi thao tác không hợp lệ, ví dụ cộng một con số vào chuỗi. Sử dụng Python, ta không cần phải khai báo biến. Biến được xem là đã khai báo nếu nó được gán một giá trị lần đầu tiên. Căn cứ vào mỗi lần gán, Python sẽ tự động xác định kiểu dữ liệu của biến. Python có một số kiểu dữ liệu thông dụng sau: int, long: số nguyên float: số thực complex: số phức list: chuỗi có thể thay đổi tuple: chuỗi không thể thay đổi str: chuỗi kí tự không thể thay đổi dict: từ điển set: một tập không xếp theo thứ tự, ở đó, mỗi phần tử chỉ xuất hiện một lần. Ngoài ra, Python còn có nhiều kiểu dữ liệu khác. Cấu trúc hướng module: Python cho phép chia chương trình thành modules để có thể sử dụng lại trong các chương trình khác. Nó cũng có sẵn một tập hợp các modules chuẩn mà ta có thể sử dụng lại trong chương trình của ta. Các thư viện này cung cấp nhiều thứ, như file I/O, các lời gọi hệ thống, sockets,… Đa năng: Python là một ngôn ngữ lập trình đơn giản nhưng rất hiệu quả. So với Unix shell, Python hỗ trợ các chương trình lớn hơn và cung cấp nhiều cấu trúc hơn. So với C, Python cung cấp nhiều cơ chế kiểm tra lỗi hơn. Vì các lí do đó, Python là một ngôn ngữ lập trình cấp rất cao. Nó cũng có sẵn nhiều kiểu dữ liệu cấp cao, ví dụ như các mảng linh hoạt (flexible arrays) ( ) và từ điển (dictionaries) mà ta phải mất nhiều thời gian để hiện thực trên C. Python cũng được sử dụng để lập trình Web. Nó có thể được sử dụng như là một ngôn ngữ kịch bản. Python được thiết kế để có thể nhúng và phục vụ như là một ngôn ngữ kịch bản để tuỳ biến và mở rộng các ứng dụng lớn hơn. Được tích hợp sẵn nhiều công cụ và có một thư viện chuẩn phong phú. Nó hỗ trợ các định dạng email, dữ liệu Internet, HTML, XML và các ngôn ngữ đánh dấu khác. Python cũng ứng dụng tất cả các giao thức Internet thông dụng như HTTP, FTP,… Python cung cấp giao tiếp đến hầu hết cơ sở dữ liệu, có khả năng xử lí văn bản, tài liệu hiệu quả, và có thể làm việc tốt với các công nghệ Web khác. Python cũng có thể được sử dụng để phát triển các ứng dụng Desktop. Người dùng có thể dùng wxPython, PyQt, PyGtk để phát triển các ứng dụng giao diện đồ họa (GUI) chất lượng cao. Đa biến hóa: có nghĩa là, thay vì ép buộc mọi người phải sử dụng duy nhất một phương pháp lập trình, Python lại cho phép sử dụng nhiều phương pháp lập trình khác nhau: hướng đối tượng, có cấu trúc, chức năng, hoặc chỉ hướng đến một khía cạnh. Python kiểu kiểu động và sử dụng bộ thu gom rác để quản lí bộ nhớ. Một đặc điểm quan trọng nữa của Python là giải pháp tên động, kết nối tên biến và tên phương thức lại với nhau trong suốt quá trình thực thi của chương trình. Cú pháp trong Python Toán tử + - * / // (chia làm tròn) % (phần dư) ** (lũy thừa) ~ (not) & (and) | (or) ^ (xor) > (right shift) == (bằng) = != (khác) Các kiểu dữ liệu Kiểu số 1234585396326 (số nguyên dài vô hạn) -86.12 7.84E-04 2j 3 + 8j (số phức) Kiểu chuỗi (string) "Hello" "It's me" '"OK"-he replied' Kiểu tuple (1, 2.0, 3) (1,) ("Hello",1,()) Kiểu list [4.8, -6] ['a','b'] Kiểu dictionary {"Vietnam":"Hanoi", "Netherlands":"Amsterdam", "France":"Paris"} Chú thích # dòng chú thích Lệnh gán tên biến = biểu thức x = 23.8 y = -x ** 2 z1 = z2 = x + y loiChao = "Hello!" i += 1 # tăng biến i thêm 1 đơn vị In giá trị print biểu thức print (7 + 8) / 2.0 print (2 + 3j) * (4 - 6j) Nội suy chuỗi (string interpolation) print "Hello %s" %("world!") print "i = %d" %i print "a = %.2f and b = %.3f" %(a,b) Cấu trúc rẽ nhánh Dạng 1: if biểu_thức_đúng: # lệnh ... Dạng 2: if biểu_thức_đúng: # lệnh ... else: # lệnh ... Dạng 3: if biểu_thức_đúng: # lệnh ... elif: # lệnh ... else: # lệnh ... Cấu trúc lặp while biểu_thức_đúng: # lệnh ... for phần_tử in dãy: # lệnh ... L = ["Ha Noi", "Hai Phong", "TP Ho Chi Minh"] for thanhPho in L: print thanhPho for i in range(10): print i Hàm def tên_hàm (tham_biến_1, tham_biến_2, ...) # lệnh ... return giá_trị_hàm def binhPhuong(x): return x*x Hàm với tham số mặc định: def luyThua(x, n=2): """Lũy thừa với số mũ mặc định là 2""" return x**n print luyThua(3) # 9 print luyThua(2,3) # 8 Lớp class ''Tên_Lớp_1'': # ... class ''Tên_Lớp_2''(''Tên_Lớp_1''): """Lớp 2 kế thừa lớp 1""" x = 3 # biến thành viên của lớp # def ''phương_thức''(self,''tham_biến''): # ... # khởi tạo a = ''Tên_Lớp_2''() print a.x print a.''phương_thức''(m) # m là giá trị gán cho tham biến Xử lí ngoại lệ (exception) try: "câu_lệnh" except "Loại_Lỗi": "thông báo lỗi" Kết nối cơ sở dữ liệu MySQL với Python Để kết nối với hệ quản trị cơ sở dữ liệu MySQL, có thể sử dụng thư viện mã nguồn mở mysql-python (trang chủ : ). Ví dụ đoạn script sử dụng thư viện mysql-python: import MySQLdb #import thư viện mysql-python conn = MySQLdb.connect (host = "localhost", user = "root", passwd = "root", db = "diemThi") sql = “câu lệnh truy vấn sql” cursor = conn.execute(sql) result = cursor.fetchall() Ngoại lệ: MySQLdb.Error khi xảy ra khi lỗi kết nối cơ sở dữ liệu MySQLdb.OperationalError: xảy ra khi câu truy vấn sai Module IVR Module ivr được nằm trong thư mục /usr/local/lib/sems/plug-in, có tên là ivr.so Cấu hình ivr Cấu hình IVR được đặt trong file ivr.conf, nằm trong thư mục /usr/local/etc/sems/etc. File này chỉ chứa duy nhất một thông số là script_path: nó chứa đường dẫn đến nơi chứa các script python. Ví dụ một file cấu hình ivr.conf: script_path=/usr/local/lib/sems/ivr/ Chú ý: các script python được sems tự động nạp vào khi khởi động cũng có thể được dùng như mọi plug-in khác trong sems, tức là các script khác, hoặc các plug-in khác có thể dùng script python đó. Để đảm bảo tính bảo mật, chỉ có các script được nạp vào lúc khởi động mới có thể được thực thi. Các cách gọi script IVR Dựa vào tên của người dùng: Trong file ser.cfg, ta thêm dòng sau: t_write_unix("/tmp/sems_sock","ivr") Trong trường hợp này, script cần thực hiện sẽ được gọi thông qua tên người dùng được xác định trên URI yêu cầu Ví dụ như: R-URI 123@192.168.1.14 starts /123.py Dựa vào tên tham số truyền vào cho plug-in đó: Khi muốn chạy một script nào đó theo cách này, giả sử như muốn chạy script xemDiemThi.py nằm trong thư mục thì ta sẽ thêm dòng sau vào trong file ser.cfg t_write_unix("/tmp/sems_sock","xemDiemThi") Script này sẽ được gọi không phụ thuộc vào URI yêu cầu như thế nào Dựa vào thông số header “P-App-Name”: Trong file ser.cfg ta thêm dòng sau: t_write_unix("/tmp/sems_sock","sems") Trong bản tin SIP gửi đi khi muốn thực hiện script nào thì trong trường P-App-Name ta sẽ gán giá trị bằng tên của script đó. Ví dụ muốn chạy script xemDiemThi.py thì header của bản tin SIP sẽ phải chứa trường sau: P-App-Name: xemDiemThi Một số tùy chọn khi biên dịch Có một số tùy chọn khi biên dịch module IVR, nằm trong file Makefile.defs trong thư mục /app/ivr. Đó là tùy chọn về chương trình dịch PYTHON và ứng dụng TextToSpeed chương trình dịch Python: có hai tùy chọn PYTHON_VERSION: phiên bản nào của python được dùng để thực thi các script. Giá trị này có thể bằng 2.5 hoặc 2.4 hoặc 2.3. Hiện thời khuyến khích dùng chương trình dịch Python từ phiên bản 2.4 trở nên PYTHON_PREFIX: chỉ đến đường dẫn cài đặt chương trình dịch Python. Khi cài đặt thì Python sẽ được copy vào một số thư mục như lib, bin, include,... Tùy vào khi cài đặt mà Python có thể được cài đặt vào trong các thư mục đó của /, /usr hay là /usr/local. Thông thường khi cài đặt Python thì thì nó sẽ được cài đặt vào trong thư mục /usr ứng dụng TextToSpeed: ứng dụng này cho phép bạn có thể tạo các ứng dụng có khả năng chuyển nội dụng text sang thành âm thanh (đọc thư, đọc tin, ...). Mặc định trong IVR sử dụng chương trình chuyển đổi TextToSpeed là flite. TTS: để sử dụng ứng dụng này phải thiết lập tham số TTS sang thành 'y' FLITE_DIR: thư mục chứa mã nguồn của chương trình flite, khi biên dịch IVR thì nó sẽ tự động biên dịch chương trình flite. ALT_FLITE_DIR: nếu như bạn không muốn IVR dịch flite mà muốn tự mình dịch lấy thì có thể cho biết thư mục cài đặt chương trình flite Ví dụ về một file Makefile.defs: # Python version: 2.5, 2.4 or 2.3 PYTHON_VERSION = 2.4 PYTHON_PREFIX = /usr # For flite text-to-speech set TTS = y TTS = y #FLITE_DIR = /usr/src/flite-1.2-release ALT_FLITE_DIR = /usr/include/flite Làm thế nào để biết được rằng module ivr đã chạy Muốn biết module IVR có được chạy hay không thì hãy nhìn vào file log khi chạy sems (hoặc vào màn hình console nếu đặt chế độ debug cho hiện log ra màn hình). Bạn sẽ thấy được một vài mục tương tự thế này (5985) DEBUG: setScriptPath (Ivr.cpp:203): setting PYTHONPATH to: '/usr/local/li b/sems/plug-in:/usr/local/lib/sems/ivr/' (5985) DEBUG: Ivr-Python: Python-Ivr logging started (5985) DEBUG: onLoad (Ivr.cpp:427): ** IVR compile time configuration: (5985) DEBUG: onLoad (Ivr.cpp:428): ** built with PYTHON support. (5985) DEBUG: onLoad (Ivr.cpp:431): ** Text-To-Speech enabled (5985) DEBUG: onLoad (Ivr.cpp:436): ** IVR run time configuration: (5985) DEBUG: onLoad (Ivr.cpp:437): ** script path: '/usr/local/lib/ sems/ivr/' Để biết được một script nào đó có được nạp hay không thì hãy quan sát phần log ở đằng sau đoạn log này. Ví dụ: (5985) INFO: onLoad (Ivr.cpp:480): Application script registered: testPython. Như thế có nghĩa là script testPython đã được nạp. Các hàm API trong IVR Các ứng dụng IVR đều phải được định nghĩa dựa trên lớp cơ sở là IvrDialogBase. class tên_Ứng_Dụng(IvrDialogBase) Khi được gọi, hàm onSessionStart sẽ được thực thi. Lập trình script IVR theo kiểu lập trình hướng sự kiện, khi có một sự kiện nào đó sảy ra thì một hàm nào đó sẽ được gọi: Khi nhấn phím bấm: hàm onDtmf được gọi Hàm onTimer được gọi khi có thiết lập setTimer Hàm onEmptyQueue được gọi khi script chạy hết các file âm thanh. ... Tóm tắt một số hàm API của IVR: để hiểu rõ một số khái niệm về session, header, parameter,... của bản tin SIP, xin hãy xem lại phần giới thiệu về giao thức SIP. Các hàm Global def getHeader(String headers, String name): lấy thông tin từ header của bản tin SIP. headers: Header cần lấy thông tin name : tên của của trường header cần lấy thông tin. Ví dụ như muốn lấy giá trị của trường P-App-Name từ header hdrs: getHeader(hdrs, “P-App-Name”) def getSessionParam(String headers, String name): lấy tham số phiên với tên lấy từ headers. Thực chất là lấy các tham số từ trường P-Iptel-Param của header. def log(String str): sử dụng lại hàm log của sems, thực hiện việc xuất thông tin ra file log hoặc màn hình console. def createThread(Callable thread): tạo ra một thread mới, chỉ nên dùng trong mã khởi tạo module. Các hàm trong class IvrDialogBase Các hàm xử lý sự kiện (event handle) def onStart(self): được gọi khi bắt đầu một dialog SIP def onBye(self): được gọi khi một dialog SIP gửi bản tin BYE def onSessionStart(self, headers): hàm này được gọi khi bắt đầu thực thi một script python. Tham số headers được truyền cho script chứa header của bản tin SIP yêu cầu thực thi script này. def onEmptyQueue(self): được thực hiện khi không còn file audio nào được chạy. Các file audio này được cho vào queue thông qua hàm queue(IvrAudioFile). def onDtmf(self, key, duration): xử lý phím bấm, các phím từ 0 đến 9 tương ứng với giá trị key = 0 -> 9, phím '*' ứng với key = 10 và phím '#' ứng với key = 11. Duration là thời gian nhấn phím. def onTimer(self, id): được gọi sau một khoảng thời gian time nào đó kể từ khi hàm setTimer(self, id, time) được gọi. id: mã để phân biệt các timer khác nhau, mỗi một sự kiện thời gian sẽ được gán với nó 1 id. Tức là hàm setTimer sẽ được gọi nhiều lần với các id khác nhau tương ứng với các sự kiện khác nhau mà ta muốn xử lý, tương ứng với mỗi một id đấy ta sẽ xử lý trong hàm onTimer(id) cho phù hợp. def onSipReply(self, reply): được gọi khi có bản tin SIP được reply. Ví dụ như khi ta gọi hàm connectCallee() để kết nối tới một số khác, khi nhận được bản tin SIP trả lời thì hàm này sẽ được gọi. reply: nội dung bản tin SIP trả về. Các hàm điều khiển phiên (session control) def stopSession(self): kết thúc phiên và kết thúc script ivr. def bye(self): gửi bản tin BYE (hoặc bản tin CANCEL) đến User Agent(người gọi). Điều khiển Media def enqueue(self, IvrAudioFile, audio_rec): thực hiện thêm một file audio vào trong playlist của chương trình, chương trình sẽ lấy các file audio trong playlist ra để chạy theo thứ tự. Có hai giá trị của audio_rec: ivr.AUDIO_READ: mở file audio ra để đọc ivr.AUDIO_WRITE: mở file audio ra để ghi âm def flush(self): thực hiện xóa playlist, tất cả mọi file được hàm queue() thêm vào trong playlist sẽ bị loại, kể cả file đó đang được chương trình phát dở cũng sẽ bị loại (bị dừng giữa chừng) dialog: dùng để lấy thông tin về bản tin SIP request gửi từ phía người dùng, ví dụ hiển thị một số thông tin từ bản tin SIP request debug("**** domain: " + self.dialog.domain) debug("**** sip_ip: " + self.dialog.sip_ip) debug("**** sip_port: " + self.dialog.sip_port) debug("**** local_uri: " + self.dialog.local_uri) debug("**** remote_uri: " + self.dialog.remote_uri) debug("**** contact_uri: " + self.dialog.contact_uri) debug("**** callid: " + self.dialog.callid) debug("**** remote_tag: " + self.dialog.remote_tag) debug("**** local_tag: " + self.dialog.local_tag) debug("**** remote_party:" + self.dialog.remote_party) debug("**** local_party: " + self.dialog.local_party) debug("**** route: " + self.dialog.route) debug("**** next_hop: " + self.dialog.next_hop) debug("**** cseq: " + str(self.dialog.cseq)) B2BUA B2BMode: nếu như được gán giá trị 'True' thì luồng xử lý bản tin SIP sẽ được tự động chuyển qua bên phía User Agent kia. Nếu như được thiết lập True ngay từ đầu phiên thì bản tin INVITE của người gọi sẽ được chuyển trực tiếp sang cho phía người được gọi, không cần phải sử dụng hàm connectCallee() def connectCallee(self, remote_party, remote_uri): thực hiện kết nối người gọi đến một số khác (chuyển hướng cuộc gọi sang số máy khác). Nếu remote_party và remote_uri để trống(None) thì chúng ta sẽ kết nối ngay tới người được gọi khi người gọi bắt đầu gọi. def terminateOtherLeg(self): kết thúc cuộc gọi của người gọi tới người được gọi def connectAudio(self): bắt đầu một phiên audio với người gọi, gửi lại bản tin INVITE nếu như cần thiết. def disconnectAudio(self): kết thúc phiên audio. Gửi lại bản tin INVITE nếu như cần phải kết nối tới người được gọi hiện tại. Phát triển một ứng dụng IVR như thế nào? Cấu trúc thư mục Giả sử bạn muốn phát triển một ứng dụng IVR tên là testIvr chẳng hạn. Bạn tạo ra một thư mục với cấu trúc như sau: Hình 36.Cấu trúc thư mục phát triển một ứng dụng Python Thư mục chính, tên file cấu hình, tên file python chính phải đặt cùng tên với ứng dụng (testIvr). File testIvr.conf chứa các tham số cho chương trình, cấu trúc rất đơn giản, nó là tập hợp các cặp tên_trường=giá_trị, trong ứng dụng khi muốn lấy giá trị của một trường nào đó, chỉ cần gọi lệnh config[‘tên_trường’] ví dụ: welcome = /usr/local/lib/sems/audio/testIvr/welcome.wav error_connect = /usr/local/lib/sems/audio/testIvr/errorConnect.wav Thư mục testIvrLib chứa các thư viện dùng cho chương trình File Makefile chứa các hướng dẫn biên dịch, nội dung chính: NAME : tên ứng dụng VERSION : phiên bản PYTHON_VERSION : phiên bản Python chạy ứng dụng LIBDIR : thư mục thư viện Include : file này sẽ được gọi khi thực thi lệnh make NAME=testIvr VERSION=0.0.1 PYTHON_VERSION=2.4 LIBDIR=testIvrLib include ../ivr/Makefile.ivr_application Class testIvr phải thừa kế từ class IvrDialogBase, phải import các module căn bản là ivr và log. from log import * from ivr import * class testIvr(IvrDialogBase): def onSessionStart(self, hdrs): debug("bắt đầu chương trình ở hàm này") #các lệnh bắt đầu chương trình # ví dụ: hiển thị lời chào self.welcome = IvrAudioFile() self.welcome.open(config['welcome'], ivr.AUDIO_READ) self.enqueue(self.caukiendientu, None) def onDtmf(self,key,duration): debug("Khi có phím nhấn hàm này sẽ được gọi") print "Bạn vừa nhấn phím ", key print " trong khoảng ", duration Dịch và chạy Để dịch được chương trình này, bạn copy toàn bộ thư mục ivrTest vào trong thư mục apps của thư mục mã nguồn sems, ví dụ là /home/khoinm/sems-0.10.0-rc2/apps. Mở cửa sổ console ra, gõ các lệnh sau: cd /home/khoinm/sems-0.10.0-rc2/apps/ivrTest make all su root #thực hiện lệnh này trong trường hợp user hiện thời không có quyền ghi vào thư mục /usr/local make install Bạn có thể gộp 2 lệnh cuối thành: sudo make install nếu user hiện thời có quyền thực hiện lệnh sudo Trong file cấu hình cho SER-SEMS ta thêm phần cấu hình cho ứng dụng ivrTest, giả sử số gọi đến ứng dụng ivrTest là 19001570 if (uri =~ "sip: 19001570.*@"){ if (!t_write_unix("/tmp/sems_sock", "ivrTest")){ t_reply("500", "error contacting sems"); } break; } Một số ứng dụng trả lời tự động phát triển trên nền SEMS Cấu hình tổng quan cho các ứng dụng Cấu hình cho một hệ thống SER-SEMS không cần cao. Ở đây đưa ra một cấu hình chuẩn đã qua thực nghiệm: Phần cứng Chip: Intel Pentium IV, 2.66GHz Mainboard: Intel 915 GL-MX RAM: 512MB Ổ cứng: 40GB Phần mềm Hệ điều hành: Debian 4.0 SER phiên bản 0.9.6 SEMS phiên bản 0.10.0-rc2 Cài đặt Cấu hình SER-SEMS Ta sẽ cài đặt cả SER và SEMS trên cùng một máy, giả sử máy đó có IP là 192.168.1.14. Sẽ có 2 hệ thống SER được chạy. Một hệ thống xử lý các bản tin SIP nói chung (SER chính), đối với các bản tin SIP liên quan đến các dịch vụ gia tăng của hệ thống thì nó sẽ được forward sang hệ thống SER thứ hai (SER-SEMS). Hệ thống SER thứ hai đóng vai trò là một SIP Stack cho SEMS, giao tiếp với SEMS thông qua socket. Ta sẽ cấu hình SER chính lắng nghe ở cổng 5060, SER-SEMS lắng nghe ở cổng 5070, còn SEMS thì lắng nghe ở cổng 10000 Hình 37. Mô hình hệ thống Đối với người dùng trong nội mạng Đối với người dùng trong nội mạng, sử dụng softPhone hoặc IP-Phone thì có thể cấu hình dễ dàng để đăng ký một tài khoản SIP trong hệ thống. Ví dụ hướng dẫn đăng ký một tài khoản SIP cho một softPhone với user 2001 và password là 2001, softPhone sử dụng là phần mềm X-Lite của hãng Couterpath ( Hình 38. phần mềm x-lite Kích chuột phải chọn SIP Account Setting… Hình 39. Thêm SIP account mới Chọn nút Add…, điền các thông số theo hình vẽ: Display Name : điền tên tùy thích Username, Password, Authorization user name : điền 2001 Domain: điền IP của SIP Proxy Server: ở đây là 192.168.1.14 Hình 40. Điền các thông só đăng ký user SIP Chọn Apply - OK Đối với người dùng sử dụng dịch vụ qua mạng Internet Đối với người sử dụng dịch vụ qua mạng Internet thì phải đăng ký qua SIP Proxy Server qua mạng Internet, do vậy phải biết được được địa chỉ WAN của SIP Proxy Server. Nếu như đăng ký domain thì bạn có thể điền tên domain vào, hoặc nếu không bạn phải điền địa chỉ WAN của SIP Proxy Server. Hình 41. Đăng ký qua mạng Internet Đối với người dùng sử dụng dịch vụ qua mạng điện thoại công cộng PSTN Hệ thống phải có một PSTN Gateway để hỗ trợ cho người dùng qua mạng PSTN. Gateway này có thể là một card PCI cắm vào máy tính. Giải pháp kinh tế nhất là dùng card PCI của Digium, kèm theo cài đặt hệ thống tổng đài IP-PBX mã nguồn mở Asterisk. Khi đó người dùng từ mạng PSTN có thể gọi vào hệ thống thông qua một số điện thoại cố định được đăng ký trước (ví dụ 04.853.3965) và thông qua PSTN Gateway, cuộc gọi này sẽ được chuyển tới hệ thống SER-SEMS. Dịch vụ trả lời điểm tự động Hệ thống trả lời điểm tự động là một hệ thống lưu trữ điểm, cho phép người dùng gọi điện đến để tra điểm, xem điểm tổng kết,... Người dùng có thể sử dụng phần mềm gọi điện thoại (softPhone), IP Phone, hoặc nếu hệ thống có kết nối đến mạng điện thoại công cộng PSTN thì người dùng có thể dùng điện thoại thường để gọi đến được. Hình 42.Hệ thống báo điểm thi Hoạt động Khi người dùng gọi đến số dịch vụ, một bản tin INVITE được gửi đến SER chính (SER Main), SER xử lý bản tin SIP, thấy nó INVITE tới một số điện thoại trong dịch vụ, nó sẽ forward bản tin SIP này sang hệ thống SER-SEMS. Hệ thống SER-SEMS kiểm tra số dịch vụ, hệ thống sẽ kiểm tra trong kịch bản file cấu hình của hệ thống xem số được gọi đến là số nào, sau đó tương ứng với số đó, hệ thống sẽ gửi các gói tin socket để giao tiếp với SEMS, yêu cầu SEMS thực thi dịch vụ tương ứng. Các bản tin SIP vẫn được truyền qua hệ thống SER còn các gói tin media (âm thanh) thì được truyền trực tiếp giữa SEMS và máy điện thoại của người dùng bằng giao thức RTP. Đối với trường hợp gọi điện thoại qua mạng PSTN thì SEMS sẽ truyền thông qua PSTN Gateway, sau đó PSTN mới tiếp tục truyền tín hiệu thoại qua mạng PSTN đến máy điện thoại thường. Cấu trúc cơ sở dữ liệu Bảng Student: lưu trữ thông tin về sinh viên Tên cột Kiểu Chú thích StudentID Int Mã số sinh viên Name Varchar Tên sinh viên Sex Tinyint Giới tính (1: Nam, 0: Nữ) dateOfBirth Datetime Ngày sinh Homeland Varchar Quê quán State Int Trạng thái (0: đang học; 1: tốt nghiệp; 2: đình chỉ học; 3: đuổi học) Bảng 9.2.2.1. Bảng Student Bảng Subject: lưu trữ thông tin môn học Tên cột Kiểu Chú thích SubjectID Int Mã số môn học SubjectName Varchar Tên môn học SubjectIvrName Varchar Tên môn học lưu trong file .wav dùng để đọc trong hệ thống trả lời điểm numberOfCredit Int Số học trình Bảng 9.2.2.2. Bảng Subject Bảng ClassCourse: lưu trữ thông tin về lớp học Tên cột Kiểu Chú thích classCourseID Int Mã số lớp học Class Varchar Tên lớp học Course Int Khóa học (K47: 47; K48: 48) Bảng 9.2.2.3. Bảng ClassCourse Bảng ClassCourseStudent: lưu trữ thông tin sinh viên – lớp học Tên cột Kiểu Chú thích classCourseID Int Mã số lớp học StudentID Int Mã số sinh viên startDate Datetime Ngày bắt đầu vào lớp học finishDate Datetime Ngày kết thúc (chuyển lớp, tốt nghiệp, bị đình chỉ, đuổi học,...) Bảng 9.2.2.4. Bảng ClassCourseStudent Bảng ClassCourseSubject: lưu trữ thông tin các môn học trong lớp học Tên cột Kiểu Chú thích classCourseID Int Mã số lớp học SubjectID Int Mã số môn học Term Int Kỳ học (kỳ 1-> 10) Bảng 9.2.2.5. Bảng ClassCourseSubject Bảng Mark: lưu trữ điểm của sinh viên Tên cột Kiểu Chú thích markID Int Mã số điểm StudentID Int Mã số sinh viên Times Int Lần thi thứ mấy (1,2,...) markValue Float Điểm thi subjectID Int Mã môn học Bảng 9.2.2.6. Bảng Mark Menu ngữ cảnh Người dùng gọi điện đến số máy của hệ thống xem điểm. Nếu như dùng IP phone hoặc softPhone thì gọi trực tiếp đến số máy của dịch vụ (giả sử như sip:1603@iscom.org). Nếu như gọi điện từ máy điện thoại thường (cố định, di động,…) thì phải gọi thông qua một PSTN Gateway chuyển cuộc gọi này đến hệ thống. Hệ thống yêu cầu nhập vào mã số (Menu Chính) Mỗi người sẽ có một mã số xác định, mã số này dùng để xác định người dùng. Nếu nhập sai hệ thống sẽ thông báo lỗi và yêu cầu nhập lại. Hệ thống đưa ra các tùy chọn cho người dùng (Menu 1): Nhấn phím 1 để xem điểm thi Nhấn phím 2 để xem mã số các môn thi Nhấn phím 3 để kết nối tới phòng giáo vụ Nhấn phím * để trở về danh mục trước (Menu Chính) Hình 43. Menu chính hệ thống báo điểm thi Menu xem điểm thi: Nhấn phím 1 để xem điểm thi của từng môn học Nhấn phím 2 để xem điểm thi của tất cả các môn học Nhấn phím * để trở về danh mục trước (Menu 1) Hình 44. Menu xem điểm thi … Một số hình ảnh Hình 45. chạy hệ thống SER và phần mềm điện thoại X-Lite Hình 46. Chạy hệ thống SEMS Ngoài ra hệ thống còn có giao diện web để quản lý điểm. Hệ thống web là dành riêng cho quản trị. Hình 47. Trang web quản lý điểm thi Các chức năng chính của giao diện web: Quản lý lớp học Thêm mới lớp học Chỉnh sửa lớp học Quản lý sinh viên Thêm sinh viên Chỉnh sửa thông tin sinh viên Quản lý môn học Thêm môn học Chỉnh sửa môn học Quản lý điểm Thêm điểm Chỉnh sửa điểm Quản lý người dùng Thêm người dùng Chỉnh sửa người dùng Hệ thống quản lý qua web chỉ mang tính hỗ trợ và nhập dữ liệu cho hệ thống thông báo điểm thi qua điện thoại. Dịch vụ nghe nhạc theo yêu cầu Hệ thống nghe nhạc theo yêu cầu: có 2 chế độ nghe là nghe ngẫu nhiên và nghe bài hát theo mã. Sau khi nghe lời chào, người dùng có thể nhấn phím 1 để nghe bài hát theo mã, hoặc nhấn phím 2 để nghe bài hát ngẫu nhiên. Có thể lưu thông tin mã số bài hát trong cơ sở dữ liệu, hoặc đơn giản nhất là lưu trữ trong file cấu hình của chương trình. Hình 48. Nghe nhạc theo yêu cầu Kết luận và hướng phát triển Các vấn đề đã giải quyết được Việc xây dựng một hệ thống tổng đài VoIP thực tế cho doanh nghiệp vừa vả nhỏ là không khó. Lợi ích từ các dịch vụ hệ thống đem lại nhiều, giá thành thấp, nên xu hướng trong tương lai các doanh nghiệp sử dụng hệ thống VoIP là rất lớn. Đồ án này tập trung vào nghiên cứu công nghệ VoIP, nghiên cứu hệ thống phần mềm tổng đài SER – SEMS, sau đó phát triển một số ứng dụng trả lời tự động demo cho hệ thống. Tác giả đã nghiên cứu tổng quan về công nghệ VoIP, chỉ ra được những ưu điểm nổi trội của nó so với công nghệ truyền thoại cũ (chuyển mạch kênh) trong mạng PSTN. Tác giả cũng đã nghiên cứu sự phát triển của công nghệ VoIP trên thế giới và trong nước, thấy được tiềm năng ứng dụng công nghệ này vào trong các doanh nghiệp và các nhà cung cấp dịch vụ. Việc thiết lập một hệ thống VoIP thực tế là hoàn toàn có thể thực hiện được thông qua một số bước xác định. Tác giả đã nghiên cứu về giao thức SIP – một giao thức hiện thời đang là giao thức báo hiệu chuẩn trong công nghệ VoIP. Đây là một giao thức đơn giản, dễ học. Tính đơn giản thể hiện ở số loại bản tin ít, tính dễ học thể hiện ở định dạng của bản tin là văn bản thuần túy hoàn toàn. Ngoài ra khả năng mở rộng là rất cao với loại bản tin OPTIONS mở rộng, nhà phát triển có thể tự định nghĩa ra các loại bản tin mới một cách dễ dàng. Tác giả cũng đưa ra một số so sánh với giao thức H.323 – một giao thức báo hiệu trong công nghệ VoIP được dùng phổ biến trong thời kỳ đầu phát triển công nghệ VoIP. Điểm hạn chế nhất của H.323 là khả năng mở rộng kém, giao thức này cũng rất rắc rối phức tạp. Tác giả đã nghiên cứu về SER – một server xử lý các bản tin SIP. Không giống các phần mềm tổng đài khác, SER được thiết kế để chuyên làm nhiệm vụ định tuyến, thiết lập cuộc gọi, ngoài nhiệm vụ xử lý bản tin SIP ra nó không thực hiện thêm chức năng nào khác. Tại thời điểm hiện tại, SER có tốc độ xử lý bản tin SIP nhanh nhất so với các phần mềm tổng đài khác. Với một số cấu hình đơn giản, hệ thống SER có thể xử lý được hàng ngàn cuộc gọi cùng lúc. SER được thiết kế hướng module nên việc phát triển và thêm các chức năng mới cho SER là rất linh hoạt. Tác giả cũng đã nghiên cứu về SEMS. Do SER chỉ xử lý các bản tin SIP nên nó không cung cấp các giá trị gia tăng cho hệ thống. SEMS đóng vai trò là một media server chuyên cung cấp các dịch vụ cho hệ thống SER. Cũng như SER, SEMS thiết kế hướng module nên phát triển các dịch vụ gia tăng mới cho SEMS cũng không quá khó. Cuối cùng, tác giả đi vào nghiên cứu một mảng dịch vụ nhỏ trong SEMS, đó là hệ thống trả lời tự động (IVR). Tác giả đã xây dựng một số chương trình thử nghiệm như: dịch vụ thông báo điểm thi, dịch vụ nghe nhạc theo yêu cầu,…Ngôn ngữ xử dụng là Python, một ngôn ngữ kịch bản hướng đối tượng khá linh hoạt. Kết quả từ các ứng dụng thử nghiệm trên cho thấy hệ thống SER-SEMS có khả năng đưa vào ứng dụng trong thực tế rất cao. Hạn chế Công nghệ VoIP có rất nhiều vấn đề cần phải nghiên cứu, do hạn chế về mặt thời gian nên tác giả chỉ nghiên cứu ở mức tổng quan về công nghệ VoIP. Còn rất nhiều mảng công nghệ mà đề tài không nói đến như: mã hóa âm thanh, bảo mật trong VoIP, chất lượng dịch vụ thoại (QoS), … Nghiên cứu hệ thống SER và SEMS cũng chỉ dừng lại ở mức nghiên cứu cấu trúc, tổng quan hệ thống, nghiên cứu các chức năng và cấu hình cho hệ thống Hệ thống tổng đài IS-COM mà tác giả tham gia nghiên cứu mới ở giai đoạn đầu nên hệ thống chưa đưa vào sử dụng, mới chỉ áp dụng thử trong phòng thí nghiệm của khoa Điện tử viễn thông. Mặt khác, hệ thống SER-SEMS cũng đang trong quá trình phát triển, ở các phiên bản gần đây (SER 0.9.6 và SEMS 0.10.0-rc2) các chức năng của hệ thống đã được tinh lọc đi rất nhiều để nâng cao hiệu năng. Ngoài ra thư viện các hàm của hệ thống cũng thường xuyên thay đổi. Do vậy việc phát triển các ứng dụng cũng trở nên khó khăn hơn. Hệ thống tài liệu và sự trợ giúp từ cộng đồng người sử dụng cũng không được tốt nhất. Dự án phần mềm SER-SEMS chỉ có hỗ trợ mailling-list. Hướng phát triển Trong thời gian tới tác giả sẽ tiếp tục nghiên cứu về SER-SEMS, tham gia vào nghiên cứu phát triển hệ thống IS-COM nhằm hoàn thiện những thiếu sót trong đồ án. Tác giả sẽ nghiên cứu các mảng khác của VoIP. Ngoài ra nhằm tăng tính linh hoạt của hệ thống IS-COM, một hướng phát triển được rất nhiều người áp dụng đó là kết hợp giữa SER và Asterisk. Khi đó SER sẽ xử lý phần báo hiệu, thực hiện các chức năng khác như chịu tải (load balancing), còn Asterisk sẽ đóng vai trò một media server cung cấp các dịch vụ gia tăng cho hệ thống. Ngoài ra còn có thể dùng Asterisk như là một gateway kết nối ra mạng PSTN thông qua card Digium. Tài liệu tham khảo Tham khảo từ sách điện tử Alan B. Johnston,SIP - Understanding the Session Initiation Protocol,Second Edition,  Artech House - 2004 Timothy Kelly, VoIP for Dummies, Wiley Publishing, 2005 T.Wallingford, Switching to VoIP, O'Reilly, June 2005 Cisco Voice over IP, version 4.1, Cisco System, 2003 Các tài liệu (file .pdf) từ trang Serdev.pdf Sems new generation-design overview SEMSng-App tutorial SIP Tutorial Tham khảo từ các trang web mailling lisst của iptel.

Các file đính kèm theo tài liệu này:

  • docDAN200.doc
Tài liệu liên quan