Asterisk一些筆記

在www.asterisk.org上可以獲得asterisk 1.4和asterisk 1.2.18兩個版本。前一個是for 2.6內核,後一個是for 2.4內核。
我在Ubuntu 6.06上編譯和運行了asterisk 1.4。在RH9上編譯和運行了asterisk 1.2。
使用”asterisk –vvvc”命令啓動了Asterisk 1.2.18後,出現了
Asterisk Ready.
*CLI>
的提示界面。這是Asterisk的console界面。當在*CLI提示符後面使用”dial”命令後,asterisk開始播放一系列的語音。Dial命令是如何工作的,在asterisk內部,dial命令的運行流程是怎樣的一個過程?經過二週的斷斷續續的對源代碼的閱讀,大致瞭解了一些信息,特在此記錄。記錄的過程也可以幫助我整理一下思路。
在asterisk中,有三個重要的邏輯實體。它們完成管理員設定的各項電話功能。這三個實體是:PBX,Channel,Application。
當一個呼叫業務啓動後,就會有一個PBX線程被啓動,它掌控着這個呼叫業務,直到呼叫業務的結束。
Channel是完成呼叫業務基本功能的實體。這些基本功能包括:二次撥號(send_digit),掛機(hangup),摘機(answer)等。Channel有很多種:H.323,OSS,SIP,ZAP,ALSA,IAX等。每個channnel實體的代碼對應於一個名爲chan_xxx.c的源代碼文件。比如OSS就對應於chan_oss.c。每個Channel實體被編譯爲.so文件,成爲linux的共享對象(Shared Object)。當asterisk系統啓動時,系統根據配置有選擇的裝入這些共享對象(類似於WINDOWS下的動態鏈接庫)。
Application是對一個呼叫業務進行操作的動作。我覺得叫Action比較好,不清楚爲什麼叫application,也許我還沒有了解更深入吧。這些動作有:撥號(dial),echo,answer,wait,playback等。每個application實體的代碼對應於一個名爲app_xxx.c的源代碼文件。比如wait就對應於app_wait.c。Application類似channel也被編譯成爲.so。
上面介紹了三個完成asterisk系統各項電話功能的實體,下面介始asterisk系統的幾個基本的配置文件。
目前,我只理解了一小部分的配置文件。對於channel,每個channel都有自已的配置文件。同樣對於OSS,配置文件是oss.conf。另一個重要的配置文件是extension.conf。它確定了asterisk系統的dial plan。
下面從asterisk系統的main()開始,介紹PBX,Channel,Appliction這三者是如何關聯到了一起。
Asterisk.c中的main()是系統的開始入口函數。在2363行,main()調用了load_modules()來裝載各個模塊(也就是共享對象)。Asterisk會裝載channel oss模塊,我們轉到chan_oss.c文件中的load_modules()函數。在這個函數裏,
首先,cfg = ast_config_load(config);裝入了oss.conf文件的內容;
其次,ast_channel_register(&oss_tech);將channel的各項基本功能註冊到了系統中。oss_tech是一個struct ast_channel_tech結構。它記錄了channel oss完成基本功能的各個函數地址。每個channel都是這樣註冊到系統中的。
最後,ast_cli_register_multiple()將channel oss支持的CLI命令及其對應的回調函數註冊到系統中。
這樣,一個channel實體被裝載了。
回到啓動asterisk後的console界面上來。在提示符*CLI>後,輸入dial,將聽到聲卡發出的聲音。這個命令是如何被執行的呢?
由於channel oss將自己支持的命令在被裝載時,通過ast_cli_register_multiple()註冊到了系統中,因此,在系統的*CLI>提示後輸入了dial後,系統在註冊信息找到了channel oss支持dial這個命令,並確定了chan_oss.c中的console_dial()函數是這個命令的回調函數,這個回調函數被調用。
在console_dial()中,oss_new()被調用是最關鍵的地方。oss_new()的作用在doc/channel.txt中有說明。事實上,channel.txt中對channel的作用有更清晰的說明。回到oss_new上,oss_new分配了一個新的struct ast_channel c。這個c的exten在ast_channel_alloc()裏被缺省賦值爲”s”,這一點還是很重要的。然後,oss_new調用了ast_pbx_start()啓動了一個PBX線程。這個線程在其生命期裏負責處理這個channel的事件。這個線程是pbx.c中的__ast_pbx_run ()。在__ast_pbx_run()裏,pbx線程通過ast_exists_extension()和ast_spawn_extension()確定了呼叫的業務流程。
業務流程是由dial plan確定的。Dial plan在extension.conf中配置。對於oss的dial(這是一個呼出),業務流程是如何確定的呢?
在oss.conf中,配置了這個channel的context和extension。對於channel oss ,它的context是local。對於context and extension這兩個概念在asterisk handbook中有說明。有了channel oss的contest and extension,pbx線程從extension.conf中去尋找。在extension.conf中,對於oss 的context是這樣配置的:
[local]
ignorepat => 9
include => default
include => parkedcalls
……
[default]
include => demo
[demo]
exten => s,1,Wait,1 ; Wait a second, just for fun
exten => s,n,Answer ; Answer the line
exten => s,n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
exten => s,n(restart),BackGround(demo-congrats) ; Play a congratulatory message
exten => s,n(instruct),BackGround(demo-instruct) ; Play some instructions
exten => s,n,WaitExten ; Wait for an extension to be dialed.
從這個配置上就可以看到,dial命令就對應於一個voice menu。當context爲local時,執行demo這個context。Channel oss的extension缺省爲”s”。因此,dial plan爲先等待1秒,然後,應答它,通過BackGround應用,播放demo-congrats語音文件。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章