서비스 지향 통신으로 전환하려면 서비스를 조회·요청하는 절차 자체를 규정하는 프로토콜이 있어야 한다. 자동차 도메인에서 이 역할은 SOME/IP(Scalable service-Oriented MiddlewarE over IP)가 맡는다 — AUTOSAR가 서로 다른 운영체제·하드웨어에서 동작하는 ECU 사이의 원격 함수 호출과 이벤트 통지를 지원하도록 규정한 미들웨어다[1].
Note
SOME/IP는 원래 BMW가 사내 프로젝트로 개발한 프로토콜이며, 이후 AUTOSAR 표준으로 채택됐다[2].
RPC와 Proxy·Skeleton
SOME/IP가 지원하는 핵심 기능은 RPC(Remote Procedure Call)다. 클라이언트가 자신이 아닌 원격 컴퓨터의 프로세스(함수)를 네트워크 너머로 호출하고 결과를 돌려받는 방식으로, 호출 측은 파라미터를 담은 호출 메시지를 보내고 결과 메시지를 받을 때까지 대기한다[3]. 기존 범용 RPC 기술은 임베디드 ECU가 감당하기 어려운 자원을 요구했기 때문에, AUTOSAR는 이 제약에 맞춰 SOME/IP를 새로 규정했다[1].
AUTOSAR Adaptive Platform은 이 RPC 관계를 Proxy와 Skeleton 한 쌍으로 코드에 구현하는 고전적인 미들웨어 패턴을 따른다 — 클라이언트 애플리케이션은 원격 서비스를 대신하는 로컬 객체인 Proxy를 통해 마치 로컬 함수처럼 서비스를 호출하고, 서버 애플리케이션은 실제 구현을 미들웨어 전송 계층에 연결하는 Skeleton으로 이 호출을 받는다. Proxy와 Skeleton 사이에서 호출을 네트워크 너머로 옮기고 응답을 되돌리는 실제 통신은 SOME/IP가 맡는다[4].
메시지 형식
SOME/IP 메시지는 16바이트 고정 헤더 뒤에 가변 길이 Payload가 붙는 구조다. 상호운용성을 위해 헤더 레이아웃은 모든 구현에서 동일해야 하며, 필드는 왼쪽 위부터 전송 순서로 배치된다[1].
Message ID[32비트]는 상위 16비트 Service ID와 하위 16비트 Method ID로 나뉜다 — Method ID의 최상위 비트가 0이면 메서드(0x0000~0x7FFF), 1이면 이벤트·알림(0x8000~0x8FFF)을 가리키는 것이 관례다[1].
Length[32비트]는 Request ID부터 메시지 끝까지의 바이트 수를 담는다. Request ID[32비트]는 ECU 안에서 호출자를 구분하는 Client ID(16비트)와 같은 클라이언트의 연속 호출을 구분하는 Session ID(16비트)로 나뉜다 — 서버가 요청의 Request ID를 그대로 복사해 응답에 담으므로, 클라이언트는 동시에 여러 요청을 보내도 응답을 올바른 요청과 짝지을 수 있다[1].
Protocol Version[8비트]은 헤더 형식 자체의 버전으로 현재 0x01로 고정되고, Interface Version[8비트]은 서비스 인터페이스의 Major 버전을 담아 명세 불일치를 검출하는 데 쓰인다[1].
Message Type[8비트]은 메시지 종류를 구분한다[1]:
| 값 | 이름 | 의미 |
|---|---|---|
| 0x00 | REQUEST | 응답을 기대하는 요청(반환값이 void여도) |
| 0x01 | REQUEST_NO_RETURN | 응답을 기대하지 않는 Fire & Forget 요청 |
| 0x02 | NOTIFICATION | 응답을 기대하지 않는 알림·이벤트 콜백 |
| 0x80 | RESPONSE | 응답 메시지 |
| 0x81 | ERROR | 오류를 담은 응답 메시지 |
이 다섯 가지 Message Type이 실제로 어떻게 조합되어 Request/Response·Fire & Forget·Notification 같은 통신 패턴을 이루는지는 SOME/IP Communication Patterns에서 다룬다.
Return Code[8비트]는 요청 처리 결과를 담는다. 헤더를 단순하게 유지하기 위해 모든 메시지가 이 필드를 갖지만, 실제 값이 실리는 것은 RESPONSE·ERROR 타입뿐이고 나머지 타입은 0x00으로 고정된다[1]:
| 값 | 이름 | 의미 |
|---|---|---|
| 0x00 | E_OK | 오류 없음 |
| 0x01 | E_NOT_OK | 특정되지 않은 오류 |
| 0x02 | E_UNKNOWN_SERVICE | 요청한 Service ID를 알 수 없음 |
| 0x03 | E_UNKNOWN_METHOD | Service ID는 알지만 Method ID를 알 수 없음 |
| 0x04 | E_NOT_READY | Service ID·Method ID는 알지만 애플리케이션이 실행 중이 아님 |
| 0x05 | E_NOT_REACHABLE | 서비스를 실행 중인 시스템에 도달할 수 없음(내부 오류 코드) |
| 0x06 | E_TIMEOUT | 타임아웃 발생(내부 오류 코드) |
| 0x07 | E_WRONG_PROTOCOL_VERSION | 지원하지 않는 SOME/IP 프로토콜 버전 |
| 0x08 | E_WRONG_INTERFACE_VERSION | 인터페이스 버전 불일치 |
| 0x09 | E_MALFORMED_MESSAGE | 역직렬화 오류로 Payload를 해석할 수 없음 |
| 0x0a | E_WRONG_MESSAGE_TYPE | 예상과 다른 Message Type 수신(예: REQUEST로 정의된 메서드에 REQUEST_NO_RETURN 수신) |
0x0b 이상 값은 향후 SOME/IP 표준이 정의할 범용 오류나, 인터페이스 명세가 서비스·메서드별로 정의하는 오류로 예약되어 있다[1].
Payload[가변 크기]는 실제 파라미터를 담으며, 전송 계층에 따라 한계가 다르다 — UDP는 0~1400바이트, TCP는 세그먼테이션을 지원해 더 큰 메시지도 전달한다[1]. 파라미터를 Payload 바이트열로 바꾸는 규칙은 SOME/IP Serialization에서 다룬다.
헤더 필드는 예외 없이 네트워크 바이트 순서(빅 엔디안)로 인코딩된다. Payload 안 파라미터의 바이트 순서는 인터페이스 정의로 설정할 수 있지만, 구조 해석에 쓰이는 길이·타입 메타데이터 필드는 설정과 무관하게 항상 빅 엔디안이어야 한다[1].
설계 목표
AUTOSAR는 SOME/IP를 다음 목표에 맞춰 설계했다[1]:
- 임베디드 환경의 엄격한 자원 제약을 만족할 것
- 가능한 한 다양한 use-case·통신 파트너와 호환될 것
- 최소한 wire-format 수준에서 AUTOSAR와 호환될 것 — AUTOSAR가 표준 수정 없이 그대로 송수신할 수 있는 PDU로 통신
- 자동차 use-case가 요구하는 기능을 제공할 것
- 작은 시스템부터 큰 시스템까지 확장 가능(scalable)할 것
이 목표에 따라 SOME/IP는 AUTOSAR·GENIVI·OSEK은 물론 운영체제가 없는 임베디드 장치에서도 구현되도록 규정되어 있고[1], AUTOSAR PDU와 호환되는 wire-format 덕분에 SOME/IP 메시지는 Socket Adaptor 이하 스택을 그대로 거쳐 전송된다.