How to Implement Client-Server Communication
Client-server is one of the multiple ways a Software Component is allowed to communicate at the VFB level, as described in the post (Types of Interfaces and Ports)[https://www.autosartoday.com/posts/types_of_interfaces_and_ports (opens in a new tab)].
Client-server communication is a form of API exchange at the VFB (Virtual Function Bus) level, used to provide functionalities from a Software Component (server) to one or more Software Components to consume (clients). A single interface can be used to provide multiple operations, which translate to C APIs, where each one has input, output and / or in-out arguments, again, just as a C function does. A PortPrototype
typed by a ClientServerInterface
is represented at the VFB level via a semi-circle, for a required port, or a circle, for a provided port, as seen in the picture below:
The port icons that represent server (left) and client (right) PortPrototypes
Client Behavior
A runnable can invoke a client-server operation connected to a require-port of its enclosing Software Component, synchronously, via a SynchronousServerCallPoint
, or asynchronously, via an AsynchronousServerCallPoint
(but an operation cannot be used by both at the same time). An operation can also take part on the same Software Component. Each of these call points reference a ClientServerOperation
of an RPortPrototype
.
The ServerCallPoints
cannot be executed concurrently. If the call point is being used, it must be completed or returns with an error before it can be invoked again.
The serverCallPoints
for the same operation that are part of the same Software Component must also define the same value for returnValueProvision
, because the RTE generates the call point API once per Software Component (this also applies to the AsynchronousServerCallResultPoints
in the same conditions). The timeout attribute must also have the same value.
In a SynchronousServerCallPoint
, the call is blocking, meaning your runnable will not execute further until the respective call point is completed.
Client-Server communication via a SynchronousServerCallPoint
An AsynchronousServerCallPoint
is defined by the runnable to trigger the execution of the operation. A response is returned via an AsynchronousServerCallReturnsEvent
, which can also be associated with a WaitPoint
, effectively blocking the runnable until the event is raised.
If a WaitPoint
is not defined, the runnable executes until completion independently of the ClientServerOperation
. Three elements need to be defined: an AsynchronousServerCallReturnsEvent
, referencing a runnable that serves as a callback, which defines an AsynchronousServerCallResultPoint
, where the results of the operation are retrieved (and is also referenced by the AsynchronousServerCallReturnsEvent
) and an AsynchronousServerCallPoint
, which references the operation and the AsynchronousServerCallResultPoint
. This process can be observed in the figure below:
Client-Server communication via an AsynchronousServerCallPoint and an AsynchronousServerCallReturnsEvent triggering another runnable
An AsynchronousServerCallPoint
can only be referenced once by an AsynchronousServerCallResultPoint
, which means the runnable defining the AsynchronousServerCallResultPoint
can retrieve the result of the operation. The call result point must also only be referenced by one AsynchronousServerCallReturnsEvent
.
If the AsynchronousServerCallPoint
is not referenced by any result point, it means the result is not fetched and the result can be considered irrelevant by the RTE generator.
When the runnable calling the AsynchronousServerCallPoint
must wait for the result, then a WaitPoint
can be created, referring to the AsynchronousServerCallReturnsEvent
that is associated with the AsynchronousServerCallResultPoint
. The event does not reference a runnable via its startOnEvent
attribute. In this configuration, the WaitPoint
and the AsynchronousServerCallResultPoint
must be part of the same runnable.
Client-Server communication via an AsynchronousServerCallPoint and an AsynchronousServerCallReturnsEvent unlocking a WaitPoint
Meta-Model Elements Relevant to Client-Server Communication
There are a few meta-model elements relevant to the implementation of client-server communication: ClientServerInterface
, ClientServerOperation
, RunnableEntity
, OperationInvokedEvent
, SynchronousServerCallPoint
and AsynchronousServerCallPoint
. There are others, especially when you delve into inter-ECU communication, which requires data transformations.
For the sake of simplicity, we will consider the meta-classes for intra-ECU communication in this article. If you want to complement your learning, do read our post SomeIpXf Overview - SOME/IP Messages and VFB Serialization in Autosar (opens in a new tab), where you can learn in detail how client-server communication is serialized to be communicated via SOME/IP over a network.
ClientServerInterface
A ClientServerInterface
is inherited from the PortInterface meta-class and includes the following attributes:
-
Operation – An aggregation of the
ClientServerOperations
of thisClientServerInterface
. These operations cannot be reused by another client-server interface. These do not need to be ordered within the client-server interface. -
PossibleError – An aggregation of the
ApplicationErrors
that are part of theClientServerInterface
.
The PortInterface
meta-class defines the properties:
-
IsService – Boolean that indicates the
PortInterface
is used for service-based communication, which involves at least on one side of the connection aServiceSwComponentPrototype
. -
ServiceKind – Enumeration that indicates the service provider, in case of a service
PortInterface
. It can take values according to the different BSW modules that are located at the Services layer (if you need refreshing over the Autosar layers, read our post Guide to the Classic Autosar Architecture (opens in a new tab)). This information is used to distinguish between standardized and vendor-specific Autosar services, which can have repercussions on the build process of both Software Components andPortInterfaces
.
ClientServerOperation
Each ClientServerOperation
is comprised of the following elements:
-
Argument – An ordered (which reflects in the order of the generated API call for the operation) aggregation of the
ArgumentDataPrototypes
of this operation. There are no optional arguments in an operation. This argument cannot be a reference to another operation. It is also not possible to define default values for the arguments. -
DiagArgIntegrity – Boolean that indicates if the operation is used to implement diagnostic routines, which implies that the input and output arguments share the same buffer, which can result in the input arguments being overwritten upon writing to an output argument. By setting this element to true, the operation is aware a shared buffer is employed and takes the necessary precautions to ensure the input arguments are not unintentionally overwritten.
-
PossibleError – Multiple references to the different
ApplicationErrors
that can be returned upon calling this operation. The referencedApplicationErrors
are owned by the respectiveClientServerInterface
.
The ArgumentDataPrototype
element is used to define the arguments of an operation, similarly to a data element, while adding direction information over the argument. It can be based on the AutosarDataPrototype
and DataPrototype
classes and sets up the elements:
-
Direction – An enumeration that indicates the direction of the argument. The possible values are
in
,inout
andout
. A value must be provided to all arguments of directionin
andinout
when invoking an operation. It is expected that the server sets a value to allinout
and out arguments when the operation is completed. -
ServerArgumentImplPolicy – Enumeration that indicates the how the argument type of the
RunnableEntity
of the server is implemented. The possible values areuseArgumentType
, where the argument type of the runnable is derived from theAutosarDataType
of theArgumentDataPrototype
(default value) oruseVoid
(which is not allowed for in arguments typed byAutosarDataTypes
that are translated into a C primitive data type), where the argument type of the runnable isvoid
. This element is used together with the information from the referredAutosarDataTypes
by the RTE to generate the data types of the arguments of theClientServerOperation
.
Client-server communication errors can be divided into two different types:
-
Infrastructure Errors – Faults not related to the Software Components themselves but with the infrastructure that enables the communication, such as timeouts or bus faults. These errors are defined by the RTE and are usually not raised by the components themselves. Such errors are implicitly a part of the VFB and do not need be described by the implementer, but reactive measures need to be taken, nonetheless.
-
Application errors – Errors related to the Software Component functionality being implemented, and therefore should be described within the respective
ClientServerInterfaces
. Since the symbol names for such errors are generated by the RTE, if two differentPortPrototypes
are typed by a client-server interface with the sameshortName
, theApplicationErrors
with the sameshortName
must also share the sameerrorCode
number.
The ApplicationError
element sets up the following property:
- ErrorCode – An integer value that reflects in the generated error code value by the RTE. This value can only be of a certain range, specified by the RTE.
OperationInvokedEvent
On the Software Component defining the provider ports typed by ClientServerInterfaces
, each ClientServerOperation
is attached to a runnable that is invoked via an OperationInvokedEvent
. The OperationInvokedEvent
meta-class is not allowed to define disabledModes
because the RTE does not support disabling the server via modes. If such functionality is desired, the server itself should implement it within its logic.
It is based on the RTEEvent
meta-class and defines the attribute:
- operation – An instance-reference to a
ClientServerOperation
that is invoked through this event. It is implemented via aPOperationInAtomicSwcInstanceRef
.
The RTEEvent
meta-class is also an abstract class, serving multiple kinds of events involving the RTE. From the VFB perspective, a RunnableEntity
can interact with RTE events in two ways: by the event enabling a runnable and via a WaitPoint
, blocking a runnable until a specific RTE event occurs. It defines the attributes:
-
disabledMode – Multiple instance-references of the
ModeDeclarations
for the modes in which this event is disabled. It is implemented viaRModeInAtomicSwcInstanceRefs
. -
startOnEvent – A reference to the
RunnableEntity
that starts when this event is triggered. The RTE is responsible for activating the runnable in response to the event.
The RModeInAtomicSwcInstanceRef
instance-reference contains the attributes:
-
base – A reference to an
AtomicSwComponentType
that serves as the base. -
contextModeDeclarationGroupPrototype – A reference to the applicable
ModeDeclarationGroupPrototype
. -
contextPort – A reference to an
AbstractRequiredPortPrototype
where the mode declaration comes from. -
targetModeDeclaration – A reference to the target
ModeDeclaration
.
SynchronousServerCallPoint and AsynchronousServerCallPoint
The ServerCallPoint
is the abstract meta-class that serves the base for the SynchronousServerCallPoints
and AsynchronousServerCallPoints
. It is inherited from the AbstractAccessPoint
meta-class and contains the properties:
-
operation – An instance-reference to the
ClientServerOperation
called by the runnable at this call point. It is implemented by anROperationInAtomicSwcInstanceRef
. -
timeout – A
TimeValue
that defines the limit for the server to perform the operation, returning an error after that time. If it is an asynchronous call point, it raises an event, otherwise it sets a return value.
The ROperationInAtomicSwcInstanceRef
is defined by the properties:
-
contextRPort – A reference to the required-port containing the operation.
-
targetRequiredOperation – A reference to the
ClientServerOperation
targeted.
The SynchronousServerCallPoint
meta-class is defined by the property:
- calledFromWithinExclusiveArea – A reference to the
ExclusiveAreaNestingOrder
, defining the exclusive area order where this call point is inserted.
The AsynchronousServerCallPoint
meta-class does not define further properties. The AsynchronousServerCallResultPoint
meta-class defines the property:
- asynchronousServerCallPoint – A reference to the
AsynchronousServerCallPoint
to which the results correspond to.
WaitPoint
The WaitPoint
meta-class defines a blocking point where a runnable must wait for an RTE event to proceed further (or a timeout period to expire). The presence of wait points in a runnable makes it a CAT2 runnable. The only events allowed to reference a runnable containing a WaitPoint
are DataReceivedEvent
, DataSendCompletedEvent
, ModeSwitchedAckEvent
and AsynchronousServerCallReturnsEvent
or reference disabledModes
. A CAT2 runnable cannot implement a mode switch because mode switches should be completed within a finite timing, and this is not guaranteed when in the presence of a WaitPoint. It is comprised by the attributes:
-
timeout – A
TimeValue
, in seconds, for the wait point to time out and the function call corresponding to the wait point to return with an error value. -
trigger – A reference to the
RTEEvent
which is waited for. The same event can take part in multipleWaitPoints
referenced by multiple runnables.
RunnableEntity
The RunnableEntity
meta-class specifies the properties:
-
argument – An ordered aggregation of multiple
RunnableEntityArguments
, defining input arguments for the runnable. -
asynchronousServerCallResultPoint – The aggregation of multiple
AsynchronousServerCallResultPoints
, allowing the runnable to retrieve the result for its asynchronous server calls. It is subject to variability because its existence depends on the implementation itself and the presence of the respective ports. -
canBeInvokedConcurrently –
Boolean
that indicates if the runnable can be called concurrently, even for the same instance of the respective Software Component. Setting this value to true requires special attention to account for concurrency, especially considering there is no way to put a ceiling on how many instances are allowed at the same time in the Autosar meta-model. A prime candidate are those runnables that can be handled completely within the scope of a local function, where the context of the client is used, but generally all source code called by multiple runnables should be reentrant. On the other hand, the RTE ensures the runnable is not invoked concurrently. -
dataReadAccess – An aggregation of multiple
VariableAccess
elements, denoting the implicit read access to elements of a sender-receiver or non-volatile data interfaces. It is subject to variability because it depends on the existence of the respective ports. -
dataReceivePointByArgument – The aggregation of multiple
VariableAccesses
, denoting explicit read access to elements contained in sender-receiver or non-volatile data interfaces. Since the data is explicitly read, the result is provided to the runnable as an argument in the function requiring the data. It is also subject to variability due to the conditional existence of ports, and it also depends on the implementation. -
dataReceivePointByValue – The aggregation of multiple
VariableAccess
elements, defining explicit read access to elements of sender-receiver or non-volatile data interfaces, this time providing the results via the return value of the explicit read call. It is subject to variability for the same reasons as thedataReceivePointByArgument
attribute. -
dataSendPoint – The aggregation of multiple
VariableAccess
elements, specifying explicit write access to elements of sender-receiver or non-volatile data interfaces. It is subject to variability because the existence of ports is also variable and is also dependent on the implementation itself. -
dataWriteAccess – The aggregation of multiple
VariableAccess
elements, this time defining implicit write access to elements of sender-receiver and non-volatile data interfaces. It is subject to variability for the same reasons as thedataSendPoint
attribute. -
externalTriggeringPoint – The aggregation of multiple
ExternalTriggeringPoints
, used to raiseExternalTriggerOccurredEvents
, via a connectedTrigger
port. It is variable because it depends on the implementation itself. -
internalTriggeringPoint – The aggregation of multiple
InternalTriggeringPoints
, used to trigger the execution of runnables that are part of this Software Component. It is also variable because it depends on the implementation. -
modeAccessPoint – The aggregation of multiple
ModeAccessPoints
, gaining read access to the current active mode. It is subject to variability because it depends on the implementation needs. -
modeSwitchPoint – The aggregation of multiple
ModeSwitchPoints
, allowing the Software Component that takes the role of a mode user to request a mode switch. It is subject to variability as it depends on the implementation. -
parameterAccess – The aggregation of multiple
ParameterAccess
elements, denoting read access toParameterDataPrototypes
that exist locally or provided by a port typed by aParameterInterface
. It is subject to variability as the respective ports and local parameters might not take part in the implementation. -
readLocalVariable – The aggregation of multiple
VariableAccess
elements, indicating read access to inter-runnable variables (both implicit and explicit). It is subject to variability depending on the implementation and the existence of the inter-runnable variables. -
serverCallPoint – The aggregation of multiple
ServerCallPoints
, denoting the client-server operations the runnable invokes. It is subject to variability because the ports may or may not exist in the implementation. -
symbol – A
CIdentifier
that defines the C API name that implements the runnable. -
waitPoint – The aggregation of multiple
WaitPoints
, places where the runnable waits for an RTE event. It must be unique within a singleEcuInstance
. -
writtenLocalVariable – The aggregation of multiple VariableAccess elements, denoting write access to inter-runnable variables (both implicit and explicit). It is subject to variability, depending on the implementation and existence of inter-runnable variables.
Closing Thoughts
This is almost everything you need to know when it comes to client-server communication. After reading this article, all you need to is practice! I recommend you pick up an Autosar ARXML design tool and connect the pieces together.
Do not forget to place yourself on the waiting list for the upcoming ebooks and see you next time!
Author: Micael Coutinho (opens in a new tab)
References:
© AutosarToday —@LinkedIn