Yate教程1

From:http://yate.null.ro/pmwiki/index.php?n=Main.CppTutorial1

 

Yate可分爲兩個部分
    * Yate內核
    * Yate模塊

    *Yate內核提供基礎,輔助API以及消息系統
    *Yate模塊使用Yate內核實現特定的功能

Yate模塊的類型
Yate模塊可分爲一下幾種
    1.通道
    2.路由器
    3.電話歷史記錄(Call Detail Recorder)
    4.計費程序
    5.其他模塊

如何指定模塊的類型
模塊類型在這裏涉及許多概念性的東西。Yate的設計中並不區分模塊的種類,而是根據模塊處理的消息類型來區分模塊類型。例如一個通道模塊接受call.execute消息,並創建一個通道來接受處理它。有此特徵的模塊我們稱之通道模塊。另一方面即使如果模塊可能接受call.execute消息並處理一個事情,但並不創建一個通道/終端,則它不是一個通道模塊。CDRBuilder就是這樣的模塊。如果你還不清楚,稍等,接下來的例子會說明清楚。

 

程序員眼裏的消息
  消息應正確派發到註冊了並在監聽該消息的模塊中。模塊可以指定接受消息的優先級。如果一模塊監聽的call.execute消息優先級爲50,其他模塊也在監聽call.execute消息,但優先級值大於50,則該模塊應該先於其他模塊獲取call.execute消息。一旦接收到該消息,模塊可向派發器返回true或fale,並附帶一些額外信息。如果返回true,則派發器停止向後續的模塊發送消息。返回false,則允許消息按照優先級繼續派發到其他模塊中。 

  Yate消息不會同Windows消息相混淆,因爲他只在Yate系統範圍內發送而沒有使用操作系統機制發送消息。此外,Yate消息構造是以字符串定義的,而OS消息使用的是數值。

TelEngine命名空間
    所有的Yate API都什麼在TelEngine命名空間中,命名空間是C++的一個概念,用於減少程序中變量名和函數名重名衝突。因此,要使
用命名空間TelEngine,如不想寫TelEngine::blahblah,你可以使用:

 

我們的第一個模塊
  我們現在開始寫我們的第一個模塊,可以接受call.execute消息,並將其呼叫和被叫的號碼輸出到控制檯中。我們設模塊名爲mymodule1.ln。在這個模塊中我們需要討論以下幾個類。
    *Module
    *Message
    *MessageReceiver
    *String
同樣還得介紹call.route


CPP文件準備
我們需在模塊目錄下創建一個名爲mymodule1.cpp的文件
包含telengine.h文件則可使用YATE的API

第一步--模塊代碼
和前面解釋的一樣,Yate模塊要申明他是一個Yate模塊都需從Module類派生。Module是從多個類派生的。在Yate API繼承關係如下:

 



注意Plugin類向Yate提供了加載模塊的功能
在我們的模塊中聲明類如下:

 

 

第二步:創建Module類的靜態變量
當Yate模塊加載一個模塊是,他首先會在模塊中(Plugin)查找名爲_plugin的靜態變量。在我們的例子中,我們需要定義類MyModule(派生於Plugin)的一個靜態變量。Yate提供了幫助做這個,僅需要這樣使用:

 

第三步:模塊initialize()的重要性
你需特別注意到我們在MyModule聲明定義的initialize方法。initialize函數在Plugin類是虛函數,在Yate加載模塊時會被調用。MyModule需要重載它,做一些模塊初始化工作。通常在這裏註冊模塊想監聽的消息。我們可這樣寫代碼:

Yate提供的Output函數輸出信息到控制檯。它只在必要的時候使用。Yate同樣提供了一些其他API函數將調試信息輸出到控制檯。

第四步:添加代碼接受消息
模塊通常需要接受一個或多個消息。模塊接受到一個消息並執行程序制度的工作。Module類派生與MessageReceiver,MessageReceiver通過虛函數received()提供了接受消息能力。我們可按自己愛好添加代碼接受消息,像這樣:

 

Yate中的類Engine。Yate創建了一個Engine的靜態對象作爲他(Yate)的啓動(不是模塊的啓動)。這個類啓動真個Yate的服務器/服務。這個類全是靜態成員函數。Install()同樣是靜態函數,這也就是我們爲什麼Engine::install這樣調用的原因。install向yate提供了我們的MessageRelay類對象,指定了我們想要監聽消息的消息id、監聽優先級等。第三個參數CallRoute是枚舉值,它僅指定我們想關聯消息的消息ID。枚舉值CallRoute爲Private+1,在類Module中定義,用於指定(說明)該消息在模塊中沒有任何RelayID。可看看Yate中Module類的枚舉值。當你監聽到多個消息,你需要識別監聽到的消息,當然這有多種方式實現。注意在MessageRelay的最好一個參數值爲55,這說明我們想監聽的消息優先級別值爲55。因此如果其他模塊也在監聽同樣的消息且優先級更高,將先接收到這個消息並且如果他返回非ture,我們的這個模塊才能接受到這個消息。MessageRelay被Yate用例發送消息,它的構造函數擁有一個MessageReceiver類的對象用戶消息的通知。我們MyModule繼承於Module,而Module繼承於MessageReceiver,因此,我們在MyModule可提供這個對象(MessageReceiver)。

第五步:重載received

類MessageReceiver的received(Message &msg,int id)方法由Yate調用,用於派發註冊過監聽的消息。received在MessageReceiver中聲明爲虛函數。注意,返回值爲bool,如果處理完這個消息,並不想後面的模塊接受處理該消息,返回true。希望後續的模塊繼續處理該消息返回false即可。這裏(received)我們可以添加自己的邏輯代碼。在received中我們可寫一些代碼,在call.route消息來臨時,輸出呼叫者和被呼叫者名。

 


上述代碼使用了Yate API提供的String類。從名可知這個類提供了字符串的相關操作。Message繼承與NamedList,這是YATE提供的另一個類,用於更好管理字符串與字符串直接的映射鏈表。類NamedList的函數getValue(),我們先獲取被叫號碼(熟知的DNID),然後獲取呼叫者的號碼,作爲電信運營商的ANI/CLI(被叫者ID/呼叫者ID)。c_str爲String的成員函數,返回字符串存儲的數據,類型爲const char*.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章