2020年7月25日 星期六

PRPL的Easy Mesh(一): 系統架構簡介

prplMesh 是Wi-Fi聯盟內定支援的開源 (Open Source)實作,所以如果要通過 Easy Mesh 1.0的認證,最好就是直接移植這個平台。平台的原始碼主要來自於Intel的貢獻,目前依然由Intel做為主力,持續開發當中。

以下共有六組開源程式在  https://github.com/prplfoundation 共有六個目錄
  • prplMesh-manifest:
    • 起始點,一些文件,還有未來將要開發的一些東西。
  • prplMesh framework:
    • Local message bus (IPC機制), 包含一堆服務的介面: platform, transport, management, topology, logging, CAPI:
  • prplMesh-common libraries (工具的基礎程式庫)
    • TLV factory, controller management, platform, WLAN, plugins
  • prplMesh-agent:
    • Agent程式碼,內部與廠商程式供通用的API與介面(TLV/CMDUs)。
  • prplMesh-controller:
    • 資料庫、控制器上執行的微工具(Micro-service task pool):例如band-steering, mobility, channel-selection, network map, 統計資訊(stats),...等等。
  • prplMesh-tools:
    • Build Code的工具、安裝程式、klocwork static code analysis, 等等。
基本上,我想分為幾個部分來寫,這一篇是簡單先看一下系統的架構,之後就依照功能的分類,做細部的介紹。

先看一下下面的圖好了,這張圖其實把prplMESH的程式架構寫得很清楚:


Easy Mesh的架構稱之為Multi-AP,就是家裡面會有好幾個Wi-Fi Access Point,這些系統概分為三個角色:
  • Multi-AP Framework
  • Controller
  • Agent
Framework與Controller都常是合在一起的執行的。或是合稱為Controller也沒有關係,但是因為Framework的架構很大,為了討論方便所以單獨拿出來成為一個大的模組。

基本上只會有一個Controller,但是每一台的Access Point上面都會有Agent來執行。Controller與Agent可以在同一台設備上,也可以在不同的設備上。習慣上,會在最靠近Router的那台裝置上執行Controller,但也有人建議是在效能最好的那台來執行Controller。

prplMesh 具有極佳的移植性,所以她建立了一些API,廠商只要把API搞定,基本上,移植工作就完成了。上圖之中有用黃色標出來的就是這些移植用的API。

哈!哈!這裡用了一些SDN的術語:
  • 南向系統介面 (Southbound API):Mesh 與 Infrastructure Layer 溝通的介面,簡單說就是Mesh與作業系統連接的API。
  • 北向系統介面 (Northbound API):這是 Framework 與 Controller連接的介面。
  • 西向系統介面(Westbound API):Framework與作業系統連接的API。
當然大部分的Wi-Fi AP都是建立在Linux系統之上,所以最底層與Linux連接的部份是Wi-Fi Driver(nl80211)與Ethernet Driver,連接的API幾乎都是用標準的Socket。

此外,Agent 在 Wi-Fi 上的操作,依然是使用 Linux 平台上標準的 hostapd 與 wpa_supplicant。

如果畫成傳統的Layer的架構,可以變成以下的圖形:


上圖就大架構而言,也許清楚了一些。上圖當中,Distribution Management主要是系統更新用的。Platform就是與作業系統有關係的API。其他兩個粉紅色的是Daemon。這都是廠商需要提供的。

在Multi-AP的方塊當中,有兩塊叫做1905.1的模組,可能各位看倌比較陌生,下面簡單介紹一下。

1905.1是IEEE訂立的標準,主要在家庭網路當中,不同的網路實體層可以透過一個標準的Protocol 來交換訊息。

1905.1沒有改變任何底層網路協定的行為或是實作方式,所以可以與現有的TCP/IP網路相容。

1905.1主要的標準,是裝置與裝置之間使用CMDU(Control Message Data Unit)交換資訊。CMDU定義了一些標準的訊息類型,例如Topology Discovery Message、Topology Notification Message、Topology Query Message、Topology Response Message、Link Metric Query Message、Link Metric Response Message等等。

訊息只是包裝成簡單的TLV(Type Length Value)格式來傳送,因此程式處理起來也非常簡單。

1905.1在MESH上面,提供兩個主要的應用:
  • 讓裝置利用群播(Multicast)的方式,建立家庭網路中,個裝置的網路拓撲邏輯(Network Topology),以及通知網路拓撲的改變(如有新的網路裝置增加,或是既有的網路裝置離線)。
  • 利用單一傳播(Unicast)方式,詢問鄰近裝置的狀態,例如鄰近裝置底下有幾個網路介面、網路介面的類型等資訊,也包含了底層彼此相連的網路介面連結狀態(Link State),如遺失封包的數量、傳輸封包的數量等。
看完上面的簡單的說明,簡單來說,如果具備以下幾樣東西,Easy Mesh的功能就已經差不多了:

-  IEEE 1905.1:用來在手機上面畫出拓樸圖,如果改變,也要改變,還有一些統計資料。
-  IEEE 802.11k, 802.11r、802.11v

另外一個好消息是Intel把他開發多年,原先想在物聯網上的大撈一票的,但希望始終是失望的雞肋產品:1905.1 原始碼給捐了出來。所以Framework當中最重要的拼圖就補齊了。

看到這裡,會不會有信心大增的感覺,其實這得不複雜,也不神祕,對吧!!! 接下來,就把需要界接的API,都在Layer的架構圖上,給他標示出來。



這張圖,如果上面的說明都有仔細看,紫色的縮寫就是這個連接用的API,也大致上可以看出這些API的功能。其中BML=BeeRocks Management Library當中,有一個奇怪的字"BeeRocks";前面不是有說,這程式是Intel捐出來的嗎! "BeeRocks" 就是 Intel 捐出平台的Code Name (中文可以叫做外號暱稱)。沒有甚麼特別的意思。"BeeRocks" 這字在程式的相關文件當中,出現的頻率可是蠻高的。


"BeeRocks" 原始來源是德國的餡餅,有包肉,也有包蘋果派。據說是先傳到阿根廷,再傳到美國。有人說俄羅斯傳到東歐,再傳美國的;在往前推,餡餅是漢朝就有的食物,蒙古人傳俄羅斯的。

接下來,用另外一個畫法說明一下三個大模組當中程式元件的關係。



這張圖是解釋Agent的大致運作,每台機器都會有一個Agent程式主控全場。此外每個Wi-Fi卡片都會有一個Radio Agent來對Wi-Fi AP做控制。

接下來是Controller的架構圖:


Controller由於需要紀錄的東西多,所以架構也複雜一些,同時有兩個小資料庫,記錄家庭網路中的一切資訊。基本上,手機的管控介面也是與這裡來連線做溝通。

接下來,就繼續依照以下的四個部份,做深入的探討:
- Framework
- Agent
- Controller
- User Interface


2020年7月18日 星期六

TR-069 初釋(續)

這是接續前篇的 TR-069 初釋  的文章,前面一定要看,不然會看不下去。

前面大致上已經交代過 TR-069、ACS與CPE之前是如何工作的? 同時也看過了 ACS 如何知道 CPE 有哪些參數可以提供的。所以這篇就要看如何讀取或設定這些參數。

四、ACS讀取CPE的資訊(GetParameterValues)

前面看過的是GetParameterNames,現在要看GetParameterValues,就是要讀出參數的值。先看例子,這是CPE對ACS的回應:

<soap:Body>
    <cwmp:GetParameterValuesResponse>
          <ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[1]">
                    <ParameterValueStruct>
                            <Name>Device.ManagementServer.URL</Name>
                            <Value xsi:type="xsd:string">http://someacs.tr69.com:9999/acs/</Value>
                    </ParameterValueStruct>
            </ParameterList>
        </cwmp:GetParameterValuesResponse>
</soap:Body>

CPE 要依照ACS要求的參數值,回傳Name/Value的對子給ACS。對子可以是完整(complete)、非完整(partial)或是混合的形式。

五、ACS設定CPE中的資訊 (SetParameterValues)

ACS用來對於設定CPE的參數。永遠都是完整路徑(Complete Path),ACS 發送設定如下:

<soap:Body>
    <cwmp:SetParameterValues>
        <ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[1]">
            <ParameterValueStruct>
                <Name>Device.ManagementServer.URL</Name>
                <Value xsi:type="xsd:string">http://someacs.tr69.com:9999/acs/</Value>
            </ParameterValueStruct>
        </ParameterList>
    </cwmp:SetParameterValuesResponse>
</soap:Body>

CPE 回應設定成功: 

<soap:Body>
    <cwmp:SetParameterValuesResponse>
         <Status>0</Status>
    </cwmp:SetParameterValuesResponse>
</soap:Body>

這裡回傳的Status Tag,在很多CPE回應ACS的呼叫當中 (諸如SetParameterValues, AddObject, DeleteObject與 Download) ,CPE Response的時候,都會用到“Status”這個參數。 

<Status> = “0”  代表說改變將會立刻被執行。
Status如果是“1”代表說改變將會在CPE重新啟動之後,才會被執行生效。注意這裡,如果是Reboot才會生效,代表沒有Reboot,設定就會不會生效。所以CPE與ACS之間,最好透過Status做溝通,ACS要決定CPE要不要立刻Reboot。例如設定完成之後,如果CPE回應"1",ACS也許要發送"Rebbot"命令給CPE。

六、GetParameterAttributes與SetParameterAttributes

CWMP 的GetParameterAttributes/SetParameterAttributes都可以有兩個XML屬性(attributes):Notification 與 Access List。
 
SetParameterAttributes RPC用來設定參數,有五個參數,包含:
  • Name :可以是完整路徑(Complete Path)或部分路徑(Partial Path)。
  • NotificationChange
  • Notification
  • AccessListChange
  • AccessList
直接看一下例子:

ACS 發送設定如下:

<soap:Body>
    <cwmp:SetParameterAttributes>
        <ParameterList soap-enc:arrayType="cwmp:SetParameterAttributes[1]">
            <SetParameterAttributesStruct>
                    <Name>Device.WiFi.SSID.2.Name</Name>
                    <NotificationChange></NotificationChange>
                    <Notification></Notification>
                    <AccessListChange></AccessListChange>
                    <AccessList soap-enc:arrayType="cwmp:string[0]"></AccessList>
            </SetParameterAttributesStruct>
        </ParameterList>
    </cwmp:SetParameterAttributes>
</soap:Body>

SetParameterAttributes RPC帶有5個參數。第一個是”NAME”,包含參數路徑,與GetParameterNames一樣,它可以是完整路徑(Complete Path)或部分路徑(Partial Path)。SetParameterAttributes中的Partial Path通常用於設置被動通知(Passive Notification)或刪除通知”Removing Notification)。如果裝置數量太多,又去設定Active Notification可能很危險,因此很多參數都會設成“canDeny”,意味著這些參數將會拒絕被設定為“Active Notification”,就是說設Active也沒有用。

接下來的參數是NotificationChange和Notification。 NotificationChange為true表示CPE應將Notification參數中的值進行設定;如果為false,則應該忽略Notification中的值。

“Notification”用於設定參數的通知規則。它是0到6的數字。0到2是基本通知機制,3到6是“輕量”通知。在TR-069中,當通過ACS以外的任何機制,更改用於通知的參數集時,將使用“4 VALUE CHANGE” 的事件代碼(Event code)。這些條件將使用SetParameterAttributes RPC來進行設置。

0到的基本通知機制,代表Active (2), Passive (1), or None (0)三個通知機制。說明如下:

0: 設定參數為None,“No” notification會移除任何之前所有通知設定,可以拒絕或忽略之前發出的“Forced Active”參數。後面還有詳細的討論。

1.設定參數為 Passive (被動):為“Passive”通知設置參數意味著,如果參數值更改,則CPE必須在其下一個通知ACS的RPC中,包括4 VALUE CHANGE事件和更改的參數值。它不會立即啟動連接,而是會在下一個最方便的時間(例如在定期通知期間或在連接請求之後)發送通知。

設置“Passive”(被動)通知,並不會拒絕任何參數,但是,對於為“Forced Inform(強制通知)” 或 “Forced Actiive(強制主動)”通知設置的參數,可以將其忽略。

2.設定參數為 Active (主動): 為“Active”通知設置參數意味著,如果參數值更改,則CPE必須立即啟動CWMP對話,以將更改通知ACS,包括4 VALUE CHANGE事件代碼和參數值,透過RPC通知CPE。根據CPE端的判斷,對於瞬態或經常更改的參數,可以拒絕激活通知的設置。例如,在“Uptime”參數上,設置”Active”通知,由於Uptime會不斷變化,將會導致無休止的CWMP會話!

這些參數不能更改或具有預設值的特性。在Data Model中定義的這些包括“Forced Inform”, “Forced Active”, 與 “Default Active” notification。
- ”Forced Inform”:參數是每個Inform RPC中,必須包含的參數。
- “Forced Active”:強制啟動通知參數,必須設定為”Active”通知,否則應忽略請求。
- “Default Active”:強制將屬性設為出廠時的預設值。

下兩個參數是AccessListChange和AccessList屬性。 AccessListChange具有與NotificationChange相同的目的。 CPE必須僅了解AccessList的“ Subscriber”的值,但是無論ACS設置了什麼,它都必須存儲該值。

CPE對於SetParameterAttributes Response 不包含任何參數。

GetParameterAttributes RPC非常簡單,並且像GetParameterValues一樣採用類似的ParameterNames參數。 GetParameterValuesResponse包含ParameterAttributeStruct對象的ParameterList數組,其中包括參數的名稱及其Notification和AccessList的值。

七、AddObject/DeleteObject

這個功能其實有些難以理解,雖然也找到例子,但還是不懂要如何運作? 我先隨便寫寫,以後如果弄得更清楚的時候,再來修改。

CPE數據模型中的“Object”是可以由ACS配置的功能性元素。使用SetParameterValues RPC配置對象的參數時,ACS可以使用AddObject RPC來創建一個Object到CPE中,並使用DeleteObject RPC將其刪除。

AddObject

下面是ACS發出AddObject的例子:

<soapenv:Body>
<cwmp:AddObject>
<ObjectName>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.</ObjectName>
<ParameterKey>3544041</ParameterKey>
</cwmp:AddObject>
</soapenv:Body>

AddObject RPC具有兩個參數。第一個是Object名稱(Name),它必須包含一個Object的路徑;那是一個以“點”作為結尾的路徑。該Object自然必須是可以在CPE之中被創建的,並且在Data Model當中,已經開啟了允許寫入的權力。如果不是,則AddObject的要求,CPE會回應這是一個無效參數(Invalid Arguments)或無效參數名稱錯誤(Invalid Parameter Name error)。

就像SetParameterValues中一樣,第二個參數是ParameterKey,用於將此RPC與ACS內部關聯的策略相關聯。CPE收到此值後,必須要更新CPE中Device.ManagementServer.ParameterKey的值。

當Object創建時,所有相關的參數都必須設置為預設值。如果無法完成此操作,則AddObject RPC必須失敗。

下面是CPE的回應例子:

<SOAP-ENV:Body SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<cwmp:AddObjectResponse>
<InstanceNumber>4</InstanceNumber>
<Status>0</Status>
</cwmp:AddObjectResponse>
</SOAP-ENV:Body>

AddObjectResponse包含兩個參數。 InstanceNumber和Status。 

Status參數的操作與SetParamterValues中的操作相同。如果將其設置為0,則可以認為Object已被添加並已經生效。如果將其設置為1,則CPE需要執行一些其他操作才能完成更改(通常是CPE重新啟動)。

上面例子中Object會回應一個數字(上例中是"4")的InstanceNumber。這是一個unsigned Int,可以採用1到2 ^ 32-1之間的值。這數字用於標識Object,指定後該編號就無法再更改,並且在該類型的現有Object List中必須唯一。刪除Object後,新的Object不應使用先前分配的標識符號。

DeleteObject 

DeleteObject RPC使用與AddObject相同的兩個參數。但是,ObjectName中的參數路徑必須以特定的實例標識符結尾,後面用“點”來結尾。這表示要刪除的特定對象。

DeleteObjectResponse只有一個參數”Status”,使用方式與前面的規則類似。

八、Reboot

ACS使用Reboot RPC來要求CPE重新啟動。

Reboot RPC僅使用一個參數 CommandKey。 該CPE的回應則不包含任何參數。文件上說,基本上不應該強迫CPE升級軟體,又重新開機,但是在除錯的過程中,遠端重開機的確是常見的行為。

CPE重啟後,必須盡快啟動與ACS的對話(Session)。 該對話中的Inform RPC包含“1-BOOT” Event,還包含 “M Reboot” Event。 這告訴ACS會話是由於設備重新啟動,是由於ACS之前的Reboot要求而進行的(此重新啟動是由於ACS發出Reboot RPC所致)。

CPE開機後,所發出的訊息如下:

<soap:Body>
    <cwmp:Inform>
            <Event soap-enc:arrayType="cwmp:EventStruct[1]">
            <EventStruct>
                    <EventCode>1 BOOT</EventCode>
          </EventStruct>
           </Event>
           <EventStruct>
    <EventCode>M Reboot</EventCode>
<CommandKey>123456</CommandKey>
          </EventStruct>
    </cwmp:Inform>
</soap:Body>

ACS另外一個讓CPE進入可以完全控制的狀態的是用FactoryReset。 這是一個Optional的RPC,Response 沒有參數,應謹慎使用,因為“FactoryReset”不是一個明確定義的狀態,通常只能在已經完整測試過的環境中才能使用。

九、Download

ACS要求CPE進行一個下載 (download),通常是因為

1. 新版本的Firmware更新。
2.某一個檔案需要跟新,或是管理網頁需要更新。

ACS的命令可以要求立刻執行或是等一下再執行。

更新完成之後,CPE要用“M Download” and “7 TRANSFER COMPLETE” events,回應ACS。
CPE必須要更新完成之後,才能通知ACS。

十、Faults

如果失敗的話,SOAP要負責處理,所有的失敗原因編號,可以參考A.5 of TR-069a2的A.5。 
CPE的失敗代碼(fault codes)是9000系列。
ACS的失敗代碼(fault codes)是8000系列。

結尾

還有一些RPC我們沒有介紹:
  • Upload – triggers an upload by the CPE to a specified location
  • ScheduledInform – schedules a CWMP session for a particular time and triggers the “3 SCHEDULED” event
  • FactoryReset
  • GetAllQueuedTransfers – returns the current uploads/downloads waiting to complete
這大家可以自己找文件看一下;如果你有仔細看我這兩篇文章,再回頭看英文版本,應該就會非常清楚TR-069工作的原理。文件的位置在下面的URL,有了概念之後,再看這篇文章,真的不難。

https://www.broadband-forum.org/technical/download/TR-069_Amendment-5.pdf

此外,我也沒有介紹Data Model的部份。因為這部份的資料也是非常的多,但是就是把許多的CPE參數,依照不同的裝置特性,做了一個詳細的規範:

TR-098 Amendment 2 Internet Gateway Device Version 1.1 Data Model for TR-069 (2008)
TR-106 Amendment 7 Data Model Template for TR-069-Enabled Devices (2013)
TR-181i2a9 Device Data Model for TR-069 (2014)
TR-143 Enabling Network Throughput Performance Tests and Statistical Monitoring (2015)

暫時就寫到這裡了!!!















2020年7月4日 星期六

TR-069 初釋

零、一些專有名詞

雖然沒甚麼,但還是稍微說一下:
  • XML – The eXtensible Markup Language
  • SOAP – The “Simple Object Access Protocol”; 基本上是用XML來描述兩個網路程式之間的呼叫。 
  • CPE – Customer Premises Equipment的簡寫,基本上就是家裡使用的聯網設備的通稱。
  • ACS – Auto-Configuration Server, Server端軟體,用來管理CPE。
  • Data Model – 一組物件的定義,好在CPE與ACS之間傳送資料。基本是Broadband Forum所定義的,也有可以做一些廠商的擴充。
  •  RPC – Remote Procedure Call. 利用SOAP當參數,來在兩個裝置之間,做Function Call。

一、何謂TR-069

TR-069是Broadband Forum 定義的一組標準參數,任所有的家庭聯網裝置,都可以透過這個規定的協定,把一些裝置的資訊,送交給ACS SERVER來進行管理。

TR-069的通信協定稱之為 CWMP,下面這張圖是Broadband Forum畫的,描述TR-069想要做的事情:
CWMP 既然是網路的產品,那就要遵循七層的概念了。真是匠氣十足啊!


此外,這裡有許多的參考文件,其實這篇的來源,也是整理一下這些文件的內容:

TR-069: 最主要的CWMP協定說明:
- Currently Amendment 2, which is CWMPv1.1
- Defines protocol, message structure, session rules, and RPCs
- Annexes deal with NAT traversal and association of gateways to LAN devices

TR-106
-  XML Schema definition and common objects for Device Data Models

TR-098
- Device Data Model for Internet Gateway Devices

XML(eXtensible Markup Language)是TR-069的基本資訊傳送格式,XML透過SOAP,允許Client/Server的應用程式,利用RPC (Remote Procedure Calls)呼叫來傳送資料。

XML “Schema” 是一段特殊的XML用來描述格式 (.xsd),Schema 可以用 namespaces 來繼承上層的 Schema 定義。


上面圖中紫色的部分,就是繼承的namespace。

TR-069文件中的section A.6定義了RPC Schema。Data Models是 “schema-like” 的XML文件,依照TR069 定義的使用情境來描述物件與參數。TR-106之中,描述了CWMP Data Model Schema,通常可以在以下的檔案當中描述 cwmp-datamodel.xsd。

最新版是1.6.1,可以在以下https://cwmp-data-models.broadband-forum.org/之中找到。

下面有TR-143 : Data Model的例子 (Performance Test Objects 與參數(Parameters))位於以下URL:
https://cwmp-data-models.broadband-forum.org/tr-143-1-1-0.xml
只拿兩行給大家看一下:

<parameter base="Interface" access="readWrite">
     <description action="replace"> {{reference}} The IP-layer interface over which the test is to be erformed. Example: Device.IP.Interface.1 If {{empty}} is specified, the CPE MUST use the interface as directed by its routing policy (''Forwarding'' table entries) to determine the appropriate interface.     
    </description>
</parameter>
<parameter base="DownloadURL" access="readWrite">
      <description action="append"> Note: For time based tests ({{param|TimeBasedTestDuration}} > 0) the ACS MAY add a hint to duration of the test to the URL. See {{bibref|TR-143a1|Section 4.3}} for more details. </description>
</parameter>

接下來是SOAP(The Simple Object Access Protocol)。SOAP是一段XML,定義schema,用來描述兩個端點之間要傳送的資訊。

RPC (Remote Procedure Call) 是傳送SOAP的應用程式,具備以下功能:
- 描述兩端點之間的傳送方式與傳送的參數。
- 描述回傳資訊的樣子。
- 描述傳送失敗的原因。

簡單來說,CWMP使用RPC的應用程式,利用SOAP的格式,傳遞 失敗(faults)、呼叫與回應(call/response)的格式、訊息ID(message ID)。

二、RPC的例子

下面看一下一個真實的RPC,他的Message Structure是甚麼樣子?

<soapenv:Envelope xmlns:soap=http://schemas.xmlsoap.org/soap/encoding/ 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
     xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
          <cwmp:ID soapenv:mustUnderstand="1">1323392</cwmp:ID>
    </soapenv:Header>
    <soapenv:Body>
         <cwmp:SetParameterValues>
         <ParameterList soap:arrayType="cwmp:ParameterValueStruct[1]">
                  <ParameterValueStruct>
                             <Name>InternetGatewayDevice.ManagementServer.URL</Name>
                             <Value xsi:type="xsd:string">http://someacs.cwmp.org/path/</Value>
                   </ParameterValueStruct>
          </ParameterList>
         <ParameterKey>1323392</ParameterKey>
         </cwmp:SetParameterValues>
    </soapenv:Body>
</soapenv:Envelope>


先看第一段CODE,是SOAP 信封標記。說明SOAP與CWMP Schema在Broadband Forum中的定義。 







 


SOAP的表頭包含交易的信息。在這個例子中,它包含CWMP Message ID。








SOAP Body 包含RPC Call/Respone的參數。這個麗姿之中是使用SetParameterValues RPC。這RPC 的SOAP參數。定義了一個Array,接下來的 <ParameterValueStruct> 描述了第一組參數的名稱與值。

再下面的<ParameterKey>定義了Key的值為1323392。


















看完了RPC Call的參數,接下來看一下,CPE與ACS之中連線的模型是甚麼模樣?



上面的十個步驟完整的說明了整個API呼叫的動作:
  1. Open Connection: 基本上,CPE永遠是啟動連線的一方。但是ACS可以用”Connection Request” 請CPE啟動連線。TR069永遠都是用SSL來連線。 
  2. HTTP Post: CPE收到ACS ”Connection Request” 便啟動連線。詢問ACS想要甚麼資訊? 
  3. HTTP Response: ACS 用 InformResponse 回應希望CPE做的事情。 
  4. HTTP Post: 在這個例子當中,CPE 用一個空的https post回應ACS,資訊收到。
  5. HTTP Response: ACS 用 GetParameterValues RPC call CPE。 
  6. HTTP Post: CPE 用 GetParameterValuesResponse RPC 將資料送給ACS。 
  7. HTTP Response: ACS可以繼續在這個Session之中,要求CPE做事,這裡是用 SetParameterValues RPC call CPE。 
  8. HTTP Post: CPE 用 SetParameterValuesResponse RPC 將資料送給ACS。 
  9. HTTP Response: ACS發一個空的https,結束CWMP Session。 
  10. Close Connection: CPE 發送 “successfully terminated”,結束連線。 
上述連線的第一步就是"Connection Request" 

基本上,CPE永遠是啟動連線的一方。但是ACS可以用”Connection Request” 請CPE啟動連線。TR069永遠都是用SSL來連線。 ACS的“Connection Request”只是簡單的用 HTTP Get 發到 CPE (at an arbitrary URL/port set by the CPE)。

因為CPE是發動方,那CPE要如何找到ACS? 大致上,有以下幾種方法:
  1. CPE在Configuration檔案中,設定預設的ACS的位置(URL)。
  2. 應運商(ISP)透過DHCP option 60 欄位當中的 dslforum.org 字串,讓DHCP Server辨識這個CPE是否需要納管? 如果是的話,DHCP server 會發送 DHCP ACK (確認) 的封包,並在 Option 43之中,加入ACS URL的資訊給CPE。
  3. 在系統一開始設定的時候,CPE連線到ACS,也就是先要到ACS去註冊自己的CR URL。
當然CPE也不能隨便讓別人來管理,所以Authentication就非常重要,ACS向CPE發起連線的時候,大致要符合以下原則:
  1. 連接請求必須為HTTP GET 1.1,這個URL必須要用計算產生,CPE可以驗算回來,每個CPE都是唯一的。
  2. 不能用HTTPS,只能用HTTP。
  3. HTTP GET1.1之中必須要空白。
  4. 連線失敗,要Sleep數十秒,再Retry,以免被誤認為 DOS攻擊。
  5. 不得終止正在進行的Session。
  6. 如果隨便就可以連線,也太不安全,所以要先Authentication,TR069可以用基本的HTTP Digest來Login,也可以用憑證(Certification)的方式來做認證。
  7. 雙向都要認證:
    • CPE 要認證 ACS 的 "Connection Requests"。
    • ACS 要認證 CPE的 "Session Initiation"。
那CWMP v1.1之中的RPC呼叫有哪些? 下面大致用CWMP v1.1 來說明一下,目前CWMP1.1已經有點舊了,新版1.1.4有更多的定義,但是v1.1是目前最基本的協定,大致上CPE/ACS都會支援:

規格之中分為兩部分,第一部分  CPE 要接受的 Methods (CPE要處理的Request):
  • GetRPCMethods
  • SetParameterValues
  • GetParameterValues
  • GetParameterNames
  • SetParameterAttributes
  • GetParameterAttributes
  • AddObject
  • DeleteObject
  • Reboot
  • Download
  • Upload
  • FactoryReset
  • GetQueuedTransfers
  • GetAllQueuedTransfers
  • ScheduleInform
  • SetVouchers
  • GetOptions
ACS端要處理Methods比較少,如下:
  • Inform
  • GetRPCMethods
  • TransferComplete
  • AutonomousTransferComplete
  • RequestDownload
  • Kicked
前面連線步驟的第三步:HTTP Response: ACS 用 InformResponse 回應希望CPE做的事情。這是最重要的RPC,每次連線ACS都要先用這個RPC來呼叫CPE。這個連線的內容包含:
  • 這次連線的原因。
  • 選用的Data Model (Forced Inform)與需要的參數列(Parameter List)
  • ACS用來通知CPE的參數。
ACS會送出InfromResponse,來完成這筆RPC。下面是一個InfromResponse RPC的例子:

<soapenv:Envelope 
  xmlns:cwmp="urn:dslforum-org:cwmp-1-0"             xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance">
  <soapenv:Header>
<cwmp:id soapenv:mustunderstand="1">1</cwmp:ID>
  </soapenv:Header>
  <soapenv:Body>
        <cwmp:informresponse>
    <maxenvelopes>1</maxenvelopes>
        </cwmp:informresponse>
  </soapenv:Body>
</soapenv:Envelope>
<soap:body>
  <cwmp:inform>
    <deviceid>
        <manufacturer>Tatung Technology Inc.</manufacturer>
        <oui>000A73</oui>
        <productclass>IGD</productclass>
        <serialnumber>123456789</serialnumber>
    </deviceid>
    <event soap-enc:arraytype="cwmp:EventStruct[1]">
        <eventstruct>
               <eventcode>2 PERIODIC</eventcode>  
               <commandkey></commandkey>
        </eventstruct>
    </event>
    <maxenvelopes>1</maxenvelopes>
    <currenttime>2020-01-23T01:49:14+00:00</currenttime>
    <retrycount>0</retrycount>
    <parameterlist soap-enc:arraytype="cwmp:ParameterValueStruct[6]">
       <parametervaluestruct>
           <name>Device.DeviceSummary</name>
           <value xsi:type="xsd:string"></value>
       </parametervaluestruct>
       <parametervaluestruct>
           <name>Device.DeviceInfo.HardwareVersion</name>
           <value xsi:type="xsd:string">3.1</value>
       </parametervaluestruct>
       <parametervaluestruct>
           <name>Device.DeviceInfo.SoftwareVersion</name>
           <value xsi:type="xsd:string">1.1.5.13</value>
       </parametervaluestruct>
       <parametervaluestruct>
           <name>Device.ManagementServer.ConnectionRequestURL</name>
           <value xsi:type="xsd:string">http://10.0.0.5:1234/</value>
       </parametervaluestruct>
       <parametervaluestruct>
           <name>Device.ManagementServer.ParameterKey</name>  
           <value xsi:type="xsd:string">null</value>
       </parametervaluestruct>
       <parametervaluestruct>
           <name>Device.LAN.IPAddress</name>  
           <value xsi:type="xsd:string">192.168.1.1</value>
       </parametervaluestruct>
     </ParameterList>
   </cwmp:Inform>
</soap:Body>

注意上面的例子當中,有一個Events Tag的參數。這個參數是定義ACS與CPE之間的連接的Event。這是非常重要的定義;其實所有溝通的組合就是在做這些與先定義的Event Tag"

<Event soap-enc:arrayType="cwmp:EventStruct[1]">
           <EventStruct>
                   <EventCode>2 PERIODIC</EventCode>
                   <CommandKey />
          </EventStruct>
</Event>

<Event Code> Tag之中說明一個或數個事先定義好的連線理由(CPE 啟動 Session的原因),整理如下:

Session CPS向ACS發起連線的時機
“0 BOOTSTRAP”CPE第一次要與ACS連線的時候。
1 BOOTCPE開機或重新啟動的時候(REBOOT)
2 PERIODIC設定一個固定的間隔,例如每24小時一次。
3 SCHEDULED通知一排程( Schedule Inform Method)
4 VALUE CHANGE每當修改參數的時候,例如版本更新、IP address改變、Provisioning Code
5 KICKED有事發生,想要連接ACS,報告一些事。
6 CONNECTION REQUESTCPE接收到ACS的連線請求時。
7 TRANSFER COMPLETE下載完成時。
8 DIAGNOSTICS COMPLETE完成自我偵錯。
9 REQUEST DOWNLOAD啟動軟體升版或下載。
10 AUTONOMOUS TRANSFER COMPLETE自動傳送完成
M Reboot
M Scheduled Inform
M Download
M Upload
其他也可以有廠商或營運商自訂的Events Tag。

上表當中,有M開頭的Event Tag沒有解釋,這裡大致說一下是甚麼意思?

這四個有M開頭的Event,通常是說前面有一個Event,這個Event是延續前面的Evernt。舉例來說:
  • "1 BOOT” 與 “M Reboot” : 前面通知CPE要Reboot,CPE Reboot之後,用”M Reboot”告訴ACS SERVER,已經完成Reboot。
  • “7 TRANSFER COMPLETE” 與 “M Download” : ACS 發 “M Download” 啟動一個下載,完成之後,用“7 TRANSFER COMPLETE” 通知ACS已經下載完成。

三、ACS 叫 CPE 做事

ACS 可以叫 CPE 做那些事情? 這裡再重複一下:
  • 詢問 CPE 支援那些 Method。
  • 詢問 CPE 支援那些 Object或那些參數(Parameter)。
  • 產生或刪除物件(Object)。
  • 讀取或編輯一些參數。
  • 讀取或編輯一些參數的屬性。
  • Reboot CPE
  • 請CPE 下載一些檔案,或是一些 Firmware Image。
但是ACS也不知道CPE是否有支援這些功能,因此可以用 GetRPCMethods詢問。下頁就是一個詢問的例子

ACS問到,你有支援那些功能啊?

<soapenv:Body>
     <cwmp:GetRPCMethods/>
</soapenv:Body>

CPE就回答說,我支援以下這一堆:

<soap:Body>
    <cwmp:GetRPCMethodsResponse>
        <MethodList soap-enc:arrayType="xsd:string[12]">
                <string>GetRPCMethods</string>
                <string>SetParameterValues</string>
                <string>GetParameterValues</string>
                <string>GetParameterNames</string>
                <string>SetParameterAttributes</string>
                <string>GetParameterAttributes</string>
                <string>AddObject</string>
                <string>DeleteObject</string>
                <string>Download</string>
                <string>Reboot</string>
                <string>ScheduleInform</string>
                <string>FactoryReset</string>
        </MethodList>
    </cwmp:GetRPCMethodsResponse>
</soap:Body>

ACS Server上面其實要記錄這些 CPE 對於CWMP的處理能力。

製造商可以建立自訂的RPC、Events、Objects與參數(Parameters),可以使用以下格式:

            X_{OUI of Company}_{NameOfNewThing}
            例如: X_012345_MyMethod

接下來,ACS就要問:原來你(CPE)可以設定或讀取一些參數啊? 那你有哪些參數可以讀取啊? 

這個Method就叫做GetParameterNames,如果寫的更科技一些,就說ACS用來取得CPE目前的Objects與 Parameters。CPE就要報告裝置的特性與參數。例子如下:

ACS問道:

<soapenv:Body>
      <cwmp:GetParameterNames>
            <ParameterPath>
                  Device.LAN.IPAddress
            </ParameterPath>
            <NextLevel>
                   0
            </NextLevel>
      </cwmp:GetParameterNames>
</soapenv:Body>


注意這裡有一個參數叫做 <NextLevel> ,他可以是True (1),或是False (0)。
如果如果Next Level = “True”, CPE回應的parameters直接是在“.”之下,沒有其他的sub-objects。
如果Next Level = “False”, 所有的parameters, 與sub-object已經完全回傳,沒有更多的參數。以上面的例子來說,ACS是問 Device.LAN.IPAddress 這個資料能不能回答啊? 

CPE就用GetParameterNamesResponse答回說:

<soap:Body>
  <cwmp:GetParameterNamesResponse>
        <ParameterList soap enc:arrayType="cwmp:ParameterInfoStruct[1]">
               <ParameterInfoStruct>
                     <Name>Device.LAN.IPAddress</Name>
                     <Writable>0</Writable>
               </ParameterInfoStruct>
        </ParameterList>
      </cwmp:GetParameterNamesResponse>
</soap:Body>

CPE回答說,有的,可以提供查詢,但是不接受ACS SERVER的遠端設定( Writable = 0)。

這裡要帶出一個完整路徑或是非完整路徑(complete path 或 partial path)的觀念。這裡適用於所有”GetXXXXX” RPC與 SetParameter RPC之中有關於參數屬性的描述。

上例當中的“ParameterPath” tag可以是“Complete” 或是 “Partial” 路徑(path)。

例如“Device.LAN.IPAddress”就是一個 “Complete” 路徑(完整的路徑。

Path路徑使用“.”作為結束,所以上例當中,如果寫成“Device.LAN.”,就是說這是一個“Partial”路徑,是說所有的Object與參數都會在一個”tree”以下:

舉例而言: “Device.LAN.”,意思是起提供在” Device.LAN.”以下的所有參數。CPE可以用一個ARRAY回傳給ACS。

所以NxetLevel 與 “Complete Path” 或是 “Partial Path” 的概念加在一起,就產生了不同的查詢結果,下面有一個比較長的例子:

先看NextLevel =1 ,就是不需要往下查,只要回答一層就可以了。ACS問道:

<soapenv:Body>
    <cwmp:GetParameterNames>
        <ParameterPath>Device.LAN. </ParameterPath>
        <NextLevel>1</NextLevel>
    </cwmp:GetParameterNames>
</soapenv:Body>

CPE回答:

<soap:Body>
<cwmp:GetParameterNamesResponse>
      <ParameterList soapenc:arrayType="cwmp:ParameterInfoStruct[9]">
     <ParameterInfoStruct>
                <Name>Device.LAN.Stats.</Name>
                <Writable>0</Writable>
     </ParameterInfoStruct>
     <ParameterInfoStruct>
                <Name>Device.LAN.IPPingDiagnostics.</Name>
                <Writable>0</Writable>
     </ParameterInfoStruct>
     <ParameterInfoStruct>
                <Name>Device.LAN.TraceRouteDiagnostics.</Name>
                <Writable>0</Writable>
      </ParameterInfoStruct>
        ...
      <ParameterInfoStruct>
              <Name>Device.LAN.MACAddress</Name>
              <Writable>0</Writable>
      </ParameterInfoStruct>
      </ParameterList>
   </cwmp:GetParameterNamesResponse>
</soap:Body>

注意沒有? CPE 回應了一個 Partial Path,意思是這第一層的目錄之下,還有許多的資訊可以提供。這時候有九個參數可以查詢。

好! 如果用 <NetLevel = 0 (TRUE)> 來問呢? 就是麻煩把所有資訊都提出來吧!!! ACS 的呼叫如下:

<soapenv:Body>
    <cwmp:GetParameterNames>
        <ParameterPath>Device.LAN. </ParameterPath>
        <NextLevel>0</NextLevel>
    </cwmp:GetParameterNames>
</soapenv:Body>

這時CPE回答如下:

<soap:Body>
   <cwmp:GetParameterNamesResponse>
       <ParameterList soapenc:arrayType="cwmp:ParameterInfoStruct[35]">
            <ParameterInfoStruct>
                    <Name>Device.LAN.</Name>
                    <Writable>0</Writable>
            </ParameterInfoStruct>
            <ParameterInfoStruct>
                    <Name>Device.LAN.AddressingType</Name>
                    <Writable>0</Writable>
            </ParameterInfoStruct>
              ...
                        <Name>Device.LAN.Stats.</Name>
                        <Writable>0</Writable>
            </ParameterInfoStruct>
            <ParameterInfoStruct>
                        <Name>Device.LAN.Stats.ConnectionUpTime</Name>
                        <Writable>0</Writable>
            </ParameterInfoStruct>
            <ParameterInfoStruct>
                        <Name>Device.LAN.Stats.TotalBytesSent</Name>
                        <Writable>0</Writable>
            </ParameterInfoStruct>
            <ParameterInfoStruct>
                        <Name>Device.LAN.IPPingDiagnostics.</Name>
                        <Writable>0</Writable>

有35個參數,一層一層的回應過來。如果是Partial Path,基本上是沒有具體數值的,還是要讀到絕對路徑,才請CPE讀出或設定數值。

因為太長了,所以另外寫到下一篇 (TR-069 初釋(續))。

下一篇會繼續看,如何讀出參數與設定參數,還有重開機、升版等等的具體作法。