$1 前言
CWMP (TR-069) 的基本原則之一是 CPE Client永遠是聯線的發起者,但ACS依然有許多 TR-069 連接請求,CPE收到之後,開始會話。這通常在ACS有事的時候,必須立即聯繫 CPE 時使用,例如ACS系統想要將一個新的服務,導入到設備上的時候,通常要主動發起連線。
TR069標準文件中的Annex K中,定義了讓ACS使用XMPP來啟動與Device連線的方法。
$1.1 STUN的使用
在最初設計CWMP的時候,主要執行於客戶端的Gateway。由於這些設備可直接在 Internet 上擁有合法的的IP地址,因此如果讓設備提供一個公開可訪問的 URL,ACS便可以輕易的發出請求(Request),如此便輕易的將TR-069 連接請求傳送到網路設備。
基本的連接請求是通過HTTP GET 方法對CPE 指定的URL 完成的(這個URL 需要在每個Inform 訊息(Message)中發送給ACS,以便ACS 始終知道當前的URL 是什麼)。成功後,設備使用Inform 方法的事件列表中的6 CONNECTION REQUEST事件啟動 CWMP 會話。
然而,隨著越來越多的設備可以通過 TR-069 進行管理,位於Gateway後面的裝置越來越多,這些裝置要透過NAT Mapping,才能提供一個可以連接URL。
TR-069 的 Annex G文件中,定義了一種使用 STUN (Session Traversal Utilities for NAT)協議的方法,以允許這些NAT之後的設備,通過網關接受 HTTP GET 請求。
但STUN 並不是最好的解決方案。最大的問題是STUN使用 UDP,ACS並不能保證它的Request可以到達Device。
$1.2使用來XMPP 來繞過 NAT
隨著更新協議的出現,Broadband Forum的TR-069 開發人員開始使用(XMPP: eXtensible Messaging and Presence Protocol ) 建立一個 Message Bus,以允許發生連接請求可以隨時發生。並在Annex K of TR-069 Amendment 5中進行了完整的定義。
要使用此功能,CPE必須支援CWMP Data Model 的 XMPPBasic:1 和 XMPPConnReq:1 profile。
詳細的定義請參考以下連結:https://cwmp-data-models.broadband-forum.org/tr-157-1-8-0.html#R.TR-069a5
在解釋如何工作之前,先要對XMP的工作與訊息傳遞格式,作一些基礎性的說明。
$2. XMPP名詞解釋
$2.1 JabberID : XMPP的識別位址寫法
簡稱JID(Jabber Identifier or JabberID)。JabberID由三個主要元素構成。node、domain、resource。格式與e-Mail類似,為 user@domain/resource
常見樣子如下: alex@example.com/home
下面是一個例子:t004@of3/663f243
|
格式
|
意義
|
說明
|
|
t004
|
node
|
node就是帳戶名稱。在Query的時候,也可以是聊天室。
|
|
Of3
|
Domain
|
domain在JabberID中大部分指的是伺服器名稱,有時我們也會寫成短名稱如of3.xmpp.tti.tv只寫 of3
|
|
663f243
|
Resource
|
在JabberID中的resource部分,大部分時候它代表XMPP
Client端連線的識別,每個連線的client會賦予唯一的resource作為識別。
|
$2.1 XML stream 與 XML stanza。
由stream內包含不同作用的stanzas區塊,不同區塊標籤,有不同功能作用。Stanzas 區塊有 <presence />、<message />、<iq />或 三個區塊,麻煩參考一下的例子:

在XMPP的Client <-> Server, Server<-> Server之間,透過傳送與接收不同的XMPP stanzas,達成各種不同任務。
以上圖為例,t002用戶,建立了一個XMPP stream,送出<stream:stream>標籤。
第一個標籤<iq>,要求t002的roster (聯絡人或中文翻為好友清單)。
接著傳送<presence>,告知伺服器他目前是online,且是avaiable。
接著傳送<message>,給t004送了一封短訊。
然後再以<presence>,知會伺服器,t002已經unavaiable。
最後以<stream:stream>結束關閉這段通信。
下面簡單的看一下這三個XML stanza。
三個XMPP stanzas有一些共通屬性元素。
id:<presence/>、<message/>、<iq/>都可以有這個屬性,但通常多見於<iq/>,因為對於<iq />而言,它是必要屬性。而其他為非必要屬性。其最大用處在於辨識傳送接收雙方stanza的對應,以免答非所問。
from:訊息發送來源,他的屬性(Type)是由SERVER端提供。
to: 訊息發送目標
type:在三個不同的stanzas中,會有不同值。
$2.1.1 <iq />
<iq />在 http://xmpp.org/rfcs/rfc6120.html#stanzas-semantics-iq 8.2.3 有詳細值列表定義。Iq是Info/Query的縮寫,包含 from/to/id/type。
<iq /> 表示Info/Query,使用<iq />必然是有問有答,這可以為XMPP通信提供一個比較可靠的請求與回應機制,類似於GET/POST/PUT方法。IQ只能包含一個payload。
IQ中包含有id Type,用於識別伺服器發回的回應。
|
type
|
說明
|
|
get
|
用於請求資訊,類似於HTTP Get
|
|
set
|
提供資訊或請求,類似於HTTP
POST/PUT
|
|
result
|
回應請求,類似於HTTP 200
|
|
error
|
錯誤資訊
|
面有一個例子,發送取得Contact List 的需求:
<iq from=alice@wonderland.lit/pda id="rr82a1z7" to=alice@wonderland.lit type="get">
<query xmlns="jabber:iq:roster"/>
</iq>
XMPP伺服器返回Contact List
<iq from=alice@wonderland.lit id="rr82a1z7" to=alice@wonderland.lit/pda type="result">
<query xmlns="jabber:iq:roster">
<item jid="whiterabbit@wonderland.lit"/>
<item jid="lory@wonderland.lit"/>
<item jid="mouse@wonderland.lit"/>
<item jid="sister@realworld.lit"/>
</query>
</iq>
Client新增一個連絡人jid="madhatter@wonderland.lit"
<iq from=alice@wonderland.lit/pda id="ru761vd7" to=alice@wonderland.lit type="set">
<query xmlns="jabber:iq:roster">
<item jid="madhatter@wonderland.lit"/>
</query>
</iq>
伺服器回應說OK
<iq from=alice@wonderland.lit id="ru761vd7" to=alice@wonderland.lit/pda type="result"/>
$2.1.2 <presence />
<presence />值定義在 http://xmpp.org/rfcs/rfc3921.html 的 2.2.1 有詳細定義。
Type= Unavailable/subscribe/subscribed/unsubscribe/unsubscribed/probe/error
<presence />是用來說明Device的可訪問性。用戶發出<presence />,表明自己上線。但是我們也不用擔心任何人都可以看到自己的線上狀態,除非我們訂閱了該使用者的狀態,訂閱之後,使用者的狀態資訊會自動發送到訂閱者處。
<presence /> 也提供subscribe/subscribed/unsubscribe/unsubscribed。意思是訂閱或是不要訂閱。
當USER設定自己是<presence />之後,如果其他使用者訂閱(subscribe)了該使用者的狀態,使用者的上線或離線狀態資訊,會自動發送到訂閱者處。
<iq type=’get’>
<query xmlns=’jabber:iq:roster’ /> //Get Client的Contact List(術語就是roster)
</iq>
<presence/> //通知伺服器,Client已線上並隨時可以接收訊息
在一個XMPP連線之中,一開始大部分用上述的stanza來開頭,這時候<iq /> 發送之後,系統會回應一堆的JID Contact List,以及Client與這些JID的訂閱關係。接下來Client發送presence節,通知自己線上,以及已經得到連絡人的狀態資訊。
$2.1.3 < message />
<message />值定義在 http://xmpp.org/rfcs/rfc3921.html 的 2.1.1 有詳細值列表定義。type包含 chat/error/groupchat/headline/normal
用於從一個Client向另外一個Client發送消息,並可以傳輸任何類型的結構化資訊(XML),不保證傳輸可靠性。
• CPE 必須能夠與 XMPP Server建立安全,且經過身份驗證的連接。
• 由於CPE保持與XMPP Server的連接,XMPP Server可以從ACS隨時發送一組來自與”允許地址”、未經請求的訊息(Message)給XMPP Server,XMPP Server 再發送給CPE。
Annex K之中,定義了要使用XMPP ( RFC 6120)發送的一組基於XMPP 的ConnectionRequests (TR069 3.2.2 節)的特定訊息(Message)。流程如下:
逐步說明如下
(1) ACS 與 XMPP Server 建立連接
前面已經大致上描述了下圖的架構:
ACS 想要用HTTP 發ConnectionRequests給CPE,但是通常CPE都在Gateway的後面,被NAT或防火牆給擋住了。為了解決這個問題,TR-069 Annex K 定義了一種通過 XMPP Server執行連接請求的方法。
ACS作為系統端服務,自己當然要先與XMPP Server隨時保持連線。第一步就ACS與XMPP Server要建立連線。
ACS通過配置XMPP.Connection object與ManagementServer Object 的ConnReqXMPPConnection 參數,來連接XMPP SERVER,提供CPE的XMPP連線。
XMPP.Connection object,可選擇性的使用 ManagementServer Object 的ConnReq AllowedJabberIDs參數,其中明訂Jabber ID列表,來表中的CPE可以發動XMPP連接請求。
當XMPP連接請求發送到CPE時,XMPP IQ Stanza將包含一個”from”地址,其中包含發起實體的Jabber ID。
此參數是一個逗號分隔的字符串列表(最多32個項目,最大項目長度256)。每個條目代表一個Jabber ID或地址,允許發起XMPP連接請求。
每個 Jabber ID 都可以是”Full JID” (包含以下格式的local-part @ domain-part / resource-part)或”Bare JID” (local-part@domain-part)。
具例如下:如果ConnReqAllowedJabberID包含”ACS1@tr069.example.com, ACS2@tr-069.example.com/resource1”,將允許以下JID傳入:
“ACS1@tr069.example.com/resource1”
“ACS1@tr069.example.com/resource2”
“ACS2@tr069.example.com/resource1”
並且不允許以下JID傳入:
“ACS2@tr069.example.com/resource2”
“ACS@tr069.example.com/resource”
如果此參數為空字串,則允許所有Jabber ID連接。並且XMPP連接請求不會因”from”地址而被視為無效。詳細的物件資訊可參考一下連結:
https://cwmp-data-models.broadband-forum.org/tr-157-1-8-0.html#D.TR-157:1.ManagementServer.
(2) ACS通過配置XMPP使能在Device中使用XMPP
基本上一定是CPE對ACS來啟動連接一個連線作業。這算是一個標準的啟動程序:
CPE -> ACS : Inform (0 BOOTSTRAP or 1 BOOT)
ACS -> CPE:InformResponse
CPE -> ACS:Empty HTTP POST
ACS -> CPE:SetParameterValues
CPE -> ACS:SetParameterValuesResponse
ACS -> CPE:HTTP204
這時候由於是CPE主動找ACS,所以完全沒有NAT與防火牆的問題。這時候ACS告訴CPE如何連接XMPP Server的資訊。
ACS要將以下資訊通知CPE,這上圖中是使用SetParameterValues,但也可以使用AddObject:
- 使用XMPP.Connection Object的ManagementServer參數通知CPE。
- 選擇性的使用ManagementServer Object來設定SERVER接受的Jabber ID。
當然如果CPE在預設值中,先設定了以上的XMPP連接值,則可以省略此步驟。
A.下圖是描述ACS與CPE之間使用AddObject來傳送:
ACS想要對CPE啟動XMPP Connection Request,ACS首先在CPE’s XMPP interface object中建構一個新的XMPP.Connection object。ParameterKey為ACS提供了一種可靠且可擴展的方法來處理接下ACS所做的更新。這裡的ParameterKey 值,在接下的動作,例如SetParameterValues、AddObject或DeleteObject等都要使用這個唯一ParameterKey參數值作為識別。CPE在Factoory Reset時,ParameterKey的值必須設置為空字符串。
B. 除了用AddObject之外,也可以用SetParameterValues。
這裡是透過Device的data model 中ManagementServer object 的ConnReqXMPPConnection parameter來告訴CPE需要連線的Path Name。位於<Value>當中的 Device.XMPP.Connection.1
透過這個CWMP呼叫,CPE就知道XMPP Server的路徑在哪裡了。接下來ACS還要告訴Devices連線用的 JabberID。
利用以上這個SetParameterValues,Devices就知道自己的
JabberID = acs@provider.com/resource1
Question: 如何知道是 “resource1” ?
ACS可以在ConnReqAllowedJabberID 參數中,設定允許連接的 JabberID。ACS在之後的XMPP message中使用的”from” ID必須與這些JabberID之一匹配才能被CPE接受。
如果CPE已經被Connection Requests設定了一個 XMPP Server,則可以省略此步驟。
(3) Establish Connection to XMPP Server
ACS與XMPP Server建立一個Secure XML Stream。CPE與XMPP Server也建立一個Secure XML Stream。接下來Device連接到XMPP Server,可以用前面得到的JabberID來建立與ACS Server連接。
CPE會在ConReqJabberID參數中,列出了它的Jabber ID,並且必須確保與 XMPP.Connection object中的JabberID參數匹配。此參數預設為主動通知 (Active Notification),因此ACS可以在不同的session中,學習它或使用GetParameterValues 請求它。
當連線建立之後,ACS可以使用 XMPP 與CPE 進行”Chat”,並向CPE發送 XMPP連接請求。
此 XMPP 連接請求包含一個 XMPP IQ stanza ,其中包含分配給 CPE 的連接請求用戶名和連接請求密碼的元素。
一旦發送,CPE 用一個空的 XMPP IQ stanza 確認請求。
一旦成功,CPE 就開始與當前在 ManagementServer.URL 參數中分配的 ACS 的 CWMP 會話。CWMP 然後照常繼續。
如果出現問題,或者 CPE 正在處理類似於 HTTP 連接請求中描述的過多請求,CPE 可以發送帶有適當錯誤類型元素的 IQ 節。
如果 XMPP 連接請求不能被認證,CPE 使用“未授權”錯誤代碼。
4. XMPP IQ (Connect Request):ACS -> XMPP Server
每當ACS希望與CPE建立連接時,它可以發送XMPP連接請求(包含連接請求訊息(Message)的XMPP IQ節到其XMPP Server,指定與連接請求需要的 CPE 匹配的”to”地址和一個與允許的Jabber ID之一匹配的”發件人”地址 - 有關詳細信息,請參閱K.2.2.2)到XMPP Server。
5. XMPP IQ (Connect Request):XMPP Server-> Client (Device)
XMPP Server轉發給Client
6. XMPP OQ (Connection Request ACK) : Client(Device) -> XMPP Server
7. XMPP OQ (Connection Request ACK) : XMPP Server -> ACS
XMPP Server將 XMPP IQ 節發送到適當的設備。
8. Inform (6 COOECTION REQUEST)
當XMPP完成到上一步(7)時,CPE便像原先一樣,通過 HTTP 發起與 ACS 的 CWMP 對話,Device向其 anagementServer.URL 參數中指定的 ACS 發出通知請求。由於ACS通過XMPP向CPE傳遞連接請求,因此通過NAT的時候,無需擔心網路地址轉換。
注:XMPP 連接請求機制通常被描述為使用單個 XMPP Server,但根據部署可能有多個 XMPP Server。一些示例是部署具有多個集群在一起的 XMPP Server的單個域,或者部署多個域,其中每個域由一組 XMPP Server組成,並且它們都可以相互通信。
ACS先與XMPP Server建立連接,然後用 TR-069 通知 CPE 可以使用此 XMPP Server來進行其連接請求。然後,CPE 與XMPP Server建立安全連接。從那時起,ACS 可以通過 XMPP Server向 CPE 的Jabber ID 傳送連接請求。此連接請求只是一個 XMPP IQ Stanza ,其中包含一個到其 XMPP Server的連接請求訊息(Message),指定與需要發送連接請求的 CPE 匹配的“to”地址和與允許的 Jabber ID 之一匹配的“from”地址。
沒有留言:
張貼留言