AUTOSAR SOME/IP: PHP parsing library

SOME/IP (Scalable service-Oriented MiddlewarE over IP) is an automotive/embedded communication protocol which supports remoteprocedure calls, event notifications and the underlying serialization/wire format.

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.9

This page hosts a formal specification of AUTOSAR SOME/IP using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

PHP source code to parse AUTOSAR SOME/IP

SomeIp.php

<?php
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

/**
 * SOME/IP (Scalable service-Oriented MiddlewarE over IP) is an automotive/embedded
 * communication protocol which supports remoteprocedure calls, event notifications
 * and the underlying serialization/wire format.
 */

namespace {
    class SomeIp extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \Kaitai\Struct\Struct $_parent = null, \SomeIp $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_header = new \SomeIp\Header($this->_io, $this, $this->_root);
            switch ($this->header()->messageId()->value()) {
                case 4294934784:
                    $this->_m__raw_payload = $this->_io->readBytes(($this->header()->length() - 8));
                    $_io__raw_payload = new \Kaitai\Struct\Stream($this->_m__raw_payload);
                    $this->_m_payload = new \SomeIpSd($_io__raw_payload);
                    break;
                default:
                    $this->_m_payload = $this->_io->readBytes(($this->header()->length() - 8));
                    break;
            }
        }
        protected $_m_header;
        protected $_m_payload;
        protected $_m__raw_payload;
        public function header() { return $this->_m_header; }
        public function payload() { return $this->_m_payload; }
        public function _raw_payload() { return $this->_m__raw_payload; }
    }
}

namespace SomeIp {
    class Header extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \SomeIp $_parent = null, \SomeIp $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__raw_messageId = $this->_io->readBytes(4);
            $_io__raw_messageId = new \Kaitai\Struct\Stream($this->_m__raw_messageId);
            $this->_m_messageId = new \SomeIp\Header\MessageId($_io__raw_messageId, $this, $this->_root);
            $this->_m_length = $this->_io->readU4be();
            $this->_m__raw_requestId = $this->_io->readBytes(4);
            $_io__raw_requestId = new \Kaitai\Struct\Stream($this->_m__raw_requestId);
            $this->_m_requestId = new \SomeIp\Header\RequestId($_io__raw_requestId, $this, $this->_root);
            $this->_m_protocolVersion = $this->_io->readU1();
            $this->_m_interfaceVersion = $this->_io->readU1();
            $this->_m_messageType = $this->_io->readU1();
            $this->_m_returnCode = $this->_io->readU1();
        }
        protected $_m_isValidServiceDiscovery;

        /**
         * auxillary value
         */
        public function isValidServiceDiscovery() {
            if ($this->_m_isValidServiceDiscovery !== null)
                return $this->_m_isValidServiceDiscovery;
            $this->_m_isValidServiceDiscovery =  (($this->messageId()->value() == 4294934784) && ($this->protocolVersion() == 1) && ($this->interfaceVersion() == 1) && ($this->messageType() == \SomeIp\Header\MessageTypeEnum::NOTIFICATION) && ($this->returnCode() == \SomeIp\Header\ReturnCodeEnum::OK)) ;
            return $this->_m_isValidServiceDiscovery;
        }
        protected $_m_messageId;
        protected $_m_length;
        protected $_m_requestId;
        protected $_m_protocolVersion;
        protected $_m_interfaceVersion;
        protected $_m_messageType;
        protected $_m_returnCode;
        protected $_m__raw_messageId;
        protected $_m__raw_requestId;

        /**
         * The Message ID shall be a 32 Bit identifier that is used to identify
         * the RPC call to a method of an application or to identify an event.
         */
        public function messageId() { return $this->_m_messageId; }

        /**
         * [PRS_SOMEIP_00042] Length field shall contain the length in Byte
         * starting from Request ID/Client ID until the end of the SOME/IP message.
         */
        public function length() { return $this->_m_length; }

        /**
         * The Request ID allows a provider and subscriber to differentiate
         * multiple parallel uses of the same method, event, getter or setter.
         */
        public function requestId() { return $this->_m_requestId; }

        /**
         * The Protocol Version identifies the used SOME/IP Header format
         * (not including the Payload format).
         */
        public function protocolVersion() { return $this->_m_protocolVersion; }

        /**
         * Interface Version shall be an 8 Bit field that contains the
         * MajorVersion of the Service Interface.
         */
        public function interfaceVersion() { return $this->_m_interfaceVersion; }

        /**
         * The Message Type field is used to differentiate different types of
         * messages.
         */
        public function messageType() { return $this->_m_messageType; }

        /**
         * The Return Code shall be used to signal whether a request was
         * successfully processed.
         */
        public function returnCode() { return $this->_m_returnCode; }
        public function _raw_messageId() { return $this->_m__raw_messageId; }
        public function _raw_requestId() { return $this->_m__raw_requestId; }
    }
}

/**
 * [PRS_SOMEIP_00035] The assignment of the Message ID shall be up to
 * the user. However, the Message ID shall be unique for the whole
 * system (i.e. the vehicle). TheMessage ID is similar to a CAN ID and
 * should be handled via a comparable process.
 * [PRS_SOMEIP_00038] Message IDs of method calls shall be structured in
 * the ID with 2^16 services with 2^15 methods.
 */

namespace SomeIp\Header {
    class MessageId extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \SomeIp\Header $_parent = null, \SomeIp $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_serviceId = $this->_io->readU2be();
            $this->_m_subId = $this->_io->readBitsIntBe(1) != 0;
            if ($this->subId() == false) {
                $this->_m_methodId = $this->_io->readBitsIntBe(15);
            }
            if ($this->subId() == true) {
                $this->_m_eventId = $this->_io->readBitsIntBe(15);
            }
        }
        protected $_m_value;

        /**
         * The value provides the undissected Message ID
         */
        public function value() {
            if ($this->_m_value !== null)
                return $this->_m_value;
            $_pos = $this->_io->pos();
            $this->_io->seek(0);
            $this->_m_value = $this->_io->readU4be();
            $this->_io->seek($_pos);
            return $this->_m_value;
        }
        protected $_m_serviceId;
        protected $_m_subId;
        protected $_m_methodId;
        protected $_m_eventId;

        /**
         * Service ID
         */
        public function serviceId() { return $this->_m_serviceId; }

        /**
         * Single bit to flag, if there is a Method or a Event ID
         */
        public function subId() { return $this->_m_subId; }

        /**
         * Method ID
         */
        public function methodId() { return $this->_m_methodId; }

        /**
         * Event ID
         */
        public function eventId() { return $this->_m_eventId; }
    }
}

/**
 * The Request ID allows a provider and subscriber to differentiate
 * multiple parallel usesof the same method, event, getter or setter.
 */

namespace SomeIp\Header {
    class RequestId extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \SomeIp\Header $_parent = null, \SomeIp $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_clientId = $this->_io->readU2be();
            $this->_m_sessionId = $this->_io->readU2be();
        }
        protected $_m_value;

        /**
         * The value provides the undissected Request ID
         */
        public function value() {
            if ($this->_m_value !== null)
                return $this->_m_value;
            $_pos = $this->_io->pos();
            $this->_io->seek(0);
            $this->_m_value = $this->_io->readU4be();
            $this->_io->seek($_pos);
            return $this->_m_value;
        }
        protected $_m_clientId;
        protected $_m_sessionId;
        public function clientId() { return $this->_m_clientId; }
        public function sessionId() { return $this->_m_sessionId; }
    }
}

namespace SomeIp\Header {
    class MessageTypeEnum {
        const REQUEST = 0;
        const REQUEST_NO_RETURN = 1;
        const NOTIFICATION = 2;
        const REQUEST_ACK = 64;
        const REQUEST_NO_RETURN_ACK = 65;
        const NOTIFICATION_ACK = 66;
        const RESPONSE = 128;
        const ERROR = 129;
        const RESPONSE_ACK = 192;
        const ERROR_ACK = 193;
    }
}

namespace SomeIp\Header {
    class ReturnCodeEnum {
        const OK = 0;
        const NOT_OK = 1;
        const UNKNOWN_SERVICE = 2;
        const UNKNOWN_METHOD = 3;
        const NOT_READY = 4;
        const NOT_REACHABLE = 5;
        const TIME_OUT = 6;
        const WRONG_PROTOCOL_VERSION = 7;
        const WRONG_INTERFACE_VERSION = 8;
        const MALFORMED_MESSAGE = 9;
        const WRONG_MESSAGE_TYPE = 10;
    }
}