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 初釋(續))。

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












































沒有留言:

張貼留言