作(zuò)者 | 不(bù)可(kě)說(shuō)
出品 | 汽車(chē)電(diàn)子(zǐ)與軟件(jiàn)
#01 引 入 ☆£
服™♠↓"務發現(xiàn)模塊(Service Dis☆✔covery Module)的(de)主要(yào)任務是(shì)在車₩∞(chē)內(nèi)通(tōng)信中管理(lǐ)服務(functional e ∏≠ ntities)的(de)可(kě)用(yòng)性,這(z₩↓§™hè)些(xiē)服務被稱為(wèi)功能(néng<✘ )實體(tǐ),并控制(zhì)事(shì)件(jiàn)±≈>消息的(de)發送行(xíng)為(wèi)。這(zhè)一(yī)機(jī)制(zhì)确保僅×αγ将事(shì)件(jiàn)消息發送給需要<✔γ≈(yào)它們的(de)接收方(即采用(yòng)發布/訂閱模式)。此'處描述的(de)解決方案就(jiù)被稱為(wèi)SOME¥>₹≠/IP-SD(基于IP的(de)可(kě)擴展面向服務中間(jiā≤φ≤♦n)件(jiàn) - 服務發現(xià ↔♣n),Scalable service-Oλ↑§λriented MiddlewarE over IP - Servicγ₹e Discovery)。 &nbsβ∏γp;
通(tōng)過服務發現₩®(xiàn)功能(néng),不(bù)同的(de)電(diàn)子(zε☆✔ǐ)控制(zhì)單元(ECU)可(kě)以提供服務實♠₹例,并在車(chē)輛(liàng)網絡中查找可(kě)用(yòng)的(d≥÷e)服務實例。一(yī)個(gè)ECU可(kě)以停止提× ©供之前提供的(de)服務實例,之後對(duì)該服務實例的(de)查找将得(de)不(bù↓®↕₹)到(dào)響應。服務實例是(shì)由其服務接口定義的(de)服務的(de)單個(gè)☆實現(xiàn)。 ↑∑♠™
除了(le)管理(lǐ)服務實例的(de)狀态外(wài),服務發現(xiàn)還(hái)能π(néng)控制(zhì)發送一(yī)種特殊消息,即事(shì)件(jiàn)消息。這(zhè)¥©些(xiē)事(shì)件(jiàn)消息被分(fēn ₹)組到(dào)事(shì)件(jiàn)組中,服務發現(xiàn)可(kě)以 ↔÷以發布/訂閱的(de)方式開(kāi)啓或關閉這(zhè)些(xi₩>δ$ē)事(shì)件(jiàn)組,從(cóng)而開(kāi)啓或關閉該事(shì)件(↑φ±♥jiàn)組中事(shì)件(jiàn)的(de)發送和(hé)接收。•∏
#02 SOME/IP SD對(duì)不(bù)同ECU角色的(de)職責
ECU的(de)服務發現(xiàn)模塊在處理<λΩ(lǐ)服務器(qì)服務和(hé)客戶端服務時(shí)扮演著(zhe)不(σ"bù)同的(de)角色,并需要(yào)執行(xíng)相(xiàng)應的(de)操作(zuò)來(lái)确保服務的(de)正确提↕≤÷供和(hé)查找。
一(y×"¥$ī)個(gè)ECU需要(yào)處理(lǐ)兩種不(bù)同類型的(de)服務:服務'>λβ端服務(Server Services):本地(dì)ECU向車(chē)輛(liàng)的(de)其他(tā)部分(→€fēn)提供服務器(qì)服務實例(即位于本地(dì)的✘↑(de)服務實例),并可(kě)以被視(shì)為(wèi)該服務實例的(de)服務端∏₽♦'。
客戶端服務(Client Services):本地(dì)ECU可(kě)能(néng)會(&←<λhuì)使用(yòng)車(chē)輛(liàng)內(nèi)另一(yī)個(gè®↔)ECU提供的(de)服務器(qì)服務實例,♥<€并可(kě)以被視(shì)為(wèi)該服務實例的(αΩ£ de)客戶端。
對(duì)于服務端服務,本地(dì)ECU的(de$↕)SOME/IP SD模塊(擔任服務器(qì)角★☆>↕色)需要(yào)執行(xíng)以下(xià)操作(zuò):
- 當服務可(kě)用(yòng)時(shí)(即提供服務的(de)軟件(jiàn)¶&•σ組件(jiàn)(SWC)準備就(jiù)緒,且服務在當前ECU狀态下(←xià)可(kě)用(yòng))提供本地(dì)服務。
✔ §•- 當服務不(bù)再可(kě)用(yòng)時(shí),撤§₽回本地(dì)服務的(de)提供(停止提γ¥↑供)。
- 響應其他(t→×ā)ECU的(de)查找請(qǐng)求¥±©。
對(duì)于客戶端服務,本地(dì)EC σ$≤U的(de)服務發現(xiàn)模塊(擔任客戶端角色)需≤δδ要(yào)執行(xíng)以下(xià)操作(zuò):
- 根據配置監聽(tīng♥↔&)提供的(de)服務和(hé)查找請(qǐng)求,并将這(zhσ ∑γè)些(xiē)信息存儲在易失性存儲器(qì$< ≥)中。
Ω¶¥- 監聽(tīng)停止提供的(de)服務信息,并根← 據配置将這(zhè)些(xiē)信息存儲¥÷∑在易失性存儲器(qì)中。
- 根據當前ECU及其軟件(jiàn)組件(jiàn)←→↕₽(SWC)的(de)狀态發送查找請(qǐng)求。
服務發現(xiàn)同樣可(kě)用(yòng)于管理(lǐ)發布/訂閱(Publish/×γSubscribe)關系。在基于服務發現(xiàn)的(d↕e)發布/訂閱應用(yòng)場(chǎng)景中,一(yī)個(gè)ECU(作(↕₹σ€zuò)為(wèi)具有(yǒu)已消費(f≠₩ βèi)事(shì)件(jiàn)組的(de)發布/訂閱客戶端)©•↔<對(duì)從(cóng)另一(yī)個(gè)ECU(作(∑Ω₩zuò)為(wèi)具有(yǒu)事(shì)件(jiàn)處§$理(lǐ)器(qì)的(de)發布/訂閱服務器÷<δ(qì))接收某些(xiē)數(shù)據(即訂閱)感興趣。
雖然訂閱關系在服務發現(xiàn)(SD)消息中明§↑(míng)确定義,但(dàn)發布關系則基于服務實例本身(shēn)的 <÷¥(de)可(kě)用(yòng)性(即提供服務條目)。基于™"$所提供的(de)服務實例,發布/訂閱客戶端可(kě)通(tōng)過訂閱事(shì)件(j™★iàn)組條目進行(xíng)訂閱。此時(s&♣♥<hí),發布/訂閱服務器(qì)将利用(yòng♣→)此訂閱關系,将發布/訂閱客戶端注冊為(wèi)對(d↑uì)訂閱中指定的(de)某些(xiē)信息感興趣的(de)方,并在發生(shēng)某些(✔↕↓₹xiē)事(shì)件(jiàn)或超時(shí)後,開(kāi)始将這(zhè)些(xiē)信σ€♥≠息發送給發布/訂閱客戶端。
為(wèi)進行(xíng)優化(huà),服務發現↕≠∏(xiàn)支持使用(yòng)多(duō)播消息而非每個(gè)客戶端的(de)單播消息,将事→∑✘(shì)件(jiàn)消息發送給多(duō)個(₹αβgè)客戶端。但(dàn)請(qǐng)注意,服務器(qì)端和(hé)客戶端預先配置的(de)多(duō)播之間(jiān)存在差異: &nbs§♥±p;
- 如(rú)果SdServerService(服務↔♥≠→端服務)為(wèi)每個(gè)事(shì)件(j"♦iàn)處理(lǐ)器(qì)預先配置了(le)多(duō)播地(dì)址和(hé)端口(即所謂“事(shì)件(jiàn)處理(lǐ)器(qì)多(duō₩©λ)播端點”),則當訂閱了(le)具有(yǒu)不(bù)同端點信息的↓∞®(de)SdClientServices(客戶端服務)達到(dào)阈值(S≈♦dEventHandler MulticastThreshold,事(♠ shì)件(jiàn)處理(lǐ)器(qì)多(duō)播阈值)時 λ↑(shí),SdServerService将切換至此多(duō)播地(dì)址和(hé)端口。
- 如(rú)果SdClient∑αService(客戶端服務)使用(yòng)多(duō)播地§♥α(dì)址和(hé)端口(即所謂“已消費(↔↑fèi)事(shì)件(jiàn)組多(duō)播端點”)進行(xíng)了(le)訂α←β閱,則SdServerService在訂閱♦↑↔♦已消費(fèi)事(shì)件(jiàn)組多§÷☆(duō)播端點(多(duō)播地(dì)址和(hé)端口)時(shí),會(huì)α₹向其發送事(shì)件(jiàn)。

#03 SD流程
服務發布流程
Down Phase
服務處于不(b↓¶≥ù)可(kě)用(yòng)狀态
Initial Wait Phase
服務準備完成後, 進入該階段, 延遲一(yī♠>)定時(shí)間(jiān)後發送服務發布報(bà&απλo)文(wén)
Repetition Phase
重複發送服務←$₹€發布報(bào)文(wén), 重複次數(shù)由配置參數(shù)決定δ¥ , 此階段收到(dào)服務發現(xià ≠©♠n)請(qǐng)求後,通(tōng)過服務發布報(bào)文(wén)進行(xí☆♣♣ng)應答(dá)
Main Phase
服務發現(xiα≤←àn)流程
D↑>own Phase
服務未被應用(yòng)請(qǐng)求
Initial Wa®™€✔it Phase
應用(yòng)發起服務請(qǐng)求後進入該階段♠β≥
Repetition Phase
重複發送服務發現(xiàn)報(bào)文(wén), δ₹★重複次數(shù)由配置文(wén)件(jiàn)參數(shù)REPETITION_Mε♣✘AX決定, 收到(dào)服務發布報(bào)文(wén)後, 停止發送π×服務發現(xiàn)報(bào)文(wén)
Main Phase
↕ > 不(bù)再重複發送服務發現(xiàn)報(bào)文(wén), 每次收到(dà£★δλo)服務發布報(bào)文(wén)後, ¶®觸發服務訂閱請(qǐng)求報(bào)文(wén)。 ≥♠
服務訂δ÷閱流程
 ♣✔;
- 服務發現(xiàn)
- 連接建立
- 注冊服務
- 事(shì)件(jiàn)通(tōng)知(zhī)
#04 SOME/IP SD協議(yì)規範

Re♣₩quest ID 由Client ID 和(hé)Sessi≠↕on ID 組成。雖然Client ID 不(bù)∑>"Ω用(yòng)于服務發現(xiàn),但✘£₽¥(dàn)Session ID 用(yòng)于檢測車(chē)輛(li àng)中其他(tā)服務發現(xiàn)實例的(de)重啓或重啓,以修複∏•φ±服務發現(xiàn)模塊的(de)本地(dì)狀态。在初始化(huà) Service Dis✘↕≤covery Module 後, ECU 發送的(de)消息的(de₽ ) Session ID應為(wèi)0x ×0001。 &n₩σbsp;
Protocol Version 字段÷∞£®是(shì)用(yòng)來(lái)描述當前SOME/IP協議(yì)版本,目前是(shìσ₽→$)0x01;
Return Code用(yòng)于表示請(qǐ↓π ng)求是(shì)否已成功處理(lǐ)。÷♣這(zhè)不(bù)适用(yòng)于SOME/IP-SD;因此返回碼被靜(jì∑®ng)态設置為(wèi)0x00。 ≥λ±
SOME/IP SD從(cóng)>σMessage ID到(dào)Return C>♠♣¶ode字段的(de)格式與SOME/IP 協議(yì)格式是(shì)一(yī)緻的(de);☆ 後面的(de)字段才是(shì)SOME/IP SD獨有(yǒu)的(de)。
Flag
如(rú)果服務4端或客戶端通(>←tōng)過評估通(tōng)信方發送的(de)SOME/IP-SD消息的(de)會(huì)話( ♥huà)ID(Session ID)和(hé)重啓标志(zhì)(Re∑•boot Flag)檢測到(dào)重啓,則受影(↓♣yǐng)響的(de)通(tōng)信本地(€∑dì)狀态将失效,并應執行(xíng)以下(xià)操作(zuò):  •☆;
客戶端檢測到(dào)服務端重啓時(shí)的(dδ€¥e)處理(lǐ):
1)如(rú)果客戶端檢測到(dào)服務端重啓,并且該↑§∞客戶端正在使用(yòng)該服務端的(de)服務,則客戶端應将此次重啓視(shì)為£↔(wèi)接收到(dào)“停止提供服務”(StopOffer)消息。
2)如(rú)©≥果為(wèi)該服務配置了(le)SdCl&₩∏ientServiceTcpRef,則活動客戶δ ×端應通(tōng)過調用(yòng)SoAd_≥♠CloseSoCon()函數(shù)并設置參數(shù)“abort”為(wèi)TR'£UE來(lái)關閉相(xiàng)應的(de)TCP連接。
服務器(qì)檢測到(dεσ™•ào)客戶端重啓時(shí)的(de)處理(lǐ):
Reserved
Le ₽✔ngth of Entries Array
E≈≈☆ntries Array
服務Services Entri$ ✔•es

- Type為(wèi)0x00時(shí),表示FindService;為(wèi)0x01時(shí),表示OfferService和(hé)St≥<opOfferService
- Index 1st options 标明(míng)屬于這(zhè)個(gè)E≠¥→¥ntry的(de)第一(yī)個(gè)option的(de)起始索≤ ™引序号,從(cóng)0開(kāi)始計(jì)算(s€₹δuàn);Index 2st options 标明(míng)屬于這(zhè)個(gè)Enλ¥✔δtry的(de)第二個(gè)option的(de↓ ₽ε)起始索引序号,從(cóng)0開(kāi)始計(jì)算(suàn);#of op★£∑t 1表明(míng)該entry有(yǒu)幾個(gè)第一≤≠♣(yī)組option;#of opt 2表明(m' íng)有(yǒu)幾個(gè)第二組op←γtion。
- 該類型Service ID字段應攜帶服務的(de)Service Iλ£γ↔D,根據是(shì)服務端還(hái)是(shì)客戶端,使用(yòng∏δ↕₽)參數(shù)SdServerServiceID或SdClientServiceID進行(x䧥δíng)靜(jìng)态配置。
- Instance ID字段應攜帶服務的(dΩ★→e)Instance ID,根據是(shì)服務端還(hái)π≥是(shì)客戶端,使用(yòng)參數(sh"÷₹ù)SdServerSer-viceInstanceID←∞和(hé)SdClientServiceInstanceID靜(jìng)态配σ∞☆β置。
- Major Version字段應包含SdServerServiceMajorVersi∞$©on或者SdClientServiceMajorVersion,這(zhè)取決于✘↕該條消息是(shì)服務端發送的(de)還(hái≠✔δ)是(shì)客戶端發送的(de)。
- TTL字段定義了(le)使用(yòng)參數(shù)SdServerTimer TTL和÷™→(hé)SdClientTimer TTL配置的(de)服務器(qì)條目的(de)生(shēn±γ≥g)存期(秒(miǎo)),但(dàn)TTL為(wèi)0的(de)Stop Entπ ries除外(wài)。
- Minor字段應攜帶SdServerServiceMinorVersion或者SdClientS↑φ✘erviceMinorVersion,這(zhè)些(xiē)都(dōu±₩$)是(shì)在服務設計(jì)階段就(jiù) ↑≥β已經規範好(hǎo)的(de)。

Length of Options Array &→₩"nbsp;
Options Array &≤εnbsp;
Type為(wèi)0x1;
&nb™"β≤sp;
IPv4 Endpo♦∑int Option

該Option傳輸單播IP地(dì)址、第四↓×">層協議(yì)(如(rú)UDP或TCP)和(hé)端口号;從(cóng)而獲φβ≈取與服務通(tōng)信所需的(de)信息。當≤ 接收到(dào)提供服務并傳輸IPv4選項的(de)服務發現(xiàn)消息時Ω★(shí),接收此消息的(de)ECU可(kě)以通(tōng)過更新Socket連接,動态配置套λ接字适配器(qì)以使用(yòng)此服務。
IPv4 Multicast Option

I×÷Pv4多(duō)播選項由SdServerService或者SdClientService用☆≈™₩(yòng)于通(tōng)告其配置的(de)事(shì)件(jiàn)£≈∞多(duō)播端點;
- 如(rú)果用(yòng)作(zuò)服務↔λ端的(de)多(duō)播端點,則SdServerServi÷φφ¶ce會(huì)聲明(míng)IPv4多(d★" uō)播地(dì)址、傳輸層協議(yì)(ISO/OSI第4層)和(hé±" )端口号,多(duō)播事(shì)件(jiàn)和(hé)多(duō)播通(tōn"'π↔g)知(zhī)事(shì)件(jiàn)将發送到(dào)這(zhè)些(xiē)端口。
- 如(rú≥±∞&)果它用(yòng)作(zuò)客戶端事(shì)件(jiàn)組多(duō)播端點,則SdCl→≤ientSer指示IPv4多(duō)播地(←→ββdì)址、傳輸層協議(yì)(ISO/OSI第4層)和(hé)"§&端口号,SdClient期望在其中接收事(shì)件(jiàn)。作(zuò)為(wèi)傳輸"≈層協議(yì),隻支持UDP。

IPv4 SD端點選項傳輸發送方SD實現(xiàn)的(®✘ 'de)端點(即IP地(dì)址和(hé)端口)。這(zhè)用(yòng)于在無法使用¥∏§(yòng)IP地(dì)址和(hé)/或端口号的(dα e)情況下(xià)标識SOME/IP-SD實例。
O₹"≠ption也(yě)支持 IPv6 Endpoint Option、IPv6☆♦ε§ Multicast Option、IP'>₹↕v6 SD Endpoint Option,但(dàn)是(shì)在車(chē)載通(tōngσα¶)信中,IPv4就(jiù)足夠了(le),并且通(tōng)常會(huì)禁用(yòng)I✘♦Pv6,因此此處不(bù)介紹IPv6相(xiàng)關的(de)Option。
#05 通(tōng)信實例分(fēn)析
第一(yī)個(₽ ↕∑gè)(offer)

第二個(gè)(Subscribe) φ
