diff --git a/CHANGELOG.md b/CHANGELOG.md
index dc40a50..38d23fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,13 +11,17 @@ Non-collectable elements are various sub-elements to collectable elements.
#### XML Port interface elements
+* ClientServerInterface | CLIENT-SERVER-INTERFACE | `collectable`
* NvDataInterface | NV-DATA-INTERFACE | `collectable`
* ParameterInterface | PARAMETER-INTERFACE | `collectable`
* SenderReceiverInterface | SENDER-RECEIVER-INTERFACE | `collectable`
+* ApplicationError | APPLICATION-ERROR
+* ClientServerOperation | CLIENT-SERVER-OPERATION
* InvalidationPolicy | INVALIDATION-POLICY
#### XML - Data type elements
+* ArgumentDataPrototype | ARGUMENT-DATA-PROTOTYPE
* ParameterDataPrototype | PARAMETER-DATA-PROTOTYPE
* VariableDataPrototype | VARIABLE-DATA-PROTOTYPE
diff --git a/examples/xml/port_interface/client_server_interface.py b/examples/xml/port_interface/client_server_interface.py
new file mode 100644
index 0000000..b7127de
--- /dev/null
+++ b/examples/xml/port_interface/client_server_interface.py
@@ -0,0 +1,73 @@
+"""
+Sender-receiver port interface examples
+"""
+import os
+import autosar
+import autosar.xml.element as ar_element
+import autosar.xml.enumeration as ar_enum
+
+
+def create_platform_types(packages: dict[str, ar_element.Package]):
+ """
+ Creates necessary platform types
+ """
+ uint8_base_type = ar_element.SwBaseType('uint8', size=8)
+ packages["PlatformBaseTypes"].append(uint8_base_type)
+ uint32_base_type = ar_element.SwBaseType('uint32', size=32)
+ packages["PlatformBaseTypes"].append(uint32_base_type)
+ sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint8_base_type.ref())
+ uint8_impl_type = ar_element.ImplementationDataType("uint8",
+ category="VALUE",
+ sw_data_def_props=sw_data_def_props)
+ packages["PlatformImplementationDataTypes"].append(uint8_impl_type)
+ sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint32_base_type.ref())
+ uint32_impl_type = ar_element.ImplementationDataType("uint32",
+ category="VALUE",
+ sw_data_def_props=sw_data_def_props)
+ packages["PlatformImplementationDataTypes"].append(uint32_impl_type)
+
+
+def create_port_interfaces(packages: dict[str, ar_element.Package]):
+ """
+ Creates interface with one element
+ """
+ uint32_impl_type = packages["PlatformImplementationDataTypes"].find("uint32")
+ interface = ar_element.ClientServerInterface("FreeRunningTimer_I", is_service=True)
+ operation = interface.make_operation("GetTimeStamp")
+ operation.make_out_argument("value",
+ ar_enum.ServerArgImplPolicy.USE_ARGUMENT_TYPE,
+ type_ref=uint32_impl_type.ref())
+ packages["PortInterfaces"].append(interface)
+
+
+def save_xml_files(workspace: autosar.xml.Workspace):
+ """
+ Saves workspace as XML documents
+ """
+ interface_document_path = os.path.abspath(os.path.join(os.path.dirname(
+ __file__), 'data', 'client_server_interface.arxml'))
+ platform_document_path = os.path.abspath(os.path.join(os.path.dirname(
+ __file__), 'data', 'platform.arxml'))
+ workspace.create_document(interface_document_path, packages="/PortInterfaces")
+ workspace.create_document(platform_document_path, packages="/AUTOSAR_Platform")
+ workspace.write_documents()
+
+
+def main():
+ """
+ Main
+ """
+ workspace = autosar.xml.Workspace()
+ packages = dict(zip(["PlatformBaseTypes",
+ "PlatformImplementationDataTypes",
+ "PortInterfaces"],
+ workspace.make_packages("AUTOSAR_Platform/BaseTypes",
+ "AUTOSAR_Platform/ImplementationDataTypes",
+ "PortInterfaces")))
+ create_platform_types(packages)
+ create_port_interfaces(packages)
+ save_xml_files(workspace)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/xml/port_interface/data/client_server_interface.arxml b/examples/xml/port_interface/data/client_server_interface.arxml
new file mode 100644
index 0000000..50cba23
--- /dev/null
+++ b/examples/xml/port_interface/data/client_server_interface.arxml
@@ -0,0 +1,27 @@
+
+
+
+
+ PortInterfaces
+
+
+ FreeRunningTimer_I
+ true
+
+
+ GetTimeStamp
+
+
+ value
+ /AUTOSAR_Platform/ImplementationDataTypes/uint32
+ OUT
+ USE-ARGUMENT-TYPE
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/xml/port_interface/data/platform.arxml b/examples/xml/port_interface/data/platform.arxml
index 98f0ffd..536a4a8 100644
--- a/examples/xml/port_interface/data/platform.arxml
+++ b/examples/xml/port_interface/data/platform.arxml
@@ -11,6 +11,10 @@
uint8
8
+
+ uint32
+ 32
+
@@ -27,6 +31,17 @@
+
+ uint32
+ VALUE
+
+
+
+ /AUTOSAR_Platform/BaseTypes/uint32
+
+
+
+
diff --git a/examples/xml/port_interface/nv_data_interface.py b/examples/xml/port_interface/nv_data_interface.py
index 6519499..64221f1 100644
--- a/examples/xml/port_interface/nv_data_interface.py
+++ b/examples/xml/port_interface/nv_data_interface.py
@@ -12,11 +12,18 @@ def create_platform_types(packages: dict[str, ar_element.Package]):
"""
uint8_base_type = ar_element.SwBaseType('uint8', size=8)
packages["PlatformBaseTypes"].append(uint8_base_type)
+ uint32_base_type = ar_element.SwBaseType('uint32', size=32)
+ packages["PlatformBaseTypes"].append(uint32_base_type)
sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint8_base_type.ref())
uint8_impl_type = ar_element.ImplementationDataType("uint8",
category="VALUE",
sw_data_def_props=sw_data_def_props)
packages["PlatformImplementationDataTypes"].append(uint8_impl_type)
+ sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint32_base_type.ref())
+ uint32_impl_type = ar_element.ImplementationDataType("uint32",
+ category="VALUE",
+ sw_data_def_props=sw_data_def_props)
+ packages["PlatformImplementationDataTypes"].append(uint32_impl_type)
def create_nv_data_interface_with_one_element(packages: dict[str, ar_element.Package]):
diff --git a/examples/xml/port_interface/parameter_interface.py b/examples/xml/port_interface/parameter_interface.py
index 01176de..c2a9532 100644
--- a/examples/xml/port_interface/parameter_interface.py
+++ b/examples/xml/port_interface/parameter_interface.py
@@ -12,11 +12,18 @@ def create_platform_types(packages: dict[str, ar_element.Package]):
"""
uint8_base_type = ar_element.SwBaseType('uint8', size=8)
packages["PlatformBaseTypes"].append(uint8_base_type)
+ uint32_base_type = ar_element.SwBaseType('uint32', size=32)
+ packages["PlatformBaseTypes"].append(uint32_base_type)
sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint8_base_type.ref())
uint8_impl_type = ar_element.ImplementationDataType("uint8",
category="VALUE",
sw_data_def_props=sw_data_def_props)
packages["PlatformImplementationDataTypes"].append(uint8_impl_type)
+ sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint32_base_type.ref())
+ uint32_impl_type = ar_element.ImplementationDataType("uint32",
+ category="VALUE",
+ sw_data_def_props=sw_data_def_props)
+ packages["PlatformImplementationDataTypes"].append(uint32_impl_type)
def create_parameter_interface_with_one_parameter(packages: dict[str, ar_element.Package]):
diff --git a/examples/xml/port_interface/sender_receiver_interface.py b/examples/xml/port_interface/sender_receiver_interface.py
index 2c6140d..360089b 100644
--- a/examples/xml/port_interface/sender_receiver_interface.py
+++ b/examples/xml/port_interface/sender_receiver_interface.py
@@ -12,11 +12,18 @@ def create_platform_types(packages: dict[str, ar_element.Package]):
"""
uint8_base_type = ar_element.SwBaseType('uint8', size=8)
packages["PlatformBaseTypes"].append(uint8_base_type)
+ uint32_base_type = ar_element.SwBaseType('uint32', size=32)
+ packages["PlatformBaseTypes"].append(uint32_base_type)
sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint8_base_type.ref())
uint8_impl_type = ar_element.ImplementationDataType("uint8",
category="VALUE",
sw_data_def_props=sw_data_def_props)
packages["PlatformImplementationDataTypes"].append(uint8_impl_type)
+ sw_data_def_props = ar_element.SwDataDefPropsConditional(base_type_ref=uint32_base_type.ref())
+ uint32_impl_type = ar_element.ImplementationDataType("uint32",
+ category="VALUE",
+ sw_data_def_props=sw_data_def_props)
+ packages["PlatformImplementationDataTypes"].append(uint32_impl_type)
def create_implementation_data_types(packages: dict[str, ar_element.Package]):
diff --git a/run_examples.cmd b/run_examples.cmd
index 15b8374..7a89eac 100644
--- a/run_examples.cmd
+++ b/run_examples.cmd
@@ -11,6 +11,7 @@ python examples\xml\unit\unit.py
python examples\xml\port_interface\nv_data_interface.py
python examples\xml\port_interface\parameter_interface.py
python examples\xml\port_interface\sender_receiver_interface.py
+python examples\xml\port_interface\client_server_interface.py
python examples\generator\data_types\gen_type_defs_scalar.py
python examples\generator\data_types\gen_type_defs_array.py
python examples\generator\data_types\gen_type_defs_record.py
diff --git a/src/autosar/xml/element.py b/src/autosar/xml/element.py
index b73909b..6089c7f 100644
--- a/src/autosar/xml/element.py
+++ b/src/autosar/xml/element.py
@@ -562,6 +562,20 @@ def _accepted_subtypes(self) -> set[ar_enum.IdentifiableSubTypes]:
"""Acceptable values for dest"""
return {ar_enum.IdentifiableSubTypes.VARIABLE_DATA_PROTOTYPE}
+
+class ApplicationErrorRef(BaseRef):
+ """
+ Reference to ApplicationError
+ tag variants: 'POSSIBLE-ERROR-REF'
+ """
+
+ def __init__(self, value: str) -> None:
+ super().__init__(value, ar_enum.IdentifiableSubTypes.APPLICATION_ERROR)
+
+ def _accepted_subtypes(self) -> set[ar_enum.IdentifiableSubTypes]:
+ """Acceptable values for dest"""
+ return {ar_enum.IdentifiableSubTypes.APPLICATION_ERROR}
+
# Documentation Elements
@@ -2153,10 +2167,31 @@ class ParameterDataPrototype(VariableDataPrototype):
Type: Concrete
Tag variants: 'PARAMETER-DATA-PROTOTYPE' | 'ROM-BLOCK'
- This is identical in functionality to VariableDataPrototype, hence the inheritance.
+ This is identical in behavior to VariableDataPrototype, hence the inheritance.
"""
+class ArgumentDataPrototype(AutosarDataPrototype):
+ """
+ Complex type AR:ARGUMENT-DATA-PROTOTYPE
+ Type: Concrete
+ Tag variants: 'ARGUMENT-DATA-PROTOTYPE'
+ """
+
+ def __init__(self,
+ name: str,
+ direction: ar_enum.ArgumentDirection | None = None,
+ server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.direction: ar_enum.ArgumentDirection | None = None # .DIRECTION
+ self.server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None # .SERVER-ARGUMENT-IMPL-POLICY
+ # .TYPE-BLUEPRINTS not supported
+ # .VARIATION-POINT not supported
+ self._assign_optional("direction", direction, ar_enum.ArgumentDirection)
+ self._assign_optional("server_arg_impl_policy", server_arg_impl_policy, ar_enum.ServerArgImplPolicy)
+
+
class ApplicationDataType(AutosarDataType):
"""
Group AR:APPLICATION-DATA-TYPE
@@ -3119,6 +3154,220 @@ def make_parameter(self,
return data_element
+class ApplicationError(Identifiable):
+ """
+ Complex type AR:APPLICATION-ERROR
+ Tag variants: 'APPLICATION-ERROR'
+ """
+
+ def __init__(self,
+ name: str,
+ error_code: int | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.error_code: int | None = None
+ self._assign_optional_strict("error_code", error_code, int)
+
+
+class ClientServerOperation(Identifiable):
+ """
+ Complex type AR:CLIENT-SERVER-OPERATION
+ Tag variants: 'CLIENT-SERVER-OPERATION'
+ """
+
+ def __init__(self,
+ name: str,
+ arguments: ArgumentDataPrototype | list[ArgumentDataPrototype] | None = None,
+ diag_arg_integrity: bool | None = None,
+ fire_and_forget: bool | None = None,
+ possible_error_refs: ApplicationErrorRef | list[ApplicationErrorRef] | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.arguments: list[ArgumentDataPrototype] = [] # .ARGUMENTS
+ self.diag_arg_integrity: bool | None = None # .DIAG-ARG-INTEGRITY
+ self.fire_and_forget: bool | None = None # .FIRE-AND-FORGET
+ # .POSSIBLE-AP-ERROR-REFS not supported
+ # .POSSIBLE-AP-ERROR-SET-REFS not supported
+ self.possible_error_refs: list[ApplicationErrorRef] = [] # .POSSIBLE-ERROR-REFS
+ # .VARIATION-POINT not supported
+
+ self._assign_optional_strict("diag_arg_integrity", diag_arg_integrity, bool)
+ self._assign_optional_strict("fire_and_forget", fire_and_forget, bool)
+ if arguments is not None:
+ if isinstance(arguments, ArgumentDataPrototype):
+ self.append_argument(arguments)
+ elif isinstance(arguments, list):
+ for argument in arguments:
+ self.append_argument(argument)
+ else:
+ msg = f"parameters: Invalid type '{str(type(arguments))}'"
+ raise TypeError(msg + ". Expected 'ArgumentDataPrototype' or list[ArgumentDataPrototype]")
+
+ if possible_error_refs is not None:
+ if isinstance(possible_error_refs, ApplicationErrorRef):
+ self.append_argument(arguments)
+ elif isinstance(possible_error_refs, list):
+ for possible_error_ref in possible_error_refs:
+ self.append_possible_error_ref(possible_error_ref)
+ else:
+ msg = f"possible_error_refs: Invalid type '{str(type(possible_error_refs))}'"
+ raise TypeError(msg + ". Expected 'ApplicationErrorRef' or list[ApplicationErrorRef]")
+
+ def append_argument(self, argument: ArgumentDataPrototype) -> None:
+ """
+ Appends argument to internal list of arguments
+ """
+ if isinstance(argument, ArgumentDataPrototype):
+ self.arguments.append(argument)
+ else:
+ msg = f"argument: Invalid type '{str(type(argument))}'"
+ raise TypeError(msg + ". Expected 'ArgumentDataPrototype'")
+
+ def make_argument(self,
+ name: str,
+ direction: ar_enum.ArgumentDirection | None = None,
+ server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None,
+ **kwargs) -> ArgumentDataPrototype:
+ """
+ Convenience method for adding a new argument to this operation
+ """
+ argument = ArgumentDataPrototype(name, direction, server_arg_impl_policy, **kwargs)
+ self.append_argument(argument)
+ return argument
+
+ def make_in_argument(self,
+ name: str,
+ server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None,
+ **kwargs) -> ArgumentDataPrototype:
+ """
+ Convenience method for adding a new in-argument to this operation
+ """
+ argument = ArgumentDataPrototype(name, ar_enum.ArgumentDirection.IN, server_arg_impl_policy, **kwargs)
+ self.append_argument(argument)
+ return argument
+
+ def make_inout_argument(self,
+ name: str,
+ server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None,
+ **kwargs) -> ArgumentDataPrototype:
+ """
+ Convenience method for adding a new inout-argument to this operation
+ """
+ argument = ArgumentDataPrototype(name, ar_enum.ArgumentDirection.INOUT, server_arg_impl_policy, **kwargs)
+ self.append_argument(argument)
+ return argument
+
+ def make_out_argument(self,
+ name: str,
+ server_arg_impl_policy: ar_enum.ServerArgImplPolicy | None = None,
+ **kwargs) -> ArgumentDataPrototype:
+ """
+ Convenience method for adding a new out-argument to this operation
+ """
+ argument = ArgumentDataPrototype(name, ar_enum.ArgumentDirection.OUT, server_arg_impl_policy, **kwargs)
+ self.append_argument(argument)
+ return argument
+
+ def append_possible_error_ref(self, possible_error_ref: ApplicationErrorRef) -> None:
+ """
+ Appends error reference to internal list of possible errors for this operation
+ """
+ if isinstance(possible_error_ref, ApplicationErrorRef):
+ self.possible_error_refs.append(possible_error_ref)
+ else:
+ msg = f"argument: Invalid type '{str(type(possible_error_ref))}'"
+ raise TypeError(msg + ". Expected 'ApplicationErrorRef'")
+
+ def make_possible_error_ref(self, value: str) -> ApplicationErrorRef:
+ """
+ Convenience method for creating and adding a new possible error reference to this operation
+ """
+ possible_error_ref = ApplicationErrorRef(value)
+ self.append_possible_error_ref(possible_error_ref)
+ return possible_error_ref
+
+
+class ClientServerInterface(PortInterface):
+ """
+ Complex type AR:CLIENT-SERVER-INTERFACE
+ Tag variants: 'CLIENT-SERVER-INTERFACE'
+ """
+
+ def __init__(self,
+ name: str,
+ operations: ClientServerOperation | list[ClientServerOperation] | None = None,
+ possible_errors: ApplicationError | list[ApplicationError] | None = None,
+ **kwargs) -> None:
+ super().__init__(name, **kwargs)
+ self.operations: list[ClientServerOperation] = []
+ self.possible_errors: list[ApplicationError] = []
+
+ if operations is not None:
+ if isinstance(operations, ClientServerOperation):
+ self.append_operation(operations)
+ elif isinstance(operations, list):
+ for operation in operations:
+ self.append_operation(operation)
+ else:
+ msg = f"operations: Invalid type '{str(type(operations))}'"
+ raise TypeError(msg + ". Expected 'ClientServerOperation' or list[ClientServerOperation]")
+
+ if possible_errors is not None:
+ if isinstance(possible_errors, ApplicationError):
+ self.append_operation(possible_errors)
+ elif isinstance(possible_errors, list):
+ for possible_error in possible_errors:
+ self.append_possible_errors(possible_error)
+ else:
+ msg = f"possible_errors: Invalid type '{str(type(possible_errors))}'"
+ raise TypeError(msg + ". Expected 'ApplicationError' or list[ApplicationError]")
+
+ def append_operation(self, operation: ClientServerOperation) -> None:
+ """
+ Appends operation to internal list of operations
+ """
+ if isinstance(operation, ClientServerOperation):
+ self.operations.append(operation)
+ else:
+ msg = f"operation: Invalid type '{str(type(operation))}'"
+ raise TypeError(msg + ". Expected 'ClientServerOperation'")
+
+ def append_possible_errors(self, possible_error: ApplicationError) -> None:
+ """
+ Appends possible error to internal list of possible errors
+ """
+ if isinstance(possible_error, ApplicationError):
+ self.possible_errors.append(possible_error)
+ else:
+ msg = f"operation: Invalid type '{str(type(possible_error))}'"
+ raise TypeError(msg + ". Expected 'ApplicationError'")
+
+ def make_operation(self,
+ name: str,
+ arguments: ArgumentDataPrototype | list[ArgumentDataPrototype] | None = None,
+ diag_arg_integrity: bool | None = None,
+ fire_and_forget: bool | None = None,
+ possible_error_refs: ApplicationErrorRef | list[ApplicationErrorRef] | None = None,
+ **kwargs) -> ClientServerOperation:
+ """
+ Convenience method for creating a new operation in this port interface
+ """
+ operation = ClientServerOperation(name, arguments, diag_arg_integrity, fire_and_forget, possible_error_refs,
+ **kwargs)
+ self.append_operation(operation)
+ return operation
+
+ def make_possible_error(self,
+ name: str,
+ error_code: int | None = None,
+ **kwargs) -> ApplicationError:
+ """
+ Convenience-method for creating a new possible error in this port interface
+ """
+ possible_error = ApplicationError(name, error_code, **kwargs)
+ self.append_possible_errors(possible_error)
+ return possible_error
+
# !!UNFINISHED!! Component Types
diff --git a/src/autosar/xml/enumeration.py b/src/autosar/xml/enumeration.py
index b843d16..1b46ab1 100644
--- a/src/autosar/xml/enumeration.py
+++ b/src/autosar/xml/enumeration.py
@@ -10,6 +10,16 @@
import autosar.xml.exception as ar_exception
+class ArgumentDirection(Enum):
+ """
+ AR:ARGUMENT-DIRECTION-ENUM--SIMPLE
+ """
+
+ IN = 0
+ INOUT = 1
+ OUT = 2
+
+
class ArrayImplPolicy(Enum):
"""
AR:ARRAY-IMPL-POLICY-ENUM--SIMPLE
@@ -151,20 +161,21 @@ class IdentifiableSubTypes(Enum):
APPLICATION_ASSOC_MAP_DATA_TYPE = 2
APPLICATION_COMPOSITE_DATA_TYPE = 3
APPLICATION_DATA_TYPE = 4
- APPLICATION_DEFERRED_DATA_TYPE = 5
- APPLICATION_PRIMITIVE_DATA_TYPE = 6
- APPLICATION_RECORD_DATA_TYPE = 7
- AUTOSAR_DATA_TYPE = 8
- BSW_MODULE_ENTRY = 9
- COMPU_METHOD = 10
- CONSTANT_SPECIFICATION = 11
- DATA_CONSTR = 12
- IMPLEMENTATION_DATA_TYPE = 13
- PHYSICAL_DIMENSION = 14
- SW_ADDR_METHOD = 15
- SW_BASE_TYPE = 16
- UNIT = 17
- VARIABLE_DATA_PROTOTYPE = 18
+ APPLICATION_ERROR = 5
+ APPLICATION_DEFERRED_DATA_TYPE = 6
+ APPLICATION_PRIMITIVE_DATA_TYPE = 7
+ APPLICATION_RECORD_DATA_TYPE = 8
+ AUTOSAR_DATA_TYPE = 9
+ BSW_MODULE_ENTRY = 10
+ COMPU_METHOD = 11
+ CONSTANT_SPECIFICATION = 12
+ DATA_CONSTR = 13
+ IMPLEMENTATION_DATA_TYPE = 14
+ PHYSICAL_DIMENSION = 15
+ SW_ADDR_METHOD = 16
+ SW_BASE_TYPE = 17
+ UNIT = 18
+ VARIABLE_DATA_PROTOTYPE = 19
class IntervalType(Enum):
@@ -391,6 +402,16 @@ class ScaleConstraintValidity(Enum):
VALID = 3
+class ServerArgImplPolicy(Enum):
+ """
+ AR:SERVER-ARGUMENT-IMPL-POLICY-ENUM--SIMPLE
+ """
+
+ USE_ARGUMENT_TYPE = 0
+ USE_ARRAY_BASED_TYPE = 1
+ USE_VOID = 2
+
+
class ServiceKind(Enum):
"""
SERVICE-PROVIDER-ENUM--SIMPLE
@@ -497,6 +518,11 @@ class VersionedTextValue:
###
xml_to_enum_map = {
+ "ArgumentDirection": {
+ "IN": ArgumentDirection.IN,
+ "INOUT": ArgumentDirection.INOUT,
+ "OUT": ArgumentDirection.OUT,
+ },
"ArrayImplPolicy": {
"PAYLOAD-AS-ARRAY": VersionedEnumValue(ArrayImplPolicy.PAYLOAD_AS_ARRAY, {49, 50, 51}),
"PAYLOAD-AS-POINTER-TO-ARRAY": VersionedEnumValue(ArrayImplPolicy.PAYLOAD_AS_POINTER_TO_ARRAY, {49, 50, 51}),
@@ -557,6 +583,7 @@ class VersionedTextValue:
"APPLICATION-ASSOC-MAP-DATA-TYPE": IdentifiableSubTypes.APPLICATION_ASSOC_MAP_DATA_TYPE,
"APPLICATION-COMPOSITE-DATA-TYPE": IdentifiableSubTypes.APPLICATION_COMPOSITE_DATA_TYPE,
"APPLICATION-DATA-TYPE": IdentifiableSubTypes.APPLICATION_DATA_TYPE,
+ "APPLICATION-ERROR": IdentifiableSubTypes.APPLICATION_ERROR,
"APPLICATION-DEFERRED-DATA-TYPE": IdentifiableSubTypes.APPLICATION_DEFERRED_DATA_TYPE,
"APPLICATION-PRIMITIVE-DATA-TYPE": IdentifiableSubTypes.APPLICATION_PRIMITIVE_DATA_TYPE,
"APPLICATION-RECORD-DATA-TYPE": IdentifiableSubTypes.APPLICATION_RECORD_DATA_TYPE,
@@ -742,6 +769,11 @@ class VersionedTextValue:
"NOT-VALID": ScaleConstraintValidity.NOT_VALID,
"VALID": ScaleConstraintValidity.VALID
},
+ "ServerArgImplPolicy": {
+ "USE-ARGUMENT-TYPE": ServerArgImplPolicy.USE_ARGUMENT_TYPE,
+ "USE-ARRAY-BASE-TYPE": ServerArgImplPolicy.USE_ARRAY_BASED_TYPE,
+ "USE-VOID": ServerArgImplPolicy.USE_VOID
+ },
"SwCalibrationAccess": {
"NOT-ACCESSIBLE": SwCalibrationAccess.NOT_ACCESSIBLE,
"READ-ONLY": SwCalibrationAccess.READ_ONLY,
@@ -777,6 +809,11 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
enum_to_xml_map = {
+ "ArgumentDirection": [
+ "IN", # 0
+ "INOUT", # 1
+ "OUT", # 2
+ ],
"ArrayImplPolicy": [
VersionedTextValue("PAYLOAD-AS-ARRAY", {49, 50, 51}), # 0
VersionedTextValue("PAYLOAD-AS-POINTER-TO-ARRAY", {49, 50, 51}), # 1
@@ -832,20 +869,21 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
"APPLICATION-ASSOC-MAP-DATA-TYPE", # 2
"APPLICATION-COMPOSITE-DATA-TYPE", # 3
"APPLICATION-DATA-TYPE", # 4
- "APPLICATION-DEFERRED-DATA-TYPE", # 5
- "APPLICATION-PRIMITIVE-DATA-TYPE", # 6
- "APPLICATION-RECORD-DATA-TYPE", # 7
- "AUTOSAR-DATA-TYPE", # 8
- "BSW-MODULE-ENTRY", # 9
- "COMPU-METHOD", # 10
- "CONSTANT-SPECIFICATION", # 11
- "DATA-CONSTR", # 12
- "IMPLEMENTATION-DATA-TYPE", # 13
- "PHYSICAL-DIMENSION", # 14
- "SW-ADDR-METHOD", # 15
- "SW-BASE-TYPE", # 16
- "UNIT", # 17
- "VARIABLE-DATA-PROTOTYPE" # 18
+ "APPLICATION-ERROR", # 5
+ "APPLICATION-DEFERRED-DATA-TYPE", # 6
+ "APPLICATION-PRIMITIVE-DATA-TYPE", # 7
+ "APPLICATION-RECORD-DATA-TYPE", # 8
+ "AUTOSAR-DATA-TYPE", # 9
+ "BSW-MODULE-ENTRY", # 10
+ "COMPU-METHOD", # 11
+ "CONSTANT-SPECIFICATION", # 12
+ "DATA-CONSTR", # 13
+ "IMPLEMENTATION-DATA-TYPE", # 14
+ "PHYSICAL-DIMENSION", # 15
+ "SW-ADDR-METHOD", # 16
+ "SW-BASE-TYPE", # 17
+ "UNIT", # 18
+ "VARIABLE-DATA-PROTOTYPE" # 19
],
"IntervalType": [
"CLOSED", # 0
@@ -1017,6 +1055,11 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
"NOT-VALID", # 2
"VALID" # 3
],
+ "ServerArgImplPolicy": [
+ "USE-ARGUMENT-TYPE", # 0
+ "USE-ARRAY-BASE-TYPE", # 1
+ "USE-VOID", # 2
+ ],
"SwCalibrationAccess": [
"NOT-ACCESSIBLE", # 0
"READ-ONLY", # 1
diff --git a/src/autosar/xml/reader.py b/src/autosar/xml/reader.py
index 4545a60..9fd27dc 100644
--- a/src/autosar/xml/reader.py
+++ b/src/autosar/xml/reader.py
@@ -127,6 +127,7 @@ def __init__(self,
'NV-DATA-INTERFACE': self._read_nv_data_interface,
'PARAMETER-INTERFACE': self._read_parameter_interface,
'SENDER-RECEIVER-INTERFACE': self._read_sender_receiver_interface,
+ 'CLIENT-SERVER-INTERFACE': self._read_client_server_interface,
# Unit elements
'UNIT': self._read_unit,
@@ -181,6 +182,7 @@ def __init__(self,
'SYMBOL-PROPS': self._read_symbol_props,
'IMPLEMENTATION-DATA-TYPE-ELEMENT': self._read_implementation_data_type_element,
'APPLICATION-RECORD-ELEMENT': self._read_application_record_element,
+ 'ARGUMENT-DATA-PROTOTYPE': self._read_argument_data_prototype,
'DATA-TYPE-MAP': self._read_data_type_map,
'SW-ARRAYSIZE': self._read_value_list,
# CalibrationData elements
@@ -193,6 +195,8 @@ def __init__(self,
'CONSTANT-REF': self._read_constant_ref,
# Port interface element
'INVALIDATION-POLICY': self._read_invalidation_policy,
+ 'APPLICATION-ERROR': self._read_application_error,
+ 'CLIENT-SERVER-OPERATION': self._read_client_server_operation,
}
self.switcher_all = {}
self.switcher_all.update(self.switcher_collectable)
@@ -1957,6 +1961,35 @@ def _read_variable_data_prototype_group(self, child_elements: ChildElementMap, d
pass
child_elements.skip('VARIATION-POINT') # Not supported
+ def _read_argument_data_prototype(self, elem: ElementTree.Element) -> ar_element.ArgumentDataPrototype:
+ """
+ Reads complex-type AR:ARGUMENT-DATA-PROTOTYPE
+ Type: Concrete
+ """
+ data = {}
+ child_elements = ChildElementMap(elem)
+ self._read_referrable(child_elements, data)
+ self._read_multi_language_referrable(child_elements, data)
+ self._read_identifiable(child_elements, elem.attrib, data)
+ self._read_data_prototype(child_elements, data)
+ self._read_autosar_data_prototype(child_elements, data)
+ self._read_argument_data_prototype_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ArgumentDataPrototype(**data)
+
+ def _read_argument_data_prototype_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:ARGUMENT-DATA-PROTOTYPE
+ """
+ xml_child = child_elements.get('DIRECTION')
+ if xml_child is not None:
+ data["direction"] = ar_enum.xml_to_enum("ArgumentDirection", xml_child.text)
+ xml_child = child_elements.get('SERVER-ARGUMENT-IMPL-POLICY')
+ if xml_child is not None:
+ data["server_arg_impl_policy"] = ar_enum.xml_to_enum("ServerArgImplPolicy", xml_child.text)
+ child_elements.skip("TYPE-BLUEPRINTS") # Not supported
+ child_elements.skip("VARIATION-POINT") # Not supported
+
# --- Reference elements
def _read_compu_method_ref(self, xml_elem: ElementTree.Element) -> ar_element.CompuMethodRef:
@@ -2135,6 +2168,20 @@ def _read_variable_data_prototype_ref(
raise ar_exception.ParseError(msg)
return ar_element.VariableDataPrototypeRef(xml_elem.text)
+ def _read_application_error_ref(
+ self,
+ xml_elem: ElementTree.Element) -> ar_element.ApplicationErrorRef:
+ """
+ Reads reference to ApplicationError
+ Type: Concrete
+ """
+ data = {}
+ self._read_base_ref_attributes(xml_elem.attrib, data)
+ if data['dest'] != 'APPLICATION-ERROR':
+ msg = f"Invalid value for DEST. Expected 'APPLICATION-ERROR', got '{data['dest']}'"
+ raise ar_exception.ParseError(msg)
+ return ar_element.ApplicationErrorRef(xml_elem.text)
+
def _read_base_ref_attributes(self, attr: dict, data: dict) -> None:
"""
Reads DEST attribute
@@ -2624,3 +2671,105 @@ def _read_invalidation_policy(self, xml_element: ElementTree.Element) -> ar_elem
if xml_child is not None:
data["handle_invalid"] = ar_enum.xml_to_enum("HandleInvalid", xml_child.text)
return ar_element.InvalidationPolicy(**data)
+
+ def _read_application_error(self, xml_element: ElementTree.Element) -> ar_element.ApplicationError:
+ """
+ Reads complex type AR:APPLICATION-ERROR
+ Tag variants: 'APPLICATION-ERROR'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_referrable(child_elements, data)
+ self._read_multi_language_referrable(child_elements, data)
+ self._read_identifiable(child_elements, xml_element.attrib, data)
+ self._read_application_error_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ApplicationError(**data)
+
+ def _read_application_error_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:APPLICATION-ERROR
+ """
+ xml_child = child_elements.get("ERROR-CODE")
+ if xml_child is not None:
+ data["error_code"] = self._read_integer(xml_child.text)
+
+ def _read_client_server_operation(self, xml_element: ElementTree.Element) -> ar_element.ClientServerOperation:
+ """
+ Reads complex type AR:CLIENT-SERVER-OPERATION
+ Tag variants: 'CLIENT-SERVER-OPERATION'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_referrable(child_elements, data)
+ self._read_multi_language_referrable(child_elements, data)
+ self._read_identifiable(child_elements, xml_element.attrib, data)
+ self._read_client_server_operation_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ClientServerOperation(**data)
+
+ def _read_client_server_operation_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:CLIENT-SERVER-OPERATION
+ """
+ xml_child = child_elements.get("ARGUMENTS")
+ if xml_child is not None:
+ arguments = []
+ data["arguments"] = arguments
+ for xml_grand_child in xml_child.findall("./*"):
+ if xml_grand_child.tag == "ARGUMENT-DATA-PROTOTYPE":
+ element = self._read_argument_data_prototype(xml_grand_child)
+ arguments.append(element)
+ xml_child = child_elements.get("DIAG-ARG-INTEGRITY")
+ if xml_child is not None:
+ data["diag_arg_integrity"] = self._read_boolean(xml_child.text)
+ xml_child = child_elements.get("FIRE-AND-FORGET")
+ if xml_child is not None:
+ data["fire_and_forget"] = self._read_boolean(xml_child.text)
+ child_elements.skip("POSSIBLE-AP-ERROR-REFS") # not supported
+ child_elements.skip("POSSIBLE-AP-ERROR-SET-REFS") # not supported
+ xml_child = child_elements.get("POSSIBLE-ERROR-REFS")
+ if xml_child is not None:
+ possible_error_refs = []
+ data["possible_error_refs"] = possible_error_refs
+ for xml_grand_child in xml_child.findall("./*"):
+ if xml_grand_child.tag == "POSSIBLE-ERROR-REF":
+ element = self._read_application_error_ref(xml_grand_child)
+ possible_error_refs.append(element)
+ child_elements.skip("VARIATION-POINT") # not supported
+
+ def _read_client_server_interface(self, xml_element: ElementTree.Element) -> ar_element.ClientServerInterface:
+ """
+ Reads complex type AR:CLIENT-SERVER-INTERFACE
+ Tag variants: 'CLIENT-SERVER-INTERFACE'
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_referrable(child_elements, data)
+ self._read_multi_language_referrable(child_elements, data)
+ self._read_identifiable(child_elements, xml_element.attrib, data)
+ self._read_port_interface(child_elements, data)
+ self._read_client_server_interface_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ return ar_element.ClientServerInterface(**data)
+
+ def _read_client_server_interface_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:CLIENT-SERVER-INTERFACE
+ """
+ xml_child = child_elements.get('OPERATIONS')
+ if xml_child is not None:
+ operations = []
+ data["operations"] = operations
+ for xml_grand_child in xml_child.findall('./*'):
+ if xml_grand_child.tag == 'CLIENT-SERVER-OPERATION':
+ element = self._read_client_server_operation(xml_grand_child)
+ operations.append(element)
+ xml_child = child_elements.get('POSSIBLE-ERRORS')
+ if xml_child is not None:
+ possible_errors = []
+ data["possible_errors"] = possible_errors
+ for xml_grand_child in xml_child.findall('./*'):
+ if xml_grand_child.tag == 'APPLICATION-ERROR':
+ element = self._read_application_error(xml_grand_child)
+ possible_errors.append(element)
diff --git a/src/autosar/xml/writer.py b/src/autosar/xml/writer.py
index c268d1a..5a067ae 100644
--- a/src/autosar/xml/writer.py
+++ b/src/autosar/xml/writer.py
@@ -205,6 +205,7 @@ def __init__(self) -> None:
'NvDataInterface': self._write_nv_data_interface,
'ParameterInterface': self._write_parameter_interface,
'SenderReceiverInterface': self._write_sender_receiver_interface,
+ 'ClientServerInterface': self._write_client_server_interface,
}
# Value specification elements
self.switcher_value_specification = {
@@ -259,6 +260,7 @@ def __init__(self) -> None:
'ValueList': self._write_value_list,
'VariableDataPrototype': self._write_variable_data_prototype,
'ParameterDataPrototype': self._write_parameter_data_prototype,
+ 'ArgumentDataPrototype': self._write_argument_data_prototype,
# CalibrationData elements
'SwValues': self._write_sw_values,
'SwAxisCont': self._write_sw_axis_cont,
@@ -269,6 +271,8 @@ def __init__(self) -> None:
'ConstantRef': self._write_constant_ref,
# Port interface element
'InvalidationPolicy': self._write_invalidation_policy,
+ 'ApplicationError': self._write_application_error,
+ 'ClientServerOperation': self._write_client_server_operation,
}
self.switcher_all = {} # All concrete elements (used for unit testing)
self.switcher_all.update(self.switcher_collectable)
@@ -1684,6 +1688,34 @@ def _write_parameter_data_prototype_group(self, elem: ar_element.ParameterDataPr
self._write_value_specification_element(elem.init_value)
self._leave_child()
+ def _write_argument_data_prototype(self, elem: ar_element.ArgumentDataPrototype) -> None:
+ """
+ Reads complex-type AR:ARGUMENT-DATA-PROTOTYPE
+ Type: Concrete
+ Tag variants: 'ARGUMENT-DATA-PROTOTYPE'
+ """
+ assert isinstance(elem, ar_element.ArgumentDataPrototype)
+ attr: TupleList = []
+ self._collect_identifiable_attributes(elem, attr)
+ self._add_child("ARGUMENT-DATA-PROTOTYPE", attr)
+ self._write_referrable(elem)
+ self._write_multilanguage_referrable(elem)
+ self._write_identifiable(elem)
+ self._write_data_prototype(elem)
+ self._write_autosar_data_prototype(elem)
+ self._write_argument_data_prototype_group(elem)
+ self._leave_child()
+
+ def _write_argument_data_prototype_group(self, elem: ar_element.ArgumentDataPrototype) -> None:
+ """
+ Reads group AR:ARGUMENT-DATA-PROTOTYPE
+ Type: Abstract
+ """
+ if elem.direction is not None:
+ self._add_content("DIRECTION", ar_enum.enum_to_xml(elem.direction))
+ if elem.server_arg_impl_policy is not None:
+ self._add_content("SERVER-ARGUMENT-IMPL-POLICY", ar_enum.enum_to_xml(elem.server_arg_impl_policy))
+
# --- Reference Elements
def _collect_base_ref_attr(self,
@@ -1855,7 +1887,18 @@ def _write_variable_data_prototype_ref(self, elem: ar_element.VariableDataProtot
self._collect_base_ref_attr(elem, attr)
self._add_content(tag, elem.value, attr)
-# Constant and value specifications
+ def _write_application_error_ref(self, elem: ar_element.ApplicationErrorRef, tag: str) -> None:
+ """
+ Writes reference to ApplicationError
+ Type: Concrete
+ Tag variants: 'POSSIBLE-ERROR-REF' | 'FIRST-APPLICATION-ERROR-REF' | 'SECOND-APPLICATION-ERROR-REF'
+ """
+ assert isinstance(elem, ar_element.ApplicationErrorRef)
+ attr: TupleList = []
+ self._collect_base_ref_attr(elem, attr)
+ self._add_content(tag, elem.value, attr)
+
+# -- Constant and value specifications
def _write_text_value_specification(self, elem: ar_element.TextValueSpecification) -> None:
"""
@@ -2047,7 +2090,7 @@ def _write_constant_reference(self, elem: ar_element.ConstantReference) -> None:
self._write_constant_ref(elem.constant_ref, "CONSTANT-REF")
self._leave_child()
-# CalibrationData elements
+# --- CalibrationData elements
def _write_sw_values(self, elem: ar_element.SwValues) -> None:
"""
@@ -2154,7 +2197,7 @@ def _write_sw_value_cont_group(self, elem: ar_element.SwValueCont) -> None:
if elem.sw_values_phys is not None:
self._write_sw_values(elem.sw_values_phys)
-# Port interface elements
+# --- Port interface elements
def _write_port_interface(self, elem: ar_element.PortInterface) -> None:
"""
@@ -2269,3 +2312,84 @@ def _write_invalidation_policy_group(self, elem: ar_element.InvalidationPolicy)
self._write_variable_data_prototype_ref(elem.data_element_ref, "DATA-ELEMENT-REF")
if elem.handle_invalid is not None:
self._add_content("HANDLE-INVALID", ar_enum.enum_to_xml(elem.handle_invalid))
+
+ def _write_application_error(self, elem: ar_element.ApplicationError) -> None:
+ """
+ Writes complex type AR:APPLICATION-ERROR
+ Tag variants: 'APPLICATION-ERROR'
+ """
+ assert isinstance(elem, ar_element.ApplicationError)
+ self._add_child("APPLICATION-ERROR")
+ self._write_referrable(elem)
+ self._write_multilanguage_referrable(elem)
+ self._write_identifiable(elem)
+ self._write_application_error_group(elem)
+ self._leave_child()
+
+ def _write_application_error_group(self, elem: ar_element.ApplicationError) -> None:
+ """
+ Writes group AR:APPLICATION-ERROR
+ """
+ if elem.error_code is not None:
+ self._add_content("ERROR-CODE", str(elem.error_code))
+
+ def _write_client_server_operation(self, elem: ar_element.ClientServerOperation) -> None:
+ """
+ Writes complex type AR:CLIENT-SERVER-OPERATION
+ Tag variants: 'CLIENT-SERVER-OPERATION'
+ """
+ assert isinstance(elem, ar_element.ClientServerOperation)
+ self._add_child("CLIENT-SERVER-OPERATION")
+ self._write_referrable(elem)
+ self._write_multilanguage_referrable(elem)
+ self._write_identifiable(elem)
+ self._write_client_server_operation_group(elem)
+ self._leave_child()
+
+ def _write_client_server_operation_group(self, elem: ar_element.ClientServerOperation) -> None:
+ """
+ Writes group AR:CLIENT-SERVER-OPERATION
+ """
+ if elem.arguments:
+ self._add_child("ARGUMENTS")
+ for argument in elem.arguments:
+ self._write_argument_data_prototype(argument)
+ self._leave_child()
+ if elem.diag_arg_integrity is not None:
+ self._add_content("DIAG-ARG-INTEGRITY", self._format_boolean(elem.diag_arg_integrity))
+ if elem.fire_and_forget is not None:
+ self._add_content("FIRE-AND-FORGET", self._format_boolean(elem.fire_and_forget))
+ if elem.possible_error_refs:
+ self._add_child("POSSIBLE-ERROR-REFS")
+ for possible_error_ref in elem.possible_error_refs:
+ self._write_application_error_ref(possible_error_ref, "POSSIBLE-ERROR-REF")
+ self._leave_child()
+
+ def _write_client_server_interface(self, elem: ar_element.ClientServerInterface) -> None:
+ """
+ Writes complex type AR:CLIENT-SERVER-INTERFACE
+ Tag variants: 'CLIENT-SERVER-INTERFACE'
+ """
+ assert isinstance(elem, ar_element.ClientServerInterface)
+ self._add_child("CLIENT-SERVER-INTERFACE")
+ self._write_referrable(elem)
+ self._write_multilanguage_referrable(elem)
+ self._write_identifiable(elem)
+ self._write_port_interface(elem)
+ self._write_client_server_interface_group(elem)
+ self._leave_child()
+
+ def _write_client_server_interface_group(self, elem: ar_element.ClientServerInterface) -> None:
+ """
+ Writes group AR:CLIENT-SERVER-INTERFACE
+ """
+ if elem.operations:
+ self._add_child("OPERATIONS")
+ for operation in elem.operations:
+ self._write_client_server_operation(operation)
+ self._leave_child()
+ if elem.possible_errors:
+ self._add_child("POSSIBLE-ERRORS")
+ for possible_error in elem.possible_errors:
+ self._write_application_error(possible_error)
+ self._leave_child()
diff --git a/tests/xml/test_data_type.py b/tests/xml/test_data_type.py
index 8234ac8..2aaeb1e 100644
--- a/tests/xml/test_data_type.py
+++ b/tests/xml/test_data_type.py
@@ -2073,5 +2073,73 @@ def test_read_write_init_value(self):
self.assertEqual(elem.init_value.value, 4)
+class TestArgumentDataPrototype(unittest.TestCase):
+
+ def test_read_write_empty(self):
+ element = ar_element.ArgumentDataPrototype("ShortName")
+ writer = autosar.xml.Writer()
+ xml = '''
+ ShortName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ArgumentDataPrototype = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ArgumentDataPrototype)
+ self.assertEqual(elem.name, "ShortName")
+
+ def test_read_write_sw_data_props(self):
+ sw_data_props = ar_element.SwDataDefPropsConditional(
+ calibration_access=ar_enum.SwCalibrationAccess.NOT_ACCESSIBLE)
+ element = ar_element.ArgumentDataPrototype("ShortName", sw_data_def_props=sw_data_props)
+ writer = autosar.xml.Writer()
+ xml = '''
+ ShortName
+
+
+
+ NOT-ACCESSIBLE
+
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ArgumentDataPrototype = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ArgumentDataPrototype)
+ self.assertEqual(elem.name, "ShortName")
+ props: ar_element.SwDataDefPropsConditional = elem.sw_data_def_props[0]
+ self.assertEqual(props.calibration_access, ar_enum.SwCalibrationAccess.NOT_ACCESSIBLE)
+
+ def test_read_write_direction(self):
+ element = ar_element.ArgumentDataPrototype("ShortName",
+ direction=ar_enum.ArgumentDirection.OUT)
+ writer = autosar.xml.Writer()
+ xml = '''
+ ShortName
+ OUT
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ArgumentDataPrototype = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ArgumentDataPrototype)
+ self.assertEqual(elem.name, "ShortName")
+ self.assertEqual(elem.direction, ar_enum.ArgumentDirection.OUT)
+
+ def test_read_write_server_arg_impl_policu(self):
+ element = ar_element.ArgumentDataPrototype("ShortName",
+ server_arg_impl_policy=ar_enum.ServerArgImplPolicy.USE_ARGUMENT_TYPE)
+ writer = autosar.xml.Writer()
+ xml = '''
+ ShortName
+ USE-ARGUMENT-TYPE
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ArgumentDataPrototype = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ArgumentDataPrototype)
+ self.assertEqual(elem.name, "ShortName")
+ self.assertEqual(elem.server_arg_impl_policy, ar_enum.ServerArgImplPolicy.USE_ARGUMENT_TYPE)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/xml/test_port_interface.py b/tests/xml/test_port_interface.py
index c1d44f3..c859ef7 100644
--- a/tests/xml/test_port_interface.py
+++ b/tests/xml/test_port_interface.py
@@ -9,6 +9,8 @@
import autosar.xml.element as ar_element # noqa E402
import autosar # noqa E402
+IMPLEMENTATION_DATA_TYPE = ar_enum.IdentifiableSubTypes.IMPLEMENTATION_DATA_TYPE
+
class TestInvalidationPolicy(unittest.TestCase):
@@ -577,5 +579,279 @@ def test_create_interface_with_two_parameters_using_make_method(self):
self.assertEqual(str(parameter.type_ref), "AUTOSAR_Platform/ImplementationDataTypes/uint16")
+class TestApplicationError(unittest.TestCase):
+
+ def test_name_only(self):
+ element = ar_element.ApplicationError("ErrorName")
+ writer = autosar.xml.Writer()
+ xml = '''
+ ErrorName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ApplicationError = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ApplicationError)
+ self.assertEqual(elem.name, "ErrorName")
+
+ def test_error_code(self):
+ element = ar_element.ApplicationError("ErrorName", error_code=10)
+ writer = autosar.xml.Writer()
+ xml = '''
+ ErrorName
+ 10
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ApplicationError = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ApplicationError)
+ self.assertEqual(elem.name, "ErrorName")
+ self.assertEqual(elem.error_code, 10)
+
+
+class TestClientServerOperation(unittest.TestCase):
+
+ def test_name_only(self):
+ element = ar_element.ClientServerOperation("OperationName")
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertEqual(elem.name, "OperationName")
+
+ def test_one_argument(self):
+ element = ar_element.ClientServerOperation("OperationName")
+ element.make_in_argument("Arg1",
+ type_ref=ar_element.AutosarDataTypeRef("/DataTypes/uint8", IMPLEMENTATION_DATA_TYPE))
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+
+
+ Arg1
+ /DataTypes/uint8
+ IN
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertEqual(elem.name, "OperationName")
+ self.assertEqual(len(elem.arguments), 1)
+ argument: ar_element.ArgumentDataPrototype = elem.arguments[0]
+ self.assertIsInstance(argument, ar_element.ArgumentDataPrototype)
+ self.assertEqual(argument.name, "Arg1")
+ self.assertEqual(str(argument.type_ref), "/DataTypes/uint8")
+ self.assertEqual(argument.direction, ar_enum.ArgumentDirection.IN)
+
+ def test_two_arguments(self):
+ element = ar_element.ClientServerOperation("OperationName")
+ element.make_in_argument("Arg1",
+ type_ref=ar_element.AutosarDataTypeRef("/DataTypes/uint8", IMPLEMENTATION_DATA_TYPE))
+ element.make_out_argument("Arg2",
+ type_ref=ar_element.AutosarDataTypeRef("/DataTypes/bool", IMPLEMENTATION_DATA_TYPE))
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+
+
+ Arg1
+ /DataTypes/uint8
+ IN
+
+
+ Arg2
+ /DataTypes/bool
+ OUT
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertEqual(len(elem.arguments), 2)
+ argument: ar_element.ArgumentDataPrototype = elem.arguments[0]
+ self.assertIsInstance(argument, ar_element.ArgumentDataPrototype)
+ self.assertEqual(argument.name, "Arg1")
+ self.assertEqual(str(argument.type_ref), "/DataTypes/uint8")
+ self.assertEqual(argument.direction, ar_enum.ArgumentDirection.IN)
+ argument: ar_element.ArgumentDataPrototype = elem.arguments[1]
+ self.assertIsInstance(argument, ar_element.ArgumentDataPrototype)
+ self.assertEqual(argument.name, "Arg2")
+ self.assertEqual(str(argument.type_ref), "/DataTypes/bool")
+ self.assertEqual(argument.direction, ar_enum.ArgumentDirection.OUT)
+
+ def test_diag_arg_integrity(self):
+ element = ar_element.ClientServerOperation("OperationName",
+ diag_arg_integrity=False)
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+ false
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertFalse(elem.diag_arg_integrity)
+
+ def test_fire_and_forget(self):
+ element = ar_element.ClientServerOperation("OperationName",
+ fire_and_forget=True)
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+ true
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertTrue(elem.fire_and_forget)
+
+ def test_single_possible_error(self):
+ element = ar_element.ClientServerOperation("OperationName")
+ element.make_possible_error_ref("/PortInterfaces/OperationName/ErrorName1")
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+
+ /PortInterfaces/OperationName/ErrorName1
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertEqual(elem.name, "OperationName")
+ self.assertEqual(len(elem.possible_error_refs), 1)
+ possible_error_ref: ar_element.ApplicationErrorRef = elem.possible_error_refs[0]
+ self.assertIsInstance(possible_error_ref, ar_element.ApplicationErrorRef)
+ self.assertEqual(str(possible_error_ref), "/PortInterfaces/OperationName/ErrorName1")
+
+ def test_dual_possible_errors(self):
+ element = ar_element.ClientServerOperation("OperationName")
+ element.make_possible_error_ref("/PortInterfaces/OperationName/ErrorName1")
+ element.make_possible_error_ref("/PortInterfaces/OperationName/ErrorName2")
+ writer = autosar.xml.Writer()
+ xml = '''
+ OperationName
+
+ /PortInterfaces/OperationName/ErrorName1
+ /PortInterfaces/OperationName/ErrorName2
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerOperation = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerOperation)
+ self.assertEqual(elem.name, "OperationName")
+ self.assertEqual(len(elem.possible_error_refs), 2)
+ possible_error_ref: ar_element.ApplicationErrorRef = elem.possible_error_refs[0]
+ self.assertIsInstance(possible_error_ref, ar_element.ApplicationErrorRef)
+ self.assertEqual(str(possible_error_ref), "/PortInterfaces/OperationName/ErrorName1")
+ possible_error_ref: ar_element.ApplicationErrorRef = elem.possible_error_refs[1]
+ self.assertIsInstance(possible_error_ref, ar_element.ApplicationErrorRef)
+ self.assertEqual(str(possible_error_ref), "/PortInterfaces/OperationName/ErrorName2")
+
+
+class TestClientServerInterface(unittest.TestCase):
+
+ def test_name_only(self):
+ element = ar_element.ClientServerInterface("InterfaceName")
+ writer = autosar.xml.Writer()
+ xml = '''
+ InterfaceName
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerInterface = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerInterface)
+ self.assertEqual(elem.name, "InterfaceName")
+
+ def test_operation(self):
+ element = ar_element.ClientServerInterface("InterfaceName")
+ operation = element.make_operation("Operation1")
+ operation.make_in_argument("Arg1",
+ type_ref=ar_element.AutosarDataTypeRef("/DataTypes/uint8", IMPLEMENTATION_DATA_TYPE))
+ writer = autosar.xml.Writer()
+ xml = '''
+ InterfaceName
+
+
+ Operation1
+
+
+ Arg1
+ /DataTypes/uint8
+ IN
+
+
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerInterface = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerInterface)
+ self.assertEqual(elem.name, "InterfaceName")
+ self.assertEqual(len(elem.operations), 1)
+ operation = elem.operations[0]
+ self.assertIsInstance(operation, ar_element.ClientServerOperation)
+ self.assertEqual(operation.name, "Operation1")
+
+ def test_operation_with_possible_error(self):
+ element = ar_element.ClientServerInterface("InterfaceName")
+ element.make_possible_error("E_NOT_OK")
+ operation = element.make_operation("Operation1")
+ operation.make_in_argument("Arg1",
+ type_ref=ar_element.AutosarDataTypeRef("/DataTypes/uint8", IMPLEMENTATION_DATA_TYPE))
+ operation.make_possible_error_ref("/Portinterfaces/InterfaceName/E_NOT_OK")
+ writer = autosar.xml.Writer()
+ xml = '''
+ InterfaceName
+
+
+ Operation1
+
+
+ Arg1
+ /DataTypes/uint8
+ IN
+
+
+
+ /Portinterfaces/InterfaceName/E_NOT_OK
+
+
+
+
+
+ E_NOT_OK
+
+
+'''
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.ClientServerInterface = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.ClientServerInterface)
+ self.assertEqual(elem.name, "InterfaceName")
+ self.assertEqual(len(elem.operations), 1)
+ operation = elem.operations[0]
+ self.assertIsInstance(operation, ar_element.ClientServerOperation)
+ self.assertEqual(len(operation.possible_error_refs), 1)
+ possible_error_ref = operation.possible_error_refs[0]
+ self.assertEqual(str(possible_error_ref), "/Portinterfaces/InterfaceName/E_NOT_OK")
+ self.assertEqual(len(elem.possible_errors), 1)
+ possible_errors = elem.possible_errors[0]
+ self.assertEqual(possible_errors.name, "E_NOT_OK")
+
+
if __name__ == '__main__':
unittest.main()