00 DoIP nedir — ISO 13400
DoIP (Diagnostics over Internet Protocol), ISO 13400 standardıyla tanımlanan ve UDS diagnostics mesajlarını Ethernet/IP ağı üzerinden taşıyan protokoldür.
Geleneksel OBD-II tanılama, fiziksel bir D-Sub konnektör (OBD-II port) üzerinden CAN bus'a doğrudan erişim sağlardı. Modern araçlar zonal mimariye geçtikçe ve araç içi Ethernet yaygınlaştıkça bu yaklaşım yetersiz kaldı:
- Yüzlerce ECU'ya tek fiziksel port üzerinden ulaşmak olanaksız
- OTA (over-the-air) güncelleme için fiziksel bağlantı zorunlu olmamalı
- Büyük firmware dosyaları CAN'ın 1 Mbps bant genişliğinde çok yavaş aktarılır
┌──────────────────────────────────────────────────────────────┐
│ DoIP Ağ Topolojisi │
├──────────────────────────────────────────────────────────────┤
│ │
│ [Harici Tester / OTA Server] │
│ │ │
│ │ Ethernet / WiFi / LTE │
│ ▼ │
│ [DoIP Gateway / VCI (Vehicle Communication Interface)] │
│ ├── 192.168.1.100 (harici interface) │
│ └── 10.0.0.1 (araç içi interface) │
│ │ │
│ │ Araç içi Ethernet (100BASE-T1) │
│ ├── [ECU-1 DoIP Node] 10.0.0.10 │
│ ├── [ECU-2 DoIP Node] 10.0.0.11 │
│ └── [ECU-3 DoIP Node] 10.0.0.12 │
│ │
└──────────────────────────────────────────────────────────────┘
DoIP'in CAN Diagnostics ile farkı
DoIP, UDP ve TCP port 13400 kullanır. Vehicle Identification UDP üzerinden, Routing Activation ve Diagnostic Messages TCP üzerinden çalışır. Port 13400, IANA'ya kayıtlıdır.
01 Ağ topolojisi detayı
DoIP'te her katılımcının bir Logical Address (LA) ve bir Physical Address (IP) vardır. Gateway, dışarıdan gelen tanılama isteklerini doğru ECU'ya logical address ile yönlendirir.
Adres yapısı
# Tipik LA tahsisi
0x0E00 → Harici Tester (OBD dongle, laptop, OTA server)
0x0E80 → DoIP Gateway / Central VCI
0x0E81 → Engine Control Unit (ECM)
0x0E82 → Transmission Control Unit (TCM)
0x0E83 → Anti-lock Braking System (ABS)
0x0E84 → Body Control Module (BCM)
0x0E85 → Airbag Control Unit (ACU)
0x0E86 → Instrument Cluster (IPC)
02 DoIP mesaj yapısı
Her DoIP mesajı 8 byte'lık Generic Header ile başlar. Header, protocol versiyonu, mesaj tipini ve payload uzunluğunu tanımlar.
┌─────────────────────────────────────────────────────────────┐
│ DoIP Generic Header (8 byte) │
├──────────┬──────────┬──────────────┬───────────────────────┤
│ Protocol │ Inverse │ Payload Type │ Payload Length │
│ Version │ Protocol │ (16 bit) │ (32 bit) │
│ (8 bit) │ Version │ │ │
│ │ (8 bit) │ │ │
└──────────┴──────────┴──────────────┴───────────────────────┘
Header Alanları
Payload Type Tablosu
03 Vehicle Identification
Tester, ağdaki DoIP node'larını keşfetmek için UDP broadcast kullanır. Araç VIN, EID ve GID gibi kimlik bilgilerini yanıt olarak döner.
Keşif Akışı
Tester (UDP) DoIP Gateway (UDP)
│ │
│── VehicleIdentificationRequest ──────────────►│
│ Dest: 255.255.255.255:13400 │
│ Payload Type: 0x0001 │
│ Payload Length: 0 │
│ │
│◄─ VehicleAnnouncementMessage (Unicast) ───────│
│ VIN: "WBAC5441X1LB12345" (17 byte) │
│ LA: 0x0E80 │
│ EID: 6 byte (MAC address) │
│ GID: 6 byte (Group ID) │
│ FTA: 0x00 (No further action) │
│ SYNC: 0x10 (VIN + LA sync'd) │
VIN ile arama
Belirli bir VIN'e sahip aracı bulmak için VehicleIdentificationRequestWithVIN mesajı gönderilir (Payload Type 0x0003). Sadece eşleşen araç yanıt verir.
# Generic Header: Proto=0x02, Inv=0xFD, Type=0x0001, Len=0x00000000
02 FD 00 01 00 00 00 00
# VehicleAnnouncement yanıtı (örnek):
# 02 FD 00 04 00 00 00 21 (header, payload 33 byte)
# 57 42 41 43 35 34 34 31 58 31 4C 42 31 32 33 34 35 (VIN: WBAC5441X1LB12345)
# 0E 80 (Logical Address: 0x0E80)
# 00 1A 2B 3C 4D 5E (EID: MAC adresi)
# 00 00 00 00 00 00 (GID: 0 = tanımlanmamış)
# 00 (FurtherActionRequired: 0)
# 10 (SyncStatus: VIN+GID sync)
EID ve GID
04 Routing Activation
Vehicle Identification'dan sonra tester, TCP bağlantısı kurar ve Routing Activation yaparak tanılama mesajları gönderme iznini alır.
Routing Activation Akışı
Tester (TCP client) DoIP Gateway (TCP server)
│ │
│── TCP SYN ────────────────────────────────────►│ :13400
│◄─ TCP SYN-ACK ────────────────────────────────│
│── TCP ACK ────────────────────────────────────►│
│ │
│── RoutingActivationRequest ───────────────────►│
│ Source LA: 0x0E00 (tester) │
│ Activation Type: 0x00 (Default) │
│ OEM-specific: 0x00000000 │
│ │
│◄─ RoutingActivationResponse ──────────────────│
│ Tester LA: 0x0E00 │
│ Gateway LA: 0x0E80 │
│ Response Code: 0x10 (Success) │
Response Code'lar
Activation Type
05 Diagnostic Message
Routing Activation başarılı olduktan sonra tester, hedef ECU'ya Diagnostic Message göndererek UDS servisleri çağırabilir.
Diagnostic Message Yapısı
┌────────────────────────────────────────────────────────────┐
│ DoIP Diagnostic Message Payload │
├───────────────┬───────────────┬──────────────────────────┤
│ Source Address│ Target Address│ UDS User Data │
│ (16 bit) │ (16 bit) │ (variable length) │
│ Tester LA │ ECU LA │ 0x22 0xF1 0x90 (VIN?) │
└───────────────┴───────────────┴──────────────────────────┘
# DoIP header: Proto=0x02, Inv=0xFD, Type=0x8001, Len=7 byte
02 FD 80 01 00 00 00 07
# Payload:
# Source LA: 0x0E00 (tester)
0E 00
# Target LA: 0x0E81 (Engine ECU)
0E 81
# UDS: ReadDataByIdentifier, DID=0xF190 (VIN)
22 F1 90
# Gateway → Tester: Positive ACK (0x8002)
02 FD 80 02 00 00 00 05
0E 00 # Tester LA
0E 81 # ECU LA (target)
00 # ACK code: 0x00 = OK
# ECU → Tester (UDS Response via DoIP DiagnosticMessage 0x8001):
02 FD 80 01 00 00 00 18
0E 81 # Source: ECU
0E 00 # Target: Tester
# UDS: 0x62 F1 90 + 17 byte VIN
62 F1 90 57 42 41 43 35 34 34 31 58 31 4C 42 31 32 33 34 35
Negative ACK Nedenleri
06 Python ile DoIP istemcisi
doipclient kütüphanesi, DoIP protokolünü Python'da soyutlar. Vehicle Identification, Routing Activation ve Diagnostic Message akışlarını otomatik yönetir.
Kurulum
pip install doipclient
Temel kullanım
from doipclient import DoIPClient
from doipclient.messages import *
# DoIP Gateway IP ve port
GATEWAY_IP = "192.168.1.100"
GATEWAY_PORT = 13400
# Tester ve hedef ECU Logical Address
TESTER_LA = 0x0E00
ECU_LA = 0x0E81
# İstemci oluştur ve bağlan
client = DoIPClient(GATEWAY_IP, ECU_LA,
client_logical_address=TESTER_LA)
# Vehicle Identification (opsiyonel — zaten bilinen IP)
vin_response = client.request_entity_status()
print(f"Gateway durum: {vin_response}")
# Routing Activation otomatik yapılır bağlantıda
# Manuel tetiklemek için:
result = client.request_activation(0x00) # Default activation
print(f"Routing activation: {result.response_code}")
# Raw UDS mesajı gönder (0x22 F190 = ReadDataByIdentifier VIN)
uds_request = bytes([0x22, 0xF1, 0x90])
response = client.send_doip_payload(
DiagnosticMessage(TESTER_LA, ECU_LA, uds_request))
print(f"UDS yanıtı: {response.user_data.hex()}")
# Bağlantıyı kapat
client.close()
UDP Vehicle Discovery
from doipclient import DoIPClient
import socket, struct
def discover_doip_nodes(timeout=2.0):
"""UDP broadcast ile ağdaki DoIP node'larını keşfet"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.settimeout(timeout)
# VehicleIdentificationRequest: 02 FD 00 01 00 00 00 00
header = struct.pack('!BBHI', 0x02, 0xFD, 0x0001, 0)
sock.sendto(header, ('255.255.255.255', 13400))
nodes = []
try:
while True:
data, addr = sock.recvfrom(1024)
nodes.append({
'ip': addr[0],
'vin': data[8:25].decode('ascii', errors='replace'),
'la': struct.unpack('!H', data[25:27])[0],
'eid': data[27:33].hex(':')
})
except socket.timeout:
pass
sock.close()
return nodes
for node in discover_doip_nodes():
print(f"IP: {node['ip']:20s} VIN: {node['vin']} LA: {node['la']:#06x} EID: {node['eid']}")
07 Kombine UDS + DoIP
python-udsoncan, transport katmanı olarak DoIP'i destekler. Bu kombinasyon, UDS'nin tam özellik setini Ethernet üzerinden kullanmayı sağlar.
DoIP transport bağlantısı
import udsoncan
from udsoncan.client import Client
from doipclient import DoIPClient
from doipclient.connectors import DoIPClientUDSConnector
# DoIP bağlantısı
doip = DoIPClient("192.168.1.100", 0x0E81,
client_logical_address=0x0E00)
# UDS transport olarak DoIP kullan
conn = DoIPClientUDSConnector(doip)
config = udsoncan.configs.default_client_config.copy()
config['request_timeout'] = 10
with Client(conn, config=config) as uds:
# Artık tam UDS API'si DoIP üzerinden çalışır
# Extended session
uds.change_session(
udsoncan.services.DiagnosticSessionControl.Session.extendedDiagnosticSession)
# VIN oku
result = uds.read_data_by_identifier([0xF190])
vin = result.service_data.values[0xF190].decode('ascii')
print(f"VIN: {vin}")
# DTC oku
dtcs = uds.get_dtc_by_status_mask(0xFF)
for dtc in dtcs.service_data.dtcs:
print(f"DTC: {dtc.id:06X}")
doip.close()
Firmware flash senaryosu (DoIP + UDS)
def doip_flash_ecu(gateway_ip, ecu_la, fw_path, flash_addr):
"""DoIP üzerinden UDS flash akışı"""
doip = DoIPClient(gateway_ip, ecu_la,
client_logical_address=0x0E00)
conn = DoIPClientUDSConnector(doip)
with open(fw_path, 'rb') as f:
firmware = f.read()
with Client(conn) as uds:
# Programming session
uds.change_session(
udsoncan.services.DiagnosticSessionControl.Session.programmingSession)
# Security access
seed = uds.request_seed(0x11).service_data.seed
uds.send_key(0x12, calculate_key(seed))
# Request Download
mem = udsoncan.MemoryLocation(address=flash_addr,
memorysize=len(firmware),
address_format=32, memorysize_format=32)
result = uds.request_download(mem,
udsoncan.DataFormatIdentifier(0x00))
max_blk = result.service_data.max_length
# Transfer bloklar
seq, offset = 1, 0
while offset < len(firmware):
chunk = firmware[offset:offset + max_blk - 2]
uds.transfer_data(seq, chunk)
offset += len(chunk)
seq = (seq % 0xFF) + 1
uds.request_transfer_exit()
uds.ecu_reset(udsoncan.services.ECUReset.ResetType.hardReset)
doip.close()
print("Flash tamamlandı.")
DoIP + 100 Mbps araç içi Ethernet ile 10 MB firmware yaklaşık 1–2 saniyede aktarılır (transfer overhead dahil). CAN üzerinden aynı firmware 80+ saniye sürerdi. Modern araçlarda OTA güncellemelerini pratik kılan budur.
08 Pratik: Simülasyon ve End-of-Line flash
Wireshark DoIP dissector ile trafik inceleme, Linux'ta DoIP gateway simülasyonu ve üretim hattı End-of-Line flash akışını uygula.
Wireshark DoIP Dissector
# Wireshark >= 3.0 DoIP desteği yerleşiktir
# TCP port 13400 otomatik olarak DoIP olarak decode edilir
# tshark ile DoIP trafiği yakala
tshark -i eth0 \
-f 'tcp port 13400 or udp port 13400' \
-T fields \
-e doip.type \
-e doip.sourceaddress \
-e doip.targetaddress \
-e doip.uds.service
# Routing Activation mesajlarını filtrele
tshark -r doip_capture.pcap \
-Y 'doip.type == 0x0005 || doip.type == 0x0006'
# Sadece UDS yanıtlarını göster
tshark -r doip_capture.pcap \
-Y 'doip.type == 0x8001 and doip.uds.service >= 0x40'
DoIP Gateway Simülasyonu (Python)
import socket, struct, threading
PROTO_VER = 0x02
INV_PROTO = 0xFD
GATEWAY_IP = '0.0.0.0'
GATEWAY_LA = 0x0E80
GATEWAY_PORT = 13400
VIN = b'SIMGW0000000000A' # 17 byte
def build_header(ptype, length):
return struct.pack('!BBHI', PROTO_VER, INV_PROTO, ptype, length)
def handle_tcp_client(sock, addr):
print(f"Bağlantı: {addr}")
while True:
data = sock.recv(4096)
if not data:
break
ptype = struct.unpack('!H', data[2:4])[0]
if ptype == 0x0005: # Routing Activation Request
# Yanıt: 0x0006, response code 0x10 (success)
src_la = struct.unpack('!H', data[8:10])[0]
payload = struct.pack('!HHHIB',
src_la, GATEWAY_LA, 0x0000, 0x00000000, 0x10)
sock.sendall(build_header(0x0006, len(payload)) + payload)
print(f" Routing Activation: tester LA={src_la:#06x}")
elif ptype == 0x8001: # Diagnostic Message
src = struct.unpack('!H', data[8:10])[0]
tgt = struct.unpack('!H', data[10:12])[0]
uds = data[12:]
print(f" DiagMsg: {src:#06x} → {tgt:#06x}, UDS: {uds.hex()}")
# Positive ACK gönder
ack_pl = struct.pack('!HHB', src, tgt, 0x00)
sock.sendall(build_header(0x8002, len(ack_pl)) + ack_pl)
sock.close()
tcp_srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcp_srv.bind((GATEWAY_IP, GATEWAY_PORT))
tcp_srv.listen(5)
print(f"DoIP Gateway simülatörü dinliyor: {GATEWAY_PORT}")
while True:
c, a = tcp_srv.accept()
threading.Thread(target=handle_tcp_client, args=(c, a), daemon=True).start()
End-of-Line (EoL) DoIP Flash Akışı
Araç üretim hattında son kontrol istasyonunda ECU'lar programlanır. Bu süreç şu adımları izler:
EoL Test Sistemi Araç DoIP Gateway
│ │
│── UDP: Vehicle Identification ─────────►│ (araç kimliğini doğrula)
│◄─ VehicleAnnouncement (VIN) ────────────│
│ │
│── TCP: Connect + Routing Activation ───►│
│◄─ Routing Activated ────────────────────│
│ │
│ [Her ECU için] │
│── UDS: 10 02 (Programming Session) ────►│ ECU LA
│── UDS: 27 11/12 (SecurityAccess) ──────►│
│── UDS: 34 (RequestDownload) ────────────►│
│── UDS: 36 (TransferData × N) ───────────►│ firmware blokları
│── UDS: 37 (TransferExit) ───────────────►│
│── UDS: 31 (CheckProgrammingDependency) ─►│
│── UDS: 11 01 (ECU Reset) ───────────────►│
│ │
│ [Flash sonrası doğrulama] │
│── UDS: 22 F101 (SW Version oku) ────────►│ yeni versiyon kontrolü
│◄─ 62 F101 [yeni versiyon] ──────────────│
DoIP üzerinden UDS konusunda daha fazla bilgi için UDS rehberini incele. AUTOSAR Adaptive sistemlerde DoIP gateway'i yapılandırmak için AUTOSAR Adaptive rehberine bak. Araç sinyal verilerini standartlaştırmak için VSS rehberini incele.