# Scalable Service-Oriented Middleware over IP

Scalable Service-Oriented Middleware over IP (SOME/IP) ist eine Kommunikationsmiddleware im Automobilbereich, welche unter anderem in AUTOSAR verwendet wird. SOME/IP ist die einzige Lösung, welche seit Anfang der Adaptive Plattform beide AUTOSAR-Plattformen unterstützte. Hierdurch ist SOME/IP als Middleware für Ethernet-Kommunikation im Fahrzeug sehr weit verbreitet.
Veröffentlichungen zu SOME/IP sind bereits ab 2011 im Rahmen des BMBF-geförderten SEIS-Projekts erschienen.
Die ersten AUTOSAR-Spezifikationen von SOME/IP wurden 2013 als Teil der Classic Platform (Version 4.1) veröffentlicht.

## Bestandteile von SOME/IP

SOME/IP selbst umfasst mehrere Kernanteile:
* SOME/IP – Serialisierung und Nachrichtenaustausch.
* SOME/IP-SD – Service Discovery (SD) und Publish/Subscribe.
* SOME/IP-TP – Transport Protocol (TP) zur Segmentierung großer Nachrichten.
Die SOME/IP-Serialisierung wurde sehr stark auf Ressourcenbedarf optimiert, um mit wenigen Speicher- und CPU-Ressourcen auszukommen. Daher wurde eine binäre und nicht beschreibende Form der Serialisierung genutzt.
Später wurde eine inkompatible, proprietäre Erweiterung zu einer TLV-ähnlichen Serialisierung definiert. Diese Erweiterung versucht, durch eine TLV-ähnliche Serialisierung mehr Flexibilität auf Kosten des Ressourcenbedarfs der Serialisierung zu erreichen.

## Grundlagen

SOME/IP beruht auf einer serviceorientierten Kommunikation. Steuergeräte fungieren hierbei sowohl als Clients als auch als Server und können damit selber sogenannte Services anbieten oder Services von anderen Steuergeräten anfordern. Im Gegensatz zur signalorientierten Datenübertragung werden hier Nachrichten nur bei Bedarf verschickt. Der Vorteil hierbei liegt in der deutlich reduzierten Buslast. Diese Art der Übertragung setzt allerdings voraus, dass ein Server über jeden Client Bescheid weiß, der Bedarf angefordert hat.
* Ein Client kann mittels einer SOME/IP-SD-Nachricht einen Service abonnieren, also Bedarf an einem Service zeigen. Der Server kann diese Anfrage entweder positiv oder negativ bestätigen. Bei einer positiven Bestätigung speichert sich der Server die Verbindungsdaten des Clients und kann diesen bei Bedarf informieren. Ein Client kann über zwei Wege herausfinden, welche Services innerhalb seines Netzwerkes angeboten werden. Über eine SOME/IP-SD-Find-Service-Nachricht kann er aktiv selber im Netzwerk nach bestimmten Services nachfragen. Bietet ein Server diesen Service an, kann er darauf antworten. Zusätzlich kann ein Server mittels SOME/IP-SD-Offer-Service-Nachrichten seine angebotenen Services an alle Clients per Broadcast versenden. Die Teilnehmer (Clients) erhalten somit passiv die im Netzwerk angebotenen Services.
* Ein Client kann auch ohne Abonnement Anfragen an einen Server senden. Im Gegensatz zu abonnierten Inhalten, bei denen der Client meistens bei Änderung der Daten jedes Mal automatisch eine Antwort erhalten will, benötigt der Client hierbei eine direkte einmalige Antwort. Auch Anfragen, die keine Antwort erfordern, sind dabei möglich.
SOME/IP ist damit das erste Protokoll im Automotive-Bereich, welches sich nicht des klassischen Ansatzes der signalbasierten Kommunikation wie CAN/LIN/FlexRay oder MOST bedient.

## Service Discovery

Das SOME/IP-SD-Protokoll (Service Discovery) regelt das Bereitstellen von Services sowie das Senden von Events. Es wurde entworfen, um die effiziente Unicast-Kommunikation mittels SOME/IP zu gewährleisten. Der Datenverkehr auf dem Bus kann damit minimiert und die allgemeine Last verringert werden. Um diese Anforderungen gewährleisten zu können, beinhaltet Service Discovery folgendes Set an Nachrichten, die gesendet werden können:
* Find Service – sucht eine Service Instance.
* Offer Service – publiziert eine Service Instance.
* Stop Offer Service – stoppt die Verfügbarkeit einer Service Instance.
* Subscribe Eventgroup – abonniert die Events und Fields einer Eventgroup.
* Stop Subscribe Eventgroup – stoppt ein Subscribe Eventgroup Entry.
* Subscribe Eventgroup Ack – bestätigt ein Subscribe Eventgroup Entry.
* Subscribe Eventgroup Nack – lehnt ein Subscribe Eventgroup Entry ab.

## Botschaften
### SOME/IP

Eine SOME/IP Botschaft kann in Header und Payload getrennt werden. Innerhalb der Payload können wiederum Daten im Type-Length-Value-Format beziehungsweise im Length-Value-Format vorkommen.

#### Header

Der Header beinhaltet dabei folgende Informationen:
* 32-Bits Message-ID, welche die Nachricht einem genauen Service und einer Methode zuordnet.
* 32-Bits Längenfeld, welches die Länge an Bytes der nachfolgenden Informationen beinhaltet.
* 32-Bits Request-ID, welche die Nachricht einem Client und einer Session-ID zuordnet.
* 8-Bits Protocol Version
* 8-Bits Interface Version
* 8-Bits Message Type, welche eine Unterscheidung der verschiedenen Nachrichtentypen beinhaltet
| Number | Value | Description |
| 0x00 | REQUEST | Request der eine Antwort erwartet |
| 0x01 | REQUEST_NO_RETURN | Request der keine Antwort erwartet |
| 0x02 | NOTIFICATION | Notification die keine Antwort erwartet |
| 0x08 | RESPONSE | Antwort |
| 0x81 | ERROR | Antwort mit einem Fehler |
| 0x20 | TP_REQUEST | TP Request der eine Antwort erwartet |
| 0x21 | TP_REQUEST_NO_RETURN | TP Request der keine Antwort erwartet |
| 0x22 | TP_NOTIFICATION | TP Notification die keine Antwort erwartet |
| 0xa0 | TP_RESPONSE | TP Antwort |
| 0xa1 | TP_ERROR | TP Antwort mit einem Fehler |
* 8-Bits Return Code, welcher anzeigt ob ein Request korrekt verarbeitet wurde
| Message Type | Erlaubter Return-Code |
| REQUEST | 0x00 |
| REQUEST_NO_RETURN | 0x00 |
| NOTIFICATION | 0x00 |
| RESPONSE | Weitere Infos in |
| ERROR | ungleich 0x00, weitere Infos in |

#### Payload

Eine SOME/IP Payload besteht aus Daten im TLV Format. Es können sowohl komplexe Datentypen als auch einfache Datentypen verwendet werden.
Folgende einfache Datentypen können verwendet werden:
* boolean: 8 bit Feld welches nur Werte von 0 (False) oder 1 (True) annehmen kann.
* uint8: unsigned integer mit 8 bit Größe.
* uint16: unsigned integer mit 16 bit Größe.
* uint32: unsigned integer mit 32 bit Größe.
* uint64: unsigned integer mit 64 bit Größe.
* sint8: signed integer mit 8 bit Größe.
* sint16: signed integer mit 16 bit Größe.
* sint32: signed integer mit 32 bit Größe.
* sint64: signed integer mit 64 bit Größe.
* float32: floating point Nummern mit 32 bit Größe.
* float64: floating point Nummern mit 64 bit Größe.
Folgende komplexe Datentypen können verwendet werden:
* struct: Eine Datenstruktur, welche eine vordefinierte Anzahl an weiteren komplexen und/oder einfachen Datentypen enthält.
* string: Character String, der typischerweise Daten im ASCII, UTF-8, oder UTF-16 Format beinhaltet. Strings mit dynamischer Länge beinhaltet ein Längenfeld zu Beginn
* array: Eine Datenstruktur, die nur Elemente des gleichen Typs enthält. Es kann sich dabei um ein statisches Array mit fester Länge handeln oder um ein dynamisches Array mit variabler Länge. Für dynamische Arrays wird ein Längenfeld benutzt.
* enumeration: an uint with the option of naming different values.
* bitfield: 8, 16, or 32bit Parameter bei welchem jeder Bitwert einen Boolean Wert repräsentiert.
* union: Ein Parameter, welcher gleichzeitig als verschiedene Datentypen interpretiert werden kann.
Das Tag im TLV Format setzt sich in AUTOSAR aus einem Wiretype, der Daten-ID und einem potentiellen Längenfeld zusammen. Handelt es sich um einen einfach Datentyp (Wire Type 0-3), kann das Längenfeld wegfallen, da die Länge des Datentyps bereits durch den Wire Type selber definiert ist. Folgende Wire Types sind definiert:
| Wire Type | Following Data |
| 0 | 8 Bit Data Base Datatype |
| 1 | 16 Bit Data Base Datatype |
| 2 | 32 Bit Data Base Datatype |
| 3 | 64 Bit Data Base Datatype |
| 4 | Complex Data Type: Array, Struct, String, Union with length field of static size (configured in data definition) |
| 5 | Complex Data Type: Array, Struct, String, Union with length field size 1 byte (ignore static definition) |
| 6 | Complex Data Type: Array, Struct, String, Union with length field size 2 byte (ignore static definition) |
| 7 | Complex Data Type: Array, Struct, String, Union with length field size 4 byte (ignore static definition) |

### SOME/IP-SD

Service Discovery setzt auf dem SOME/IP-Protokoll auf und verwendet die bereits genannten Header-Elemente des SOME/IP-Headers (mit Ausnahme von Message-ID und dem Längenfeld). Zusätzlich kommt darauffolgend ein 1-Byte-Feld mit diversen Flags. Die nachfolgenden 3 Bytes sind reserviert und nicht in Verwendung. In der Payload sind Entry Arrays vorhanden. Die Anzahl dieser ist durch ein vorangestelltes Längenfeld definiert. Nachfolgend kommt zusätzlich ein Options Array ebenfalls mit vorangestelltem Längenfeld.
In Entry Arrays können zwei Typen auftreten, jeweils für Services oder für Eventgroups.
Ein Entry Array Element für Services beinhaltet folgende Felder:
* 8-Bits Type, welcher entweder Find (0x00) oder Offer (0x01) annehmen kann
* 8-Bits Index, welcher den ersten Index im Options Entry für den ersten Durchlauf beinhaltet
* 8-Bits Index, welcher den ersten Index im Options Entry für den zweiten Durchlauf beinhaltet
* 4-Bits Anzahl der Optionen 1ter Durchlauf
* 4-Bits Anzahl der Optionen 2ter Durchlauf
* 16-Bits Service-ID
* 16-Bit Instance-ID
* 16-Bits Major Version
* 24-Bits Time To Live
* 32-Bits Minor Version
Ein Entry Array Element für Eventgroups beinhaltet folgende Felder:
* 8-Bits Type, welcher entweder SubscribeEventgroup/StopSubscribeEventgroup (0x06) oder SubscribeEventgroupNack/SubscribeEventgroupAck (0x07) annehmen kann
* 8-Bits Index, welcher den ersten Index im Options Entry für den ersten Durchlauf beinhaltet
* 8-Bits Index, welcher den ersten Index im Options Entry für den zweiten Durchlauf beinhaltet
* 4-Bits Anzahl der Optionen 1ter Durchlauf
* 4-Bits Anzahl der Optionen 2ter Durchlauf
* 16-Bits Service-ID
* 16-Bit Instance-ID
* 16-Bits Major Version
* 24-Bits Time To Live
* 16-Bits Reserviert
* 16-Bits Eventgroup-ID
Ein Option Array kann zusätzliche Informationen für die einzelnen Entrys beinhalten. Es beinhaltet folgende Elemente:
* 8-Bits Längenfeld, welches die Länge an Bytes des Konfigurationsstrings beinhaltet.
* 4-Bits Type, mit statischem Wert 0x01
* 4-Bits reserviert, mit statischem Wert 0x00
* Null terminierter Konfigurationsstring
Ein Konfigurationsstring beinhaltet Elemente die dem Format [Länge][Key][=][Value] entsprechen. Terminiert wird der String mit einem Längenfeld des Wertes 0, dass keine nachfolgenden Elemente angibt.