1. 程式人生 > >深入理解Asterisk體系架構

深入理解Asterisk體系架構

Asterisk和其他傳統的PBX完全不同,因為Asterisk的撥號計劃以同樣的方式處理所有的入局通道(incoming channels)。

傳統的PBX在邏輯上區分工作站通道(連線電話機)和電話局通道(連線到外部世界)。這意味著,你不可能無縫地在一個工作站埠配置一個外部閘道器。同樣,傳統PBX也很難實現對離站(off-site,不在座位上或外出辦事)資源的訪問,比如前臺如果外出辦事就什麼事都做不了,因為她哪怕能打電話回公司,也是不能訪問內部資源的。

Asterisk在內部不區分工作站通道和電話局通道,而是一律統稱通道。有很多種通道型別(驅動不同),但Asterisk撥號計劃以不加區別(介面一致)的方式處理這些通道,也就是說,一個內部使用者可能位於電話局埠,但撥號計劃可以把他當成在工作站埠一樣。如果你沒有用過傳統PBX,可能還體會不到Asterisk這種方式的強大和靈活。下圖顯示了兩種架構的區別。

模組

Asterisk是基於模組構建的。一個模組提供特定的功能,是一個可裝載的元件,比如通道驅動(chan_sip.so),或者一項可以連線到外部技術的資源(func_odbc.so)。Asterisk按照/etc/asterisk/modules.conf配置檔案裝載模組。後面我們會討論各個模組的使用。這裡我們只會介紹模組的概念,以及模組的各種型別。

執行一個不載入任何模組的Asterisk也是有可能的,儘管它什麼都做不了。你只有理解了Asterisk模組化的特點,才能充分理解Asterisk的架構。

Note:你可以啟動一個沒有載入任何模組的Asterisk,然後手工在控制檯一個個地新增;這種方法一般用於效能調優,可以保證僅載入所需要的模組。

Asterisk模組型別包括:

  • 應用程式(即撥號計劃中的命令)
  • 橋接模組
  • 呼叫詳單記錄模組
  • 通道事件日誌模組
  • 通道驅動
  • 編碼解碼器
  • 格式直譯器
  • 撥號計劃函式
  • PBX模組
  • 資源模組
  • 附加模組
  • 測試模組

接下來我們會列出分屬各個型別的所有模組,他們的用途,以及我們所認為的受歡迎程度和重要程度(有一些很常用,但有一些不太有用,僅僅是為了相容而保留)。這些模組的細節會在本書中陸續介紹,根據各自的情況,有些會被全面的討論,有些則根本不會涉及。

下面這些術語反映了我們對各個模組的看法:

  • 不重要
這個模組是個老古董。如果你要使用它,就不要指望能在社群中得到很好的支援。
  • 不可靠
新設計的或者試驗性的模組,不要用於生產環境。
  • 很有用
很時新,有人維護,受歡迎而且被推薦。
  • 可以用
能夠用,但用得不多,可能不完整。不推薦。
  • 不好說
新出現的模組,時間短,完整性和受歡迎程度都不太好說。
  • 已廢棄
已經被更好的模組取代了。
  • 有侷限
有侷限性,不能滿足要求。
  • 很重要
必須的。

應用程式

應用程式用於撥號計劃中,能夠處理呼叫流程。比如Dial()就是一個很重要的應用程式,負責建立出局連線。

名稱 用途 評價
app_adsiprog 給相容模擬電話載入模擬顯示服務介面(ADSI)指令碼。 不重要
app_alarmreceiver 支援接受警報裝置的報告。 不重要
app_amd 檢測電話答錄機。 不穩定
app_authenticate 比較雙音多頻(DTMF)輸入和一個給定的字串(通常是密碼)。 很有用
app_cdr 寫CDR記錄。 很有用
app_celgenuserevent 為CEL產生使用者自定義事件。 不好說
app_chanisavail 檢測通道的狀態。 不穩定
app_channelredirect 強制另一個通道進入撥號計劃的另一個地方。 很有用
app_chanspy 允許一個通道收聽另一個通道。 很有用
app_confbridge 電話會議(新版)。 不好說
app_controlplayback 播放提示,並提供快進和倒帶功能。 很有用
app_dahdibarge 允許在DAHDI通道中插話。(已廢棄,見app_chanspy) 已廢棄
app_dahdiras 在DAHDI通道上建立RAS伺服器。 不重要
app_db 訪問Asterisk內建的伯克利資料庫。(已廢棄,見func_db) 已廢棄
app_dial 把通道連線起來。(例如,打電話) 很重要
app_dictate 播放一段錄音,並提供開始/停止功能。 很有用
app_directed_pickup 應答另外一部分機上的呼叫。 很有用
app_directory 給出voicemail.conf中的姓名列表。 很有用
app_disa 提供撥號音並接受DTMF輸入。 很有用
app_dumpchan 在Asterisk控制檯列印通道變數。 很有用
app_echo 回放從通道中收到的語音。 很有用
app_exec 包含Exec(),TryExec()和ExecIf()。根據條件執行應用程式。 很有用
app_externalivr 類似於AGI,但是非同步的。 很有用
app_fax 提供SendFax()和ReceiveFax() 很有用
app_festival “文字-轉-語音”引擎。 可以用
app_flash 在通道上執行一次瞬間掛機 很有用
app_followme 根據followme.conf檔案執行找到我/跟隨我功能。 很有用
app_forkcdr 在當前呼叫上開始一條新的CDR記錄。 可以用
app_getcpeid 獲得ADSI CPE ID。 不重要
app_ices 把音訊傳送到一個icecast伺服器。 可以用
app_image 向可以支援的裝置上傳輸影象。 有侷限
app_ivrdemo 開發者的示例應用程式。 不重要
app_jack 使用JACK音訊連線工具包共享音訊。 很有用
app_macro 觸發撥號計劃巨集。(已廢棄,見GoSub()) 已廢棄
app_meetme 多方會議。 很有用
app_milliwatt 產生1004赫茲的音訊,以測試類比電路。 很有用
app_minivm 提供基本的函式,使得你可以構造自己的語音信箱。 可以用
app_mixmonitor 兩頭錄音,然後合併。 很有用
app_morsecode 產生莫爾斯電碼。 可以用
app_mp3 用mpg123播放mp3。 不重要
app_nbscat 獲得NBS音訊。 不重要
app_originate 允許發起一次呼叫。 很有用
app_osplookup 執行OSP查詢。 可以用
app_page 尋呼。 很有用
app_parkandannounce 自動播報保持的電話。 可以用
app_playback 播放音訊檔案,不接受輸入。 很有用
app_playtones 播放按鍵音。 很有用
app_privacy 如果沒有收到CallerID,就要求輸入使用者號碼。 不重要
app_queue 提供自動呼叫分配。 很有用
app_read 要求使用者輸入,並把輸入存入變數。 很有用
app_readexten 要求使用者輸入,並把當前來電轉駁到指定分機和上下文。 可以用
app_readfile 把檔案內容存入一個通道變數。(已廢棄,見func_env中的FILE()) 已廢棄
app_record 把收到的音訊存入檔案。 很有用
app_rpt 使用音效卡。(TODO:什麼是rpt專案,不懂。) 有侷限
app_sayunixtime 已指定的格式播放時間。 很有用
app_senddtmf 向呼叫者傳輸DTMF音訊。 很有用
app_sendtext 向相容的通道傳送文字。 不重要
app_setcallerid 在通道上設定CallerID。(已廢棄,見func_callerid) 已廢棄
app_skel 開發者的示例應用程式。 很有用
app_sms 在支援的地區傳送SMS訊息。 有侷限
app_softhangup 請求關閉通道。 很有用
app_speech_utils 語音識別。 很有用
app_stack 提供GoSub()等堆疊相關的操作。 很重要
app_system 執行作業系統命令。 很有用
app_talkdetect 類似於app_background,但允許收到音訊後中斷播放。 很有用
app_test C/S測試應用程式。 可以用
app_transfer 在當前通道上執行轉移。 很有用
app_url 向被呼叫通道傳遞URI。 有侷限
app_userevent 在AMI中產生一個定製事件。 很有用
app_verbose 在CLI中產生一個定製時間。 很有用
app_voicemail 提供語音信箱功能。 很重要
app_waitforring (TODO:不明白) 不重要
app_waitforsilence 包括WaitForSilent()和WaitForNoise();監聽入局通道,有超時限制。 很有用
app_waituntil 等待一個指定的Linux時間(從1970第一秒開始的計數值)到來。 很有用
app_while 包括While(),EndWhile()等,用於迴圈。 很有用
app_zapateller 播放特殊音調,以阻止電話推銷者。 可以用

橋接模組

橋接模組是Asterisk 1.8的新功能;他們以新的方式執行通道之間的橋接。他們每一個都提供不同的特性,用於不同的橋接需求。這些模組只用於app_confbridge。

名稱 用途 評價
bridge_builtin_features 當使用內建使用者特性(在features.conf中定義)時,執行橋接。 不好說
bridge_multiplexed 執行復雜的多路轉發,用於大型會議室。 不好說
bridge_simple 執行簡單的“通道-到-通道”橋接。 不好說
bridge_softmix 執行簡單的多路轉發,用於大型會議室。(TODO:不明白和bridge_multiplexed的區別) 不好說

電話詳單記錄模組

CDR模組是為了讓各種形式的話單記錄更方便。你可以把CDR存入檔案、資料庫、RADIUS、或syslog。

注:CDR不是為了計費而設計的。計費功能應該使用CEL。

名稱 用途 評價
cdr_adaptive_odbc 通過ODBC寫CDR,允許新增自定義欄位。 很有用
cdr_csv 把CDR寫入CSV檔案。 可以用
cdr_custom 和cdr_csv一樣,但允許新增自定義欄位。 很有用
cdr_manager 把CDR輸出到AMI介面。 很有用
cdr_odbc 通過ODBC寫CDR。 可以用
cdr_pgsql 把CDR寫到PostgreSQL。 很有用
cdr_radius 把CDR寫到RADIUS。 可以用
cdr_sqlite 把CDR寫到sqlite2資料庫。(已廢棄,見cdr_sqlite3_custom) 已廢棄
cdr_sqlite3_custom 把CDR寫到sqlite3資料庫,允許新增自定義欄位。 很有用
cdr_syslog 把CDR寫到syslog。 很有用
cdr_tds 把CDR寫到Microsoft SQL或Sybase資料庫,需要老版tds。 可以用

Web介面中會有一些和CDR相關的報告功能。

通道事件日誌模組

通道事件日誌可以完整記錄所有的呼叫活動。這也意味著你需要更小心地規劃擬撥號計劃,畢竟它不可能自動開始工作。Asterisk的CEL模組如下:

名稱 用途 評價
cel_custom 寫到磁碟檔案。 很有用
cel_manager 寫到AMI。 很有用
cel_odbc 寫到ODBC。 很有用
cel_pgsql 寫到PostgreSQL。 很有用
cel_radius 寫到RADIUS。 可以用
cel_sqlite3_custom 寫到sqlite3。 很有用
cel_tds 寫到Microsoft SQL或Sybase,需要老版tds。 可以用

通道驅動

沒有通道驅動,Asterisk就不可能建立呼叫。每種協議或通道型別都有自己特定的通道驅動。通道模組可以看做是通往Asterisk核心的網管。Asterisk的通道驅動如下:

名稱 用途 評價
chan_agent 為Queue()提供坐席通道。 很有用
chan_alsa 提供到高階Linux聲音架構(ALSA)的連線。 很有用
chan_bridge 僅供ConfBridge()內部使用。 很重要
chan_console 提供到portaudio的連線。 不好說
chan_dahdi 提供到DAHDI介面卡的連線。 很有用
chan_gtalk 提供到Google Talk的連線。 可以用
chan_h323 提供H.323連線。(已廢棄,見chan_ooh323) 已廢棄
chan_iax2 提供IAX2連線。 很有用
chan_jingle 提供jingle連線。 可以用
chan_local 把一部分撥號計劃當成通道。 很有用
chan_mgcp 提供媒體網管控制協議(MGCP)連線。 可以用
chan_misdn 連線到支援mISDN的ISDN卡。 有侷限
chan_multicast_rtp 連線到RTP多播流。 很有用
chan_nbs 網路廣播聲音(NBS)連線。 不重要
chan_oss 開放聲音系統驅動。 很有用
chan_phone LInux電話介面驅動,相當老。 不重要
chan_sip 回話啟動協議。 很重要
chan_skinny 思科瘦客戶端控制協議(SCCP)。 可以用
chan_unistim 北電Unistim協議。 可以用
chan_usbradio CM108 USB無線電介面卡。 可以用
chan_vpb Voicetronix通道。 不重要

編碼解碼器

編碼解碼器允許Asterisk轉換不同呼叫之間的音訊格式。如果一個呼叫來自PRI電路(使用G.711編碼),需要連線到一個SIP壓縮通道(使用G.729,SIP支援的編碼之一),那麼相應的編碼解碼器就會執行所需的轉換。

注:如果編碼解碼需要複雜的演算法,大量的轉碼工作會對CPU造成負擔。有些像Sangoma和Digium廠商的卡會提供硬體解碼編碼。

名稱 用途 評價
codec_adpcm 自適應差分脈碼調製解調 不重要
codec_alaw 全世界PSTN(除了美國、加拿大)採用脈衝編碼調製的A-law演算法。 很重要
codec_a_mu A-law到Mu-law的轉換。 很有用
codec_dahdi 使用Digium硬體解碼。(需要Digium轉碼卡) 很重要
codec_g722 寬頻帶音訊編碼解碼。 很有用
codec_g726 (TODO:不懂,大概類似於codec_adpcm) 不重要
codec_gsm 全球移動通訊系統。 很有用
codec_ilbc 因特網低位元率編碼解碼。 不重要
codec_lpc10 線性預測編碼生硬合成器。 不重要
codec_resample 8-bit和16-bit間帶符號線性取樣。 可以用
codec_speex speex編碼。 可以用
codec_ulaw 用於美國、加拿大的 脈衝編碼調製的Mu-law演算法。 很重要

格式直譯器

格式直譯器呼叫編碼解碼器的功能,但他們操作檔案而不是通道。如果你錄製了一段GSM音訊,要播放到其他非GSM通道,就需要一個格式直譯器。

如果你錄製成了多種格式(GSM,WAV),當某個通道需要該音訊時,Asterisk會選擇一個轉換代價最小的格式。

名稱 用途 評價
format_g723 G.723 .g723 不重要
format_g726 G.726 .g726 不重要
format_g729 G.729 .g729 很有用
format_gsm RPE-LTP (original GSM codec) .gsm 可以用
format_h263 H.263—video .h263 可以用
format_h264 H.264—video .h264 可以用
format_ilbc Internet Low Bitrate Codec .ilbc 不重要
format_jpeg Graphic file .jpeg .jpg 不重要
format_ogg_vorbis Ogg container .ogg 可以用
format_pcm Various Pulse-Coded Modulation formats: .alaw, .al, .alw, .pcm, .ulaw, .ul, .mu, .ulw, .g722, .au 很有用
format_siren14 G.722.1 Annex C (14 kHz) .siren14 不好說
format_siren7 G.722.1 (7 kHz) .siren7 不好說
format_sln16 16-bit signed linear .sln16 不好說
format_sln 8-bit signed linear .sln .raw 很有用
format_vox .vox 不重要
format_wav .wav 很有用
format_wav_gsm GSM audio in a WAV container .WAV, .wav49 可以用

撥號計劃函式

撥號計劃函式是對撥號計劃應用程式的補充,提供了一些有用的增強功能,比如字串處理、日期時間轉換、ODBC連線性等。

名稱 用途 評價
func_aes 加密、解密AES字串。 很有用
func_audiohookinherit 允許來電轉駁後仍被錄音。 很有用
func_base64 編碼、解碼base-64字串。 可以用
func_blacklist 讀、寫astdb中的黑名單。 很有用
func_callcompletion 存取通道的呼叫完成配置引數。 不好說
func_callerid 存取CallerID。 很有用
func_cdr 存取CDR變數。 很有用
func_channel 存取通道資訊 很有用
func_config 包括AST_CONFIG();從配置檔案讀取變數。 可以用
func_connectedline 改變已連線的通道資訊(需要電話的支援)。 不好說
func_curl 使用curl訪問URL。 很有用
func_cut 對字串切片或者切塊。 很有用
func_db 提供astdb函式。 很有用
func_devstate 獲得裝置狀態。 很有用
func_dialgroup 建立一個同時撥號組。 很有用
func_dialplan 驗證指定的撥號計劃目標是否存在。 很有用
func_enum 執行ENUM查詢。 很有用
func_env 包括FILE(),STAT(),ENV()。執行作業系統動作。 很有用
func_extstate 返回指定的分機狀態。 很有用
func_global 存取全域性變數。 很有用
func_groupcount 存取一個組的通道數。 很有用
func_iconv 字元編碼轉換。 可以用
func_lock 包括LOCK(),UNLOCK(),TRYLOCK();用於撥號計劃中的競爭控制。 很有用
func_logic 邏輯判斷函式,包括ISNULL(),SET(),EXISTS(),IF(),IFTIME(),IMPORT() 很有用
func_math 數學函式,包括MATH(),INC(),DEC() 很有用
func_md5 生成MD5指紋。 很有用
func_module 檢測模組是否已經裝載。 可以用
func_odbc 訪問ODBC。 很有用
func_pitchshift 修改音訊流的音調。 很有用
func_rand 生成一個隨機數。 很有用
func_realtime 在Asterisk實時架構中執行查詢。 很有用
func_redirecting 獲取本次呼叫的轉發資訊。 很有用
func_sha1 生成SHA1指紋。 很有用
func_shell 執行shell命令,並返回結果。 很有用
func_speex 執行聲音調優。 很有用
func_sprintf 字串格式化。 很有用
func_srv 執行SRV查詢。 很有用
func_strings 字串處理函式。 很有用
func_sysinfo 獲取系統資訊,例如記憶體,交換空間和CPU負荷等。 很有用
func_timeout 存取通道的超時時間。 很有用
func_uri 把字串做URI安全編碼。 很有用
func_version 獲取Asterisk版本資訊。 可以用
func_vmcount 獲取語音信箱的訊息數。 很有用
func_volume 設定通道音量。 很有用

PBX模組

PBX模組提供增強的控制和配置機制。

名稱 用途 評價
pbx_ael 提供AEL支援。(很少有人用,如果不想用傳統的撥號計劃配置檔案的話,大多數人會選擇AMI+AGI) 可以用
pbx_config 用於解釋extensions.conf,最傳統、用得最多的撥號計劃語言。 很有用
pbx_dundi 執行遠端Asterisk資料查詢。 很有用
pbx_loopback 類似於撥號計劃的include,有點過時。 不重要
pbx_lua 支援使用lua編寫撥號計劃。 很有用
pbx_realtime 提供Asterisk實時架構相關的功能。 很有用
pbx_spool 和Asterisk外呼檔案有關,提供外呼連線池。 很有用

資源模組

資源模組用於整合外部資源。例如res_odbc用於訪問ODBC資料庫連線。

名稱 用途 評價
res_adsi 提供ADSI。(儘管大多數ADSI功能Asterisk是不用的,但語音信箱用到這個資源) 很重要
res_ael_share 為pbx_ael提供共享程式。(如果你使用AEL的話,這個模組就很重要。) 很重要
res_agi 提供Asterisk網管介面。 很有用
res_ais 使用注入OpenAIS一類的AIS實現, 提供分散式訊息等待指示和裝置狀態通知。 很有用
res_calendar 提供日曆系統的整合。 很有用
res_calendar_caldav 提供CalDAV特定的能力。 很有用
res_calendar_exchange 提供微軟Exchange的特定能力。 很有用
res_calendar_icalendar 提供蘋果/谷歌的iCalendar特定能力。 很有用
res_clialiases 建立CLI別名。 很有用
res_clioriginate 從CLI發起一次呼叫。 可以用
res_config_curl 使用curl拉取配置資訊。 很有用
res_config_ldap 從LDAP拉取配置資訊。 可以用
res_config_odbc 從ODBC拉取配置資訊。 很有用
res_config_pgsql 從PostgreSQL拉取配置資訊。 可以用
res_config_sqlite 從SQLite拉取配置資訊。 可以用
res_convert 使用CLI執行檔案編碼轉換。 可以用
res_crypto 提供加密功能。 很有用
res_curl 為其他curl模組提供公共服務。 很有用
res_fax 為其他fax模組提供公共服務。 很有用
res_fax_spandsp 為使用spandsp的傳真功能提供外掛。 很有用
res_http_post 為Asterisk的HTTP伺服器提供POST上傳功能。 可以用
res_jabber 提供Jabber/XMPP資源。 很有用
res_limit 允許調整Asterisk程序的系統限制。 可以用
res_monitor 提供呼叫錄音資源。 很有用
res_musiconhold 提供等待音樂(MOH)功能。 很重要
res_mutestream 提供音訊流的禁音和放音功能。 不好說
res_odbc 為其他ODBC模組提供公共功能。 很有用
res_phoneprov (TODO:提供來自Asterisk HTTP 伺服器的電話?不懂。) 不好說
res_pktccops 提供PacketCable COPS資源。 不好說
res_realtime 為Asterisk實時架構(ARA)提供CLI命令。 很有用
res_rtp_asterisk 提供RTP。 很重要
res_rtp_multicast 提供多播RTP。 不好說
res_security_log 啟用安全日誌。 不好說
res_smdi 通過SMDI協議提供語音信箱通知。 有侷限
res_snmp 向SNMP管理的網路提供系統狀態資訊。 可以用
res_speech 通用語音識別API。 有侷限
res_timing_dahdi 通過DAHDI核心介面提供時鐘。 很有用
res_timing_kqueue 通過某些作業系統的特性提供時鐘。 不好說
res_timing_pthread 使用標準pthread API提供時鐘;不是很有效率,但移植性好。 很有用
res_timing_timerfd 通過新版Linux核心的timerfd API提供時鐘。 很有用

附加模組

附加模組是社群開發的模組,用法和版權條款都和Asterisk的主程式碼不一樣。它們位於不同的目錄,預設是不會編譯和安裝的。要啟用這些模組就要使用menuselect構建配置工具。

名稱 用途 評價
app_mysql 在撥號計劃中執行MySQL查詢。(已廢棄,見func_odbc) 已廢棄
app_saycountpl 用波蘭語播報計數。(已廢棄,已經整合到say.conf中) 已廢棄
cdr_mysql 在MySQL中記錄CDR。(我們推薦cdr_adaptive_odbc) 可以用
chan_mobile 允許手機通過藍芽接聽或撥打電話。 有侷限
chan_ooh323 支援H.323協議。 可以用
format_mp3 支援播放MP3檔案。 可以用
res_config_mysql 使用MySQL資料庫作為實時配置後端。 很有用

測試模組

測試模組被Asterisk開發團隊用來驗證新程式碼。它們會被頻繁地新增或修改,對你沒什麼用,除非你要開發Asterisk。

如果你是Asterisk開發者,你也許會對Asterisk測試套件有興趣,你可以執行自動測試並將結果反饋給Asteisk專案。通過不斷地新增測試用例,Asterisk可以防止程式碼腐爛。通過新增你自己的測試用例,升級的時候會更有把握些。

更多資訊可以參考:

檔案結構

Asterisk是一個複雜的系統,由很多資源組成。這些資源以不同的方式使用檔案系統。既然Linux在這一點上很靈活,那就很有必要搞清楚什麼資料存在什麼地方(比如語音信箱檔案、日誌檔案等)。

配置檔案

Asterisk配置檔案包括extensions.conf,sip.conf,modules.conf,以及各種通道、資源、模組和函式用到的引數定義檔案。這些檔案一般位於/etc/asterisk,在做Asterisk的配置和管理工作時你經常會進到這個目錄。

模組

Asterisk的模組一般會安裝到/usr/lib/asterisk/modules目錄。你一般不用關心這個目錄;但你知道模組在什麼地方有時候也很有用。例如,如果你升級Asterisk,並且用menuselect構建配置工具選擇了不同的模組,老的(不相容)模組又沒有刪除,安裝指令碼會提示警告資訊。 應該從modules目錄中刪除 這些老的模組檔案 。要麼手工刪除,要麼呼叫make uninstall。<