基于嵌入式Linux的網(wǎng)絡(luò)語音平臺的設(shè)計與構(gòu)建
采用IP網(wǎng)絡(luò)進(jìn)行語音通信是一種廉價且方便的通信方式。其目前的技術(shù)已經(jīng)為用戶間的通信提供清晰、穩(wěn)定、低延時的話音質(zhì)量,同時支持語音、數(shù)據(jù)、圖像的傳輸和其他多媒體業(yè)務(wù)。特別對于許多大中型企業(yè)來說,由于在各省或不同國家設(shè)有機(jī)構(gòu),每月都會產(chǎn)生巨額的國際、國內(nèi)長話通信費用,同時由于信息保密的要求,企業(yè)往往需要自己構(gòu)建類似VPN這樣的IP通話網(wǎng)絡(luò)以降低通信成本。這樣機(jī)構(gòu)內(nèi)部會先建立一個自己的電話網(wǎng)絡(luò),同時以VPN或其他方式通過IP網(wǎng)連接出去。整個系統(tǒng)可以有效降低企業(yè)的運營成本,提高工作的效率。本文所述的網(wǎng)絡(luò)語音處理平臺就是建立在此種方案上,主要通過VoIP網(wǎng)關(guān)+模擬話機(jī)的方式來實現(xiàn)。其中VoIP網(wǎng)關(guān)的主要功能是進(jìn)行信令處理、以ITU-T提出的H.323協(xié)議或IETF提出的SIP協(xié)議通信、語音編解碼處理等。
1 結(jié)構(gòu)體系介紹
網(wǎng)絡(luò)語音處理平臺的基本工作原理是先將模擬語音信號轉(zhuǎn)為數(shù)字信號,再對輸入的語音數(shù)據(jù)編碼進(jìn)行壓縮處理,然后在H.323或SIP協(xié)議框架的基礎(chǔ)上,把這些語音數(shù)據(jù)分組打包,經(jīng)過IP網(wǎng)絡(luò)把數(shù)據(jù)包送至接收端,接收端再把這些語音數(shù)據(jù)包串起來,經(jīng)過解壓處理后,恢復(fù)成原來的語音信號,從而達(dá)到由互聯(lián)網(wǎng)傳送語音的目的。本文將分硬件和軟件兩部分來講述網(wǎng)絡(luò)語音平臺的構(gòu)建。
1.1 硬件部分
整個硬件部分如圖1所示。
整個系統(tǒng)包括語音處理部分和網(wǎng)絡(luò)數(shù)據(jù)處理兩部分,其中語音處理部分又分為FXO和FXS接口電路。FXO接口用于連接PSTN,可模擬電話功能,提供環(huán)路關(guān)閉功能并檢測來話振鈴。FXS用于連接POT普通電話機(jī),模擬電話局端交換的功能。
在VoIP網(wǎng)關(guān)中,F(xiàn)XS電路是在分組網(wǎng)絡(luò)上建立去話呼叫與接收來話呼叫的基本接口。在用戶端(CPE)應(yīng)用中,F(xiàn)XS電路存在于網(wǎng)關(guān)中,可提供撥號音、電池電流與振鈴電壓的功能,并檢測來自電話的環(huán)路關(guān)閉。由于該交換功能處于CPE級,因此不必與PSTN建立直接連接。FXS電路包括CODEC與SLIC(用戶線路接口電路)兩部分。CODEC由ADC與DAC構(gòu)成。ADC將來自模擬電話的模擬信號轉(zhuǎn)換為可通過VoIP網(wǎng)絡(luò)傳輸?shù)臄?shù)字信號。DAC將數(shù)字信號轉(zhuǎn)換為模擬電平,以驅(qū)動模擬電話。為了實現(xiàn)4kHz的音頻帶寬,ADC的采樣速率通常約為8kHz。SLIC部分則模擬PSTN電壓電平,通過用戶線向共電式話機(jī)直流饋電,檢測電話掛機(jī)還是摘機(jī),并生成高達(dá)120V的振鈴電壓,同時提供過壓保護(hù)(Overvoltage Protection)功能,以防止用戶線上的電壓沖擊或過壓而損壞設(shè)備。
SLIC芯片采用LEGERITY的LE7947C,在控制器的控制下能模仿電話局局端功能,能對饋電電流進(jìn)行控制,并提供掛機(jī)傳輸功能,如在電話線路處在On-Hook狀態(tài)(被呼叫方?jīng)]摘機(jī)時)提供振鈴信號。監(jiān)視用戶線通斷狀態(tài),以檢測話機(jī)的摘機(jī)、掛機(jī)、撥號脈沖等用戶線信號,轉(zhuǎn)送給控制設(shè)備,以表示用戶的忙閑狀態(tài)和接續(xù)要求。SLIC芯片控制的方式如表1所示。這些控制信號接到了IXP421的GPIO上,這樣由IXP421發(fā)出控制信號??刂平Y(jié)果通過引腳的電平值來表示。
其中開路是指當(dāng)線路出現(xiàn)故障時,模塊在內(nèi)部將TIP和RING線斷開。激活是指模塊收到摘機(jī)信號后(無論作為主叫還是振鈴時),首先使模塊重新激活,然后開始通話。通話結(jié)束后又設(shè)為待機(jī)狀態(tài)。如需掛機(jī)傳輸功能,需在振鈴1秒(狀態(tài)值為1)后,將狀態(tài)值設(shè)為3(即011),持續(xù)時間為4秒,在此期間模塊可向話機(jī)傳送呼叫方ID等信號。待機(jī)是指模塊等待主叫摘機(jī)或作為被叫振鈴等事件發(fā)生。
CODEC芯片采用LEGERITY的T8503。它是A-律/μ-律的PCM編碼器,含有A/D和D/A單元,實現(xiàn)聲音的數(shù)字化和重組,并能實現(xiàn)增益控制。CODEC芯片具有兩個通道,每個通道均含有一個針對語音編碼或解碼的濾波器。兩個通道的PCM數(shù)據(jù)通過PCM同步接口進(jìn)行接收和發(fā)送,并由一對FSXn和FSRn控制兩個通道的幀同步,確保在每個通話時隙進(jìn)行數(shù)據(jù)傳輸。
FXO電路部分包括CODEC與數(shù)據(jù)存取裝置(DAA)。將模擬語音轉(zhuǎn)換為數(shù)字信號,隨后再轉(zhuǎn)換回來,同時負(fù)責(zé)數(shù)據(jù)的傳輸。DAA模擬(POTS)電話功能,其重要作用是去除高電壓直流偏置,將PSTN環(huán)路關(guān)閉,從而僅傳送來自PSTN的模擬交流信號。并具有極性保護(hù)電路,保證電話機(jī)與外線連接時能取得極性正確的直流工作電壓。[!--empirenews.page--]
FXO部分電路主要采用SILICON LABS公司的SI3016和SI3021。SI3016為一個DAA電路,能為線路上的信號提供光電隔離和2/4線轉(zhuǎn)換功能,以滿足編解碼與數(shù)字交換對四線傳輸?shù)囊?。并且能夠?qū)崿F(xiàn)對線路上的振鈴信號、呼叫方ID和極性反轉(zhuǎn)檢測等功能。SI3021一方面提供直接連接DSP的通信接口,另一方面也提供控制接口。電路可工作于On-Hook(電話線可供使用)和Off-Hook(電話線忙碌)這兩種狀態(tài)下,通過設(shè)定SI3021的引腳電平的高低來控制:為高表示處于On-Hook狀態(tài),可以接收或發(fā)起一個呼叫;為低表示處于Off-Hook狀態(tài),電話線忙碌。當(dāng)線路上有振鈴信號時通過引腳表示。并可以通過配置M1和M0腳來選定串行數(shù)據(jù)接口的工作模式。整個平臺還配有CPLD電路,是為了控制各個電話接口,并協(xié)調(diào)各端口間的通信。
主處理器IXP421是INTEL公司IXP42x系列的網(wǎng)絡(luò)處理器,它在VoIP應(yīng)用方面具有自己的特點。如提供了兩個高速同步串口HSS, 同時含有高速網(wǎng)絡(luò)處理引擎NPE,在Xscale的配合下它可以實現(xiàn)DSP等高級數(shù)據(jù)處理的應(yīng)用。并配有基于Xscale的DSP軟件庫,支持2~4路語音信號的處理。在網(wǎng)絡(luò)處理方面,IXP421集成有10~100兆MAC,通過MII/RMII接口連接通用PHY芯片,并連至IP網(wǎng)絡(luò)。
1.2 軟件部分
軟件可從功能上或驅(qū)動模塊上劃分,下面將從以上兩個方面進(jìn)行分析。
1.2.1 軟件功能模塊
從功能上可劃分如圖2所示的模塊結(jié)構(gòu)。
其中DSR模塊是IXP421進(jìn)行底層語音數(shù)據(jù)處理的模塊,它主要采用由INTEL提供的DSR(DSP software release)軟件庫。一方面,它與上層應(yīng)用程序進(jìn)行通信,傳遞數(shù)據(jù)或響應(yīng)來自上層的控制消息。另一方面,它與底層接口進(jìn)行通信與控制。
編碼部分負(fù)責(zé)進(jìn)行編碼和對從HSS到IP接口的數(shù)據(jù)分組打包,提供對G.711等音頻標(biāo)準(zhǔn)的支持,并提供有增益控制功能的自動等級控制ALC單元和區(qū)分背景噪聲的VAD功能。并將多個語音幀合并成一個IP分組包。對語音包以特定的幀長進(jìn)行壓縮編碼,壓縮后的語音包送入網(wǎng)絡(luò)處理單元。網(wǎng)絡(luò)處理單元為語音添加包頭、時標(biāo)和其他信息后,把數(shù)據(jù)放在可變長的數(shù)據(jù)報或分組中,然后給每個數(shù)據(jù)報附帶尋址和控制信息,并通過網(wǎng)絡(luò)發(fā)送到目的地。
相對于解碼部分負(fù)責(zé)把從IP網(wǎng)絡(luò)接收的語音分組包進(jìn)行打包并轉(zhuǎn)成語音數(shù)據(jù)流發(fā)送至HSS接口。類似于編碼部分,解碼部分也包含G.711和G.729數(shù)據(jù)處理和ALC處理單元。不同的是其包含產(chǎn)生適當(dāng)背景噪聲的CNG單元、消除由于網(wǎng)絡(luò)丟包而造成語音信息不完整問題的PLC單元和控制從IP網(wǎng)絡(luò)到HSS接口數(shù)據(jù)傳輸節(jié)奏的JitterBuffer單元。
電話信號音監(jiān)測模塊負(fù)責(zé)監(jiān)控300~3500Hz的電話信號音,如DTMF信號等。主要是采用快速傅立葉算法FFT來進(jìn)行分析和判斷。電話信號音產(chǎn)生模塊則負(fù)責(zé)產(chǎn)生相應(yīng)的電話信號音。而網(wǎng)絡(luò)節(jié)點是連接HSS端口與編解碼等部分的程序模塊,它把需要從HSS端口發(fā)送的數(shù)據(jù)放入HSS發(fā)送緩沖區(qū),或把需要從HSS端口接收的數(shù)據(jù)放入HSS接收緩沖區(qū)內(nèi)。
1.2.2 狀態(tài)機(jī)的結(jié)構(gòu)
為了模擬通常狀態(tài)下的電話機(jī)工作流程,需要相應(yīng)地建立幾種不同的狀態(tài),并實現(xiàn)不同狀態(tài)的轉(zhuǎn)換。一般通話雙方有空閑、撥號、發(fā)送信令、回應(yīng)、建立連接和斷開連接等狀態(tài),故可以定義如下幾個狀態(tài)值:call_idel、call_dial、call_cancel、call_invite、call_ack、call_connect、call_bye等。例如用戶摘機(jī)事件發(fā)生后會有中斷產(chǎn)生,若該路終端目前的狀態(tài)為call_ack時,表明該終端用戶為被動接收者,且已接收到invite信令并等待用戶摘機(jī)。故此時狀態(tài)轉(zhuǎn)為call_connect并進(jìn)行相關(guān)處理。而當(dāng)該路終端目前的狀態(tài)不為call_ack時,表明該終端用戶為主動呼叫者,準(zhǔn)備撥號撥打電話。此時狀態(tài)轉(zhuǎn)為call_dial,話筒中產(chǎn)生等待音,DSR模塊開始等待用戶撥號。當(dāng)用戶結(jié)束撥號后狀態(tài)轉(zhuǎn)為call_invite并進(jìn)行相關(guān)處理。大致流程如圖3所示。
為了保證狀態(tài)機(jī)能在不同的狀態(tài)之間轉(zhuǎn)換和方便控制管理各路話音通話的信息。還需要建立一些全局?jǐn)?shù)據(jù)結(jié)構(gòu):
struct call_params{
unsigned char local_num;
unsigned char remote_num;
unsigned char local_addr;
unsigned char remote_addr;
unsigned char status;
};
用于保存當(dāng)前網(wǎng)關(guān)中各路話音的配置參數(shù),num表示該路通話的本地號碼和對端號碼,addr表示該路通話對應(yīng)在DSR內(nèi)所使用的本地和遠(yuǎn)端網(wǎng)絡(luò)地址,status記錄本地終端在該通話中處于狀態(tài)機(jī)中的狀態(tài)。設(shè)備在加電啟動后,需要按步驟進(jìn)行一系列的初始化工作。包括一些記錄狀態(tài)信息的全局變量,初始化SLIC接口、DSR模塊、網(wǎng)絡(luò)接口、信令處理模塊并開啟所需的監(jiān)控線程,等待控制狀態(tài)的變化。
1.2.3 軟件驅(qū)動模塊
因為網(wǎng)絡(luò)語音底層平臺使用嵌入式LINUX做為其操作系統(tǒng),故需要劃分如圖4所示的幾個模塊并寫出相應(yīng)的驅(qū)動。[!--empirenews.page--]
以內(nèi)核態(tài)運行的程序主要包括SLIC控制模塊、DSR控制模塊及接口和DSR數(shù)據(jù)模塊這三部分,它們基本完成了底層所需的功能要求。用戶態(tài)的程序都是運行在其上,對其進(jìn)行管理控制,以實現(xiàn)上層的應(yīng)用。
(1)SLIC控制模塊
由于整個平臺包含有FXS和FXO接口,故SLIC控制模塊也可以相應(yīng)地分為兩部分。
對于FXS接口程序部分,其主要是模擬PSTN局端功能,對提供撥號音、電池電流與振鈴電壓和檢測來自電話的環(huán)路關(guān)閉進(jìn)行相應(yīng)地控制。當(dāng)有控制信息需要輸出時,驅(qū)動程序通過向SLIC芯片的C1、C2和C3管腳寫入相應(yīng)的電平,實現(xiàn)對SLIC的控制(具體數(shù)值可參看表1)。可以根據(jù)SLIC所處的狀態(tài)進(jìn)行劃分,設(shè)置如下四種狀態(tài):fxs_ring,fxs_take,fxs_onhook,fxs_offhook。當(dāng)其處在fxs_ring狀態(tài)下就可以為FXS接口提供撥號音、振鈴等信號;當(dāng)其處在fxs_take狀態(tài)下表明用戶剛剛摘機(jī);當(dāng)其處在fxs_offhook狀態(tài)下表明該終端用戶為主動呼叫者,需要處理摘機(jī)以后的操作;當(dāng)其處在fxs_onhook狀態(tài)下表明用戶掛機(jī)。
相應(yīng)的,當(dāng)SLIC有中斷輸入時,中斷處理程序會根據(jù)當(dāng)前的狀態(tài)來判斷。如果確定是用戶進(jìn)行了摘機(jī)或掛機(jī)操作后,查詢最后一次硬中斷后該路SLIC的電平,為0則處于摘機(jī)狀態(tài),否則處于掛機(jī)狀態(tài)。這里中斷的處理較為重要。其內(nèi)容包括:中斷源是由哪個FXS端口發(fā)出的,并根據(jù)所處的狀態(tài)來開啟相應(yīng)狀態(tài)下的定時器,以保證狀態(tài)變化間的時間間隔。
對于FXO接口程序部分,其主要是模擬電話機(jī)的功能,所以功能相對要簡單些。在程序中主要設(shè)定有fxo_ring、fxo_onhook和fxo_offhook這三個狀態(tài)。當(dāng)其處在fxo_offhook狀態(tài)下表明用戶摘機(jī)。當(dāng)其處在fxo_onhook狀態(tài)下驅(qū)動程序就把DAA芯片的引腳拉高,表明用戶掛機(jī)。相應(yīng)的,當(dāng)有控制信息需要輸入時,其檢測DAA芯片的引腳來進(jìn)行判斷,這里同樣要啟動相應(yīng)的定時器,來判斷回路上是否有振鈴電平或何時回路上振鈴信號結(jié)束等信息。當(dāng)程序判斷處在fxo_ring狀態(tài)下,則表明線路上有振鈴信號并做相關(guān)處理。
(2)DSR控制模塊及接口
DSR控制模塊及接口主要實現(xiàn)用戶對串行語音數(shù)據(jù)通信接口HSS以及底層引擎NPE的控制。既與來自上層應(yīng)用程序進(jìn)行信息交互,又為上層應(yīng)用程序和SLIC硬件之間提供控制接口。與一般的設(shè)備驅(qū)動一樣,主要包括DSR_open()、DSR_close()、DSR_read()、DSR_write()和DSR_ioctl()這些函數(shù)。其中DSR_read()和DSR_write()主要負(fù)責(zé)從DSR讀取消息和向DSR寫入消息。DSR_ioctl()主要負(fù)責(zé)控制DSR的相關(guān)配置參數(shù)讀入與讀出和傳遞SLIC控制信息給底層的SLIC控制模塊。參數(shù)包括根據(jù)當(dāng)前所處狀態(tài)判斷后所得出的C1、C2和C3管腳寫入相應(yīng)的電平值、查詢當(dāng)前SLIC的工作狀態(tài)信息、SLIC振鈴信號的產(chǎn)生和停止等。DSR的相關(guān)配置參數(shù)包括DSR中DSP通道數(shù)目、通道編碼器的類型、編解碼器輸出語音數(shù)據(jù)幀的大小等。
(3)DSR數(shù)據(jù)模塊
DSR數(shù)據(jù)模塊主要實現(xiàn)話音數(shù)據(jù)在內(nèi)核與用戶態(tài)之間的交互。包括從內(nèi)核中讀取數(shù)據(jù),向內(nèi)核中發(fā)送數(shù)據(jù)。為了有效把握數(shù)據(jù)傳輸節(jié)奏,需要建立一種內(nèi)部緩存機(jī)制。包括從DSR讀取到數(shù)據(jù)緩存后發(fā)送給用戶態(tài)的應(yīng)用程序和用戶態(tài)的應(yīng)用程序向DSR發(fā)送數(shù)據(jù)的緩存。緩存內(nèi)的數(shù)據(jù)查詢也是每隔一段時間后再進(jìn)行的。但注意緩存不應(yīng)開的過大,以免通話延時的加大。為了消除由于網(wǎng)絡(luò)丟包而造成語音信息不完整的問題,DSR數(shù)據(jù)模塊也建立了相應(yīng)的機(jī)制來控制。
用戶的應(yīng)用程序主要運行在用戶態(tài),針對DSR模塊和網(wǎng)絡(luò)上收發(fā)的語音數(shù)據(jù)和控制信令進(jìn)行處理操作。以編程實現(xiàn)直接內(nèi)向呼叫、呼叫轉(zhuǎn)移網(wǎng)絡(luò)、呼叫等待和三方呼叫等功能。對于底層通話平臺來說,主要關(guān)心的是處理電話和IP網(wǎng)絡(luò)間的銜接問題,這需要做好如下幾個接口:DSR控制接口、DSR數(shù)據(jù)接口和網(wǎng)絡(luò)接口,以實現(xiàn)語音數(shù)據(jù)收發(fā)、通話信令收發(fā)和DSR控制消息收發(fā)的管理。
網(wǎng)絡(luò)接口模塊用來接受網(wǎng)絡(luò)上傳遞進(jìn)來的數(shù)據(jù),做出相關(guān)處理后將壓縮的語音數(shù)據(jù)通過DSR數(shù)據(jù)接口傳遞給內(nèi)核處理,同時也負(fù)責(zé)將從DSR數(shù)據(jù)接口傳遞來的壓縮后的語音數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上。如果從網(wǎng)絡(luò)上傳遞進(jìn)來的數(shù)據(jù)是通話信令,則在做出相關(guān)處理后將具體的控制信息通過DSR控制接口發(fā)送給內(nèi)核,或者根據(jù)底層操作的內(nèi)容把相應(yīng)的信令信息通過網(wǎng)絡(luò)接口發(fā)送到網(wǎng)絡(luò)上。例如,對DSR的相關(guān)控制消息包括打開與關(guān)閉DSR編解碼功能、打開與關(guān)閉在向電話輸出的電話信令音和開啟與關(guān)閉檢測用戶鍵盤撥號等功能。
2 測試
為了保證當(dāng)前系統(tǒng)能正確工作,需要對其底層功能進(jìn)行測試。因為編碼壓縮的語音數(shù)據(jù)由實時傳送協(xié)議RTP負(fù)責(zé)傳遞,故主要采用用戶數(shù)據(jù)UDP包的形式接收與發(fā)送。出于這個角度考慮,可以實現(xiàn)將電話手柄的MIC采集的聲音返回至同一電話手柄的聽筒內(nèi)。首先編寫一個小程序來實現(xiàn)將話筒收集的語音數(shù)據(jù)發(fā)送至網(wǎng)絡(luò)上,同時接受來自網(wǎng)絡(luò)的數(shù)據(jù)并還原成模擬話音。假設(shè)網(wǎng)絡(luò)上有一臺IP地址為192.168.0.1的主機(jī)。其運行一個UDP數(shù)據(jù)包環(huán)回程序負(fù)責(zé)將網(wǎng)上接收到的UDP數(shù)據(jù)包轉(zhuǎn)發(fā)回源發(fā)送端。開始測試前,先設(shè)定一些必要的控制信息,如對方IP地址和語音編解碼方式等。將網(wǎng)線和話筒線連至網(wǎng)口和RJ11接口,撥通IP地址為192.168.0.1主機(jī)的電話,看看電話手柄的聽筒內(nèi)將能夠聽到話筒MIC所收集的話音。如果話音正確,則表明底層的功能已實現(xiàn)。
基于IXP421的網(wǎng)絡(luò)語音平臺方案實現(xiàn)了底層的相關(guān)功能,而上層的應(yīng)用較為靈活,且有很強的擴(kuò)展性,例如實現(xiàn)VPN功能及多媒體業(yè)務(wù),還需要開發(fā)相應(yīng)的軟件,本文并未涉及到。隨著網(wǎng)絡(luò)語音相關(guān)技術(shù)的逐步走向成熟,相信會有越來越多的人因之受益。