diff --git a/docs/source/index.rst b/docs/source/index.rst index 0b1fd498..14f0548f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,15 +1,15 @@ Welcome to UDS documentation! ============================= .. toctree:: - :hidden: + :hidden: - Home - pages/installation.rst - pages/user_guide.rst - pages/examples.rst - autoapi/index.rst - pages/knowledge_base.rst - pages/contribution.rst + Home + pages/installation.rst + pages/user_guide.rst + pages/examples.rst + autoapi/index.rst + pages/knowledge_base.rst + pages/contribution.rst Overview @@ -22,10 +22,11 @@ and decode diagnostic communication. The architecture enables to use it with various communication buses (e.g. CAN, LIN). The most likely use cases of this package are: - - communication with your vehicle (e.g. reading Diagnostic Trouble Codes) - - monitoring and decoding UDS communication - - performing tests against on-board ECU (server) - - performing tests against OBD Tester (client) + +- communication with your vehicle (e.g. reading Diagnostic Trouble Codes) +- monitoring and decoding UDS communication +- performing tests against on-board ECU (server) +- performing tests against OBD Tester (client) Implementation Status @@ -39,32 +40,32 @@ Features ```````` Current implementation status of package features: -+----------------------------------------------+--------------------------------------------+ -| Feature | Implementation Status | -+==============================================+============================================+ -| UDS Messages and Packets | Available since version `0.0.2 | -| | `_ | -+----------------------------------------------+--------------------------------------------+ -| UDS Packets Reception and Transmission | Available since version `0.3.0 | -| | `_ | -+----------------------------------------------+--------------------------------------------+ -| UDS Messages Reception and Transmission | Available since version `1.0.0 | -| | `_ | -+----------------------------------------------+--------------------------------------------+ -| Messages Segmentation | Available since version `0.2.0 | -| | `_ | -+----------------------------------------------+--------------------------------------------+ -| UDS Packets Desegmentation | Available since version `0.2.0 | -| | `_ | -+----------------------------------------------+--------------------------------------------+ -| Support for Services with multiple responses | Planned | -+----------------------------------------------+--------------------------------------------+ -| Client Simulation | Planned | -+----------------------------------------------+--------------------------------------------+ -| Server Simulation | Planned | -+----------------------------------------------+--------------------------------------------+ -| Support for Messages Databases | Planned | -+----------------------------------------------+--------------------------------------------+ ++-----------------------------------------+--------------------------------------------+ +| Feature | Implementation Status | ++=========================================+============================================+ +| UDS Messages and Packets | Available since version `0.0.2 | +| | `_ | ++-----------------------------------------+--------------------------------------------+ +| UDS Packets Reception and Transmission | Available since version `0.3.0 | +| | `_ | ++-----------------------------------------+--------------------------------------------+ +| UDS Messages Reception and Transmission | Available since version `1.0.0 | +| | `_ | ++-----------------------------------------+--------------------------------------------+ +| Messages Segmentation | Available since version `0.2.0 | +| | `_ | ++-----------------------------------------+--------------------------------------------+ +| UDS Packets Desegmentation | Available since version `0.2.0 | +| | `_ | ++-----------------------------------------+--------------------------------------------+ +| Client Simulation | Planned | ++-----------------------------------------+--------------------------------------------+ +| Server Simulation | Planned | ++-----------------------------------------+--------------------------------------------+ +| UDS Sniffer | Planned | ++-----------------------------------------+--------------------------------------------+ +| Support for Messages Databases | Planned | ++-----------------------------------------+--------------------------------------------+ Buses supported @@ -100,4 +101,4 @@ Contact .. admonition:: Documentation generated - |today| + |today| diff --git a/docs/source/pages/knowledge_base/diagnostic_message.rst b/docs/source/pages/knowledge_base/diagnostic_message.rst index 88724e7b..73c402c7 100644 --- a/docs/source/pages/knowledge_base/diagnostic_message.rst +++ b/docs/source/pages/knowledge_base/diagnostic_message.rst @@ -6,8 +6,9 @@ Messages that are exchanged by clients and servers during UDS communications are In the documentation and the implementation, `UDS message` name is also in use. We distinguish two types of diagnostic messages depending on who is a transmitter: - - `diagnostic request`_ - - `diagnostic response`_ + +- `diagnostic request`_ +- `diagnostic response`_ UDS communication is always initiated by a client who sends a `diagnostic request`_ to a network that it has direct connection with. The client might not be directly connected to a desired recipient(s) of the request, therefore some @@ -17,26 +18,26 @@ server shall transmit the request to the sub-network if this is a route (not nec one recipient of the message. .. figure:: ../../diagrams/KnowledgeBase-Gateway_request.png - :alt: Gateway - request - :figclass: align-center - :width: 100% + :alt: Gateway - request + :figclass: align-center + :width: 100% - Diagnostic request routing in example vehicle networks. + Diagnostic request routing in example vehicle networks. - In this example all ECUs in the vehicle are the targets of the request - functionally addressed request was sent. + In this example all ECUs in the vehicle are the targets of the request - functionally addressed request was sent. Each server which was the recipient of the request, might decide to send a response back to the nearest client (the one which previously transmitted the request in this sub-network). Then, the client shall act as a gateway again and redirect the response back until it reaches the request message originator (Diagnostic Tester). .. figure:: ../../diagrams/KnowledgeBase-Gateway_response.png - :alt: Gateway - response - :figclass: align-center - :width: 100% + :alt: Gateway - response + :figclass: align-center + :width: 100% - Diagnostic responses routing in example vehicle networks. + Diagnostic responses routing in example vehicle networks. - In this example all ECUs in the vehicle responds to the request. + In this example all ECUs in the vehicle responds to the request. .. _knowledge-base-request-message: @@ -84,9 +85,9 @@ Where: .. note:: When positive diagnostic message is received, this equation is always true: - .. code-block:: + .. code-block:: - RSID = SID + 0x40 + RSID = SID + 0x40 Negative Response Message @@ -106,9 +107,10 @@ Format of negative response messages: | 3 | NRC | XX | +------+-----------------------+-------+ -Where: - - SID - `Service Identifier`_ value that was received in the request message to which the server responded - - NRC - `Negative Response Code`_ value that identified the reason for negative response +where: + +- SID - `Service Identifier`_ value that was received in the request message to which the server responded +- NRC - `Negative Response Code`_ value that identified the reason for negative response .. _knowledge-base-sid: @@ -121,93 +123,94 @@ SID value determines whether the message is `diagnostic request`_ or `diagnostic General purpose (application) and format of `diagnostic message`_ is also by determined by SID value. List of all Service Identifier (SID) values and their application: - - 0x00 - not applicable, reserved by ISO 14229-1 - - 0x01-0x0F - ISO 15031-5/SAE J1979 specific services - - 0x10 - `DiagnosticSessionControl`_ service request - - 0x11 - `ECUReset`_ service request - - 0x12-0x13 - reserved by ISO 14229-1 - - 0x14 - `ClearDiagnosticInformation`_ service request - - 0x15-0x18 - reserved by ISO 14229-1 - - 0x19 - `ReadDTCInformation`_ service request - - 0x1A-0x21 - reserved by ISO 14229-1 - - 0x22 - `ReadDataByIdentifier`_ service request - - 0x23 - `ReadMemoryByAddress`_ service request - - 0x24 - `ReadScalingDataByIdentifier`_ service request - - 0x25-0x26 - reserved by ISO 14229-1 - - 0x27 - `SecurityAccess`_ service request - - 0x28 - `CommunicationControl`_ service request - - 0x29 - `Authentication`_ service request - - 0x2A - `ReadDataByPeriodicIdentifier`_ service request - - 0x2B - reserved by ISO 14229-1 - - 0x2C - `DynamicallyDefineDataIdentifier`_ service request - - 0x2D - reserved by ISO 14229-1 - - 0x2E - `WriteDataByIdentifier`_ service request - - 0x2F - `InputOutputControlByIdentifier`_ service request - - 0x30 - reserved by ISO 14229-1 - - 0x31 - `RoutineControl`_ service request - - 0x32-0x33 - reserved by ISO 14229-1 - - 0x34 - `RequestDownload`_ service request - - 0x35 - `RequestUpload`_ service request - - 0x36 - `TransferData`_ service request - - 0x37 - `RequestTransferExit`_ service request - - 0x38 - `RequestFileTransfer`_ service request - - 0x39-0x3C - reserved by ISO 14229-1 - - 0x3D - `WriteMemoryByAddress`_ service request - - 0x3E - `TesterPresent`_ service request - - 0x3F - not applicable, reserved by ISO 14229-1 - - 0x40 - not applicable, reserved by ISO 14229-1 - - 0x41-0x4F - ISO 15031-5/SAE J1979 specific services - - 0x50 - positive response to `DiagnosticSessionControl`_ service - - 0x51 - positive response to `ECUReset`_ service - - 0x52-0x53 - reserved by ISO 14229-1 - - 0x54 - positive response to `ClearDiagnosticInformation`_ service - - 0x55-0x58 - reserved by ISO 14229-1 - - 0x59 - positive response to `ReadDTCInformation`_ service - - 0x5A-0x61 - reserved by ISO 14229-1 - - 0x62 - positive response to `ReadDataByIdentifier`_ service - - 0x63 - positive response to `ReadMemoryByAddress`_ service - - 0x64 - positive response to `ReadScalingDataByIdentifier`_ service - - 0x65-0x66 - reserved by ISO 14229-1 - - 0x67 - positive response to `SecurityAccess`_ service - - 0x68 - positive response to `CommunicationControl`_ service - - 0x69 - positive response to `Authentication`_ service - - 0x6A - positive response to `ReadDataByPeriodicIdentifier`_ service - - 0x6B - reserved by ISO 14229-1 - - 0x6C - positive response to `DynamicallyDefineDataIdentifier`_ service - - 0x6D - reserved by ISO 14229-1 - - 0x6E - positive response to `WriteDataByIdentifier`_ service - - 0x6F - positive response to `InputOutputControlByIdentifier`_ service - - 0x70 - reserved by ISO 14229-1 - - 0x71 - positive response to `RoutineControl`_ service - - 0x72-0x73 - reserved by ISO 14229-1 - - 0x74 - positive response to `RequestDownload`_ service - - 0x75 - positive response to `RequestUpload`_ service - - 0x76 - positive response to `TransferData`_ service - - 0x77 - positive response to `RequestTransferExit`_ service - - 0x78 - positive response to `RequestFileTransfer`_ service - - 0x79-0x7C - reserved by ISO 14229-1 - - 0x7D - positive response to `WriteMemoryByAddress`_ service - - 0x7E - positive response to `TesterPresent`_ service - - 0x7F - negative response service identifier - - 0x80-0x82 - not applicable, reserved by ISO 14229-1 - - 0x83 - reserved by ISO 14229-1 - - 0x84 - `SecuredDataTransmission`_ service request - - 0x85 - `ControlDTCSetting`_ service request - - 0x86 - `ResponseOnEvent`_ service request - - 0x87 - `LinkControl`_ service request - - 0x88 - reserved by ISO 14229-1 - - 0x89-0xB9 - not applicable, reserved by ISO 14229-1 - - 0xBA-0xBE - system supplier specific service requests - - 0xBF-0xC2 - not applicable, reserved by ISO 14229-1 - - 0xC3 - reserved by ISO 14229-1 - - 0xC4 - positive response to `SecuredDataTransmission`_ service - - 0xC5 - positive response to `ControlDTCSetting`_ service - - 0xC6 - positive response to `ResponseOnEvent`_ service - - 0xC7 - positive response to `LinkControl`_ service - - 0xC8 - reserved by ISO 14229-1 - - 0xC9-0xF9 - not applicable, reserved by ISO 14229-1 - - 0xFA-0xFE - positive responses to system supplier specific requests - - 0xFF - not applicable, reserved by ISO 14229-1 + +- 0x00 - not applicable, reserved by ISO 14229-1 +- 0x01-0x0F - ISO 15031-5/SAE J1979 specific services +- 0x10 - `DiagnosticSessionControl`_ service request +- 0x11 - `ECUReset`_ service request +- 0x12-0x13 - reserved by ISO 14229-1 +- 0x14 - `ClearDiagnosticInformation`_ service request +- 0x15-0x18 - reserved by ISO 14229-1 +- 0x19 - `ReadDTCInformation`_ service request +- 0x1A-0x21 - reserved by ISO 14229-1 +- 0x22 - `ReadDataByIdentifier`_ service request +- 0x23 - `ReadMemoryByAddress`_ service request +- 0x24 - `ReadScalingDataByIdentifier`_ service request +- 0x25-0x26 - reserved by ISO 14229-1 +- 0x27 - `SecurityAccess`_ service request +- 0x28 - `CommunicationControl`_ service request +- 0x29 - `Authentication`_ service request +- 0x2A - `ReadDataByPeriodicIdentifier`_ service request +- 0x2B - reserved by ISO 14229-1 +- 0x2C - `DynamicallyDefineDataIdentifier`_ service request +- 0x2D - reserved by ISO 14229-1 +- 0x2E - `WriteDataByIdentifier`_ service request +- 0x2F - `InputOutputControlByIdentifier`_ service request +- 0x30 - reserved by ISO 14229-1 +- 0x31 - `RoutineControl`_ service request +- 0x32-0x33 - reserved by ISO 14229-1 +- 0x34 - `RequestDownload`_ service request +- 0x35 - `RequestUpload`_ service request +- 0x36 - `TransferData`_ service request +- 0x37 - `RequestTransferExit`_ service request +- 0x38 - `RequestFileTransfer`_ service request +- 0x39-0x3C - reserved by ISO 14229-1 +- 0x3D - `WriteMemoryByAddress`_ service request +- 0x3E - `TesterPresent`_ service request +- 0x3F - not applicable, reserved by ISO 14229-1 +- 0x40 - not applicable, reserved by ISO 14229-1 +- 0x41-0x4F - ISO 15031-5/SAE J1979 specific services +- 0x50 - positive response to `DiagnosticSessionControl`_ service +- 0x51 - positive response to `ECUReset`_ service +- 0x52-0x53 - reserved by ISO 14229-1 +- 0x54 - positive response to `ClearDiagnosticInformation`_ service +- 0x55-0x58 - reserved by ISO 14229-1 +- 0x59 - positive response to `ReadDTCInformation`_ service +- 0x5A-0x61 - reserved by ISO 14229-1 +- 0x62 - positive response to `ReadDataByIdentifier`_ service +- 0x63 - positive response to `ReadMemoryByAddress`_ service +- 0x64 - positive response to `ReadScalingDataByIdentifier`_ service +- 0x65-0x66 - reserved by ISO 14229-1 +- 0x67 - positive response to `SecurityAccess`_ service +- 0x68 - positive response to `CommunicationControl`_ service +- 0x69 - positive response to `Authentication`_ service +- 0x6A - positive response to `ReadDataByPeriodicIdentifier`_ service +- 0x6B - reserved by ISO 14229-1 +- 0x6C - positive response to `DynamicallyDefineDataIdentifier`_ service +- 0x6D - reserved by ISO 14229-1 +- 0x6E - positive response to `WriteDataByIdentifier`_ service +- 0x6F - positive response to `InputOutputControlByIdentifier`_ service +- 0x70 - reserved by ISO 14229-1 +- 0x71 - positive response to `RoutineControl`_ service +- 0x72-0x73 - reserved by ISO 14229-1 +- 0x74 - positive response to `RequestDownload`_ service +- 0x75 - positive response to `RequestUpload`_ service +- 0x76 - positive response to `TransferData`_ service +- 0x77 - positive response to `RequestTransferExit`_ service +- 0x78 - positive response to `RequestFileTransfer`_ service +- 0x79-0x7C - reserved by ISO 14229-1 +- 0x7D - positive response to `WriteMemoryByAddress`_ service +- 0x7E - positive response to `TesterPresent`_ service +- 0x7F - negative response service identifier +- 0x80-0x82 - not applicable, reserved by ISO 14229-1 +- 0x83 - reserved by ISO 14229-1 +- 0x84 - `SecuredDataTransmission`_ service request +- 0x85 - `ControlDTCSetting`_ service request +- 0x86 - `ResponseOnEvent`_ service request +- 0x87 - `LinkControl`_ service request +- 0x88 - reserved by ISO 14229-1 +- 0x89-0xB9 - not applicable, reserved by ISO 14229-1 +- 0xBA-0xBE - system supplier specific service requests +- 0xBF-0xC2 - not applicable, reserved by ISO 14229-1 +- 0xC3 - reserved by ISO 14229-1 +- 0xC4 - positive response to `SecuredDataTransmission`_ service +- 0xC5 - positive response to `ControlDTCSetting`_ service +- 0xC6 - positive response to `ResponseOnEvent`_ service +- 0xC7 - positive response to `LinkControl`_ service +- 0xC8 - reserved by ISO 14229-1 +- 0xC9-0xF9 - not applicable, reserved by ISO 14229-1 +- 0xFA-0xFE - positive responses to system supplier specific requests +- 0xFF - not applicable, reserved by ISO 14229-1 DiagnosticSessionControl @@ -374,164 +377,164 @@ Negative Response Code (NRC) is one byte value which contains information why a a positive response message. List of NRC values: - - 0x00 - positiveResponse - This NRC shall not be used in a negative response message. - This positiveResponse parameter value is reserved for server internal implementation. - - 0x00-0x0F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x10 - generalReject - This NRC indicates that the requested action has been rejected by the server. - - 0x11 - serviceNotSupported - This NRC indicates that the requested action will not be taken because the - server does not support the requested service. - - 0x12 - SubFunctionNotSupported - This NRC indicates that the requested action will not be taken because the - server does not support the service specific parameters of the request message. - - 0x13 - incorrectMessageLengthOrInvalidFormat - This NRC indicates that the requested action will not be taken - because the length of the received request message does not match the prescribed length for the specified service - or the format of the parameters do not match the prescribed format for the specified service. - - 0x14 - responseTooLong - This NRC shall be reported by the server if the response to be generated exceeds - the maximum number of bytes available by the underlying network layer. This could occur if the response message - exceeds the maximum size allowed by the underlying transport protocol or if the response message exceeds the server - buffer size allocated for that purpose. - - 0x15-0x20 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x21 - busyRepeatRequest - This NRC indicates that the server is temporarily too busy to perform the requested - operation. In this circumstance the client shall perform repetition of the "identical request message" or - "another request message". The repetition of the request shall be delayed by a time specified in the respective - implementation documents. - - 0x22 - conditionsNotCorrect - This NRC indicates that the requested action will not be taken because the server - prerequisite conditions are not met. - - 0x23 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. - - 0x24 - requestSequenceError - This NRC indicates that the requested action will not be taken because the server - expects a different sequence of request messages or message as sent by the client. This may occur when sequence - sensitive requests are issued in the wrong order. - - 0x25 - noResponseFromSubnetComponent - This NRC indicates that the server has received the request but the requested - action could not be performed by the server as a subnet component which is necessary to supply the requested - information did not respond within the specified time. - - 0x26 - FailurePreventsExecutionOfRequestedAction - This NRC indicates that the requested action will not be taken - because a failure condition, identified by a DTC (with at least one DTC status bit for TestFailed, Pending, - Confirmed or TestFailedSinceLastClear set to 1), has occurred and that this failure condition prevents the server - from performing the requested action. - - 0x27-0x30 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x31 - requestOutOfRange - This NRC indicates that the requested action will not be taken because the server has - detected that the request message contains a parameter which attempts to substitute a value beyond its range of - authority (e.g. attempting to substitute a data byte of 111 when the data is only defined to 100), or which attempts - to access a DataIdentifier/RoutineIdentifer that is not supported or not supported in active session. - - 0x32 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. - - 0x33 - securityAccessDenied - This NRC indicates that the requested action will not be taken because the server's - security strategy has not been satisfied by the client. - - 0x34 - authenticationRequired - This NRC indicates that the requested service will not be taken because the client - has insufficient rights based on its Authentication state. - - 0x35 - invalidKey - This NRC indicates that the server has not given security access because the key sent by - the client did not match with the key in the server's memory. This counts as an attempt to gain security. - - 0x36 - exceedNumberOfAttempts - This NRC indicates that the requested action will not be taken because the client - has unsuccessfully attempted to gain security access more times than the server's security strategy will allow. - - 0x37 - requiredTimeDelayNotExpired - This NRC indicates that the requested action will not be taken because - the client's latest attempt to gain security access was initiated before the server's required timeout period had - elapsed. - - 0x38 - secureDataTransmissionRequired - This NRC indicates that the requested service will not be taken because - the requested action is required to be sent using a secured communication channel. - - 0x39 - secureDataTransmissionNotAllowed - This NRC indicates that this message was received using the - SecuredDataTransmission (SID 0x84) service. However, the requested action is not allowed to be sent using - the SecuredDataTransmission (0x84) service. - - 0x3A - secureDataVerificationFailed - This NRC indicates that the message failed in the security sub-layer. - - 0x3B-0x4F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x50 - Certificate verification failed, Invalid Time Period - Date and time of the server does not match - the validity period of the Certificate. - - 0x51 - Certificate verification failed, Invalid Signature - Signature of the Certificate could not be verified. - - 0x52 - Certificate verification failed, Invalid Chain of Trust - Certificate could not be verified against stored - information about the issuing authority. - - 0x53 - Certificate verification failed, Invalid Type - Certificate does not match the current requested use - case. - - 0x54 - Certificate verification failed, Invalid Format - Certificate could not be evaluated because the format - requirement has not been met. - - 0x55 - Certificate verification failed, Invalid Content - Certificate could not be verified because the content - does not match. - - 0x56 - Certificate verification failed, Invalid Scope - The scope of the Certificate does not match the contents - of the server. - - 0x57 - Certificate verification failed, Invalid Certificate (revoked) - Certificate received from client is invalid, - because the server has revoked access for some reason. - - 0x58 - Ownership verification failed - Delivered Ownership does not match the provided challenge or could not - verified with the own private key. - - 0x59 - Challenge calculation failed - The challenge could not be calculated on the server side. - - 0x5A - Setting Access Rights failed - The server could not set the access rights. - - 0x5B - Session key creation/derivation failed - The server could not create or derive a session key. - - 0x5C - Configuration data usage failed - The server could not work with the provided configuration data. - - 0x5D - DeAuthentication failed - DeAuthentication was not successful, server could still be unprotected. - - 0x5E-0x6F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x70 - uploadDownloadNotAccepted - This NRC indicates that an attempt to upload/download to a server's memory - cannot be accomplished due to some fault conditions. - - 0x71 - transferDataSuspended - This NRC indicates that a data transfer operation was halted due to some fault. - The active transferData sequence shall be aborted. - - 0x72 - generalProgrammingFailure - This NRC indicates that the server detected an error when erasing or programming - a memory location in the permanent memory device (e.g. Flash Memory). - - 0x73 - wrongBlockSequenceCounter - This NRC indicates that the server detected an error in the sequence of - blockSequenceCounter values. Note that the repetition of a TransferData request message with a blockSequenceCounter - equal to the one included in the previous TransferData request message shall be accepted by the server. - - 0x74-0x77 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x78 - requestCorrectlyReceived-ResponsePending - This NRC indicates that the request message was received correctly, - and that all parameters in the request message were valid (these checks can be delayed until after sending this NRC - if executing the boot software), but the action to be performed is not yet completed and the server is not yet ready - to receive another request. As soon as the requested service has been completed, the server shall send a positive - response message or negative response message with a response code different from this. - - 0x79-0x7D - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. - - 0x7E - SubFunctionNotSupportedInActiveSession - This NRC indicates that the requested action will not be taken - because the server does not support the requested SubFunction in the session currently active. This NRC shall only - be used when the requested SubFunction is known to be supported in another session, otherwise response code - SubFunctionNotSupported shall be used. - - 0x7F - serviceNotSupportedInActiveSession - This NRC indicates that the requested action will not be taken because - the server does not support the requested service in the session currently active. This NRC shall only be used when - the requested service is known to be supported in another session, otherwise response code serviceNotSupported - shall be used. - - 0x80 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. - - 0x81 - rpmTooHigh - This NRC indicates that the requested action will not be taken because the server prerequisite - condition for RPM is not met (current RPM is above a preprogrammed maximum threshold). - - 0x82 - rpmTooLow - This NRC indicates that the requested action will not be taken because the server prerequisite - condition for RPM is not met (current RPM is below a preprogrammed minimum threshold). - - 0x83 - engineIsRunning - This NRC is required for those actuator tests which cannot be actuated while the Engine - is running. This is different from RPM too high negative response, and shall be allowed. - - 0x84 - engineIsNotRunning - This NRC is required for those actuator tests which cannot be actuated unless - the Engine is running. This is different from RPM too low negative response, and shall be allowed. - - 0x85 - engineRunTimeTooLow - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for engine run time is not met (current engine run time is below a preprogrammed limit). - - 0x86 - temperatureTooHigh - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for temperature is not met (current temperature is above a preprogrammed maximum threshold). - - 0x87 - temperatureTooLow - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for temperature is not met (current temperature is below a preprogrammed minimum threshold). - - 0x88 - vehicleSpeedTooHigh - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for vehicle speed is not met (current VS is above a preprogrammed maximum threshold). - - 0x89 - vehicleSpeedTooLow - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for vehicle speed is not met (current VS is below a preprogrammed minimum threshold). - - 0x8A - throttle/PedalTooHigh - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for throttle/pedal position is not met (current throttle/pedal position is above - a preprogrammed maximum threshold). - - 0x8B - throttle/PedalTooLow - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for throttle/pedal position is not met (current throttle/pedal position is below - a preprogrammed minimum threshold). - - 0x8C - transmissionRangeNotInNeutral - This NRC indicates that the requested action will not be taken because - the server prerequisite condition for being in neutral is not met (current transmission range is not in neutral). - - 0x8D - transmissionRangeNotInGear - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for being in gear is not met (current transmission range is not in gear). - - 0x8E - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. - - 0x8F - brakeSwitch(es)NotClosed (Brake Pedal not pressed or not applied) - This NRC indicates that for safety - reasons, this is required for certain tests before it begins, and shall be maintained for the entire duration of - the test. - - 0x90 - shifterLeverNotInPark - This NRC indicates that for safety reasons, this is required for certain tests before - it begins, and shall be maintained for the entire duration of the test. - - 0x91 - torqueConverterClutchLocked - This NRC indicates that the requested action will not be taken because - the server prerequisite condition for torque converter clutch is not met (current torque converter clutch status - above a preprogrammed limit or locked). - - 0x92 - voltageTooHigh - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for voltage at the primary pin of the server (ECU) is not met (current voltage is above - a preprogrammed maximum threshold). - - 0x93 - voltageTooLow - This NRC indicates that the requested action will not be taken because the server - prerequisite condition for voltage at the primary pin of the server (ECU) is not met (current voltage is below - a preprogrammed minimum threshold). - - 0x94 - ResourceTemporarilyNotAvailable - This NRC indicates that the server has received the request but - the requested action could not be performed by the server because an application which is necessary to supply - the requested information is temporality not available. This NRC is in general supported by each diagnostic service, - as not otherwise stated in the data link specific implementation document, therefore it is not listed in the list - of applicable response codes of the diagnostic services. - - 0x95-0xEF - reservedForSpecificConditionsNotCorrect - This range of values is reserved for future definition - condition not correct scenarios by ISO 14229 Standard. - - 0xF0-0xFE - vehicleManufacturerSpecificConditionsNotCorrect - This range of values is reserved for vehicle - manufacturer specific condition not correct scenarios. - - 0xFF - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. + +- 0x00 - positiveResponse - This NRC shall not be used in a negative response message. + This positiveResponse parameter value is reserved for server internal implementation. +- 0x00-0x0F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x10 - generalReject - This NRC indicates that the requested action has been rejected by the server. +- 0x11 - serviceNotSupported - This NRC indicates that the requested action will not be taken because the + server does not support the requested service. +- 0x12 - SubFunctionNotSupported - This NRC indicates that the requested action will not be taken because the + server does not support the service specific parameters of the request message. +- 0x13 - incorrectMessageLengthOrInvalidFormat - This NRC indicates that the requested action will not be taken + because the length of the received request message does not match the prescribed length for the specified service + or the format of the parameters do not match the prescribed format for the specified service. +- 0x14 - responseTooLong - This NRC shall be reported by the server if the response to be generated exceeds + the maximum number of bytes available by the underlying network layer. This could occur if the response message + exceeds the maximum size allowed by the underlying transport protocol or if the response message exceeds the server + buffer size allocated for that purpose. +- 0x15-0x20 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x21 - busyRepeatRequest - This NRC indicates that the server is temporarily too busy to perform the requested + operation. In this circumstance the client shall perform repetition of the "identical request message" or + "another request message". The repetition of the request shall be delayed by a time specified in the respective + implementation documents. +- 0x22 - conditionsNotCorrect - This NRC indicates that the requested action will not be taken because the server + prerequisite conditions are not met. +- 0x23 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. +- 0x24 - requestSequenceError - This NRC indicates that the requested action will not be taken because the server + expects a different sequence of request messages or message as sent by the client. This may occur when sequence + sensitive requests are issued in the wrong order. +- 0x25 - noResponseFromSubnetComponent - This NRC indicates that the server has received the request but the requested + action could not be performed by the server as a subnet component which is necessary to supply the requested + information did not respond within the specified time. +- 0x26 - FailurePreventsExecutionOfRequestedAction - This NRC indicates that the requested action will not be taken + because a failure condition, identified by a DTC (with at least one DTC status bit for TestFailed, Pending, + Confirmed or TestFailedSinceLastClear set to 1), has occurred and that this failure condition prevents the server + from performing the requested action. +- 0x27-0x30 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x31 - requestOutOfRange - This NRC indicates that the requested action will not be taken because the server has + detected that the request message contains a parameter which attempts to substitute a value beyond its range of + authority (e.g. attempting to substitute a data byte of 111 when the data is only defined to 100), or which attempts + to access a DataIdentifier/RoutineIdentifer that is not supported or not supported in active session. +- 0x32 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. +- 0x33 - securityAccessDenied - This NRC indicates that the requested action will not be taken because the server's + security strategy has not been satisfied by the client. +- 0x34 - authenticationRequired - This NRC indicates that the requested service will not be taken because the client + has insufficient rights based on its Authentication state. +- 0x35 - invalidKey - This NRC indicates that the server has not given security access because the key sent by + the client did not match with the key in the server's memory. This counts as an attempt to gain security. +- 0x36 - exceedNumberOfAttempts - This NRC indicates that the requested action will not be taken because the client + has unsuccessfully attempted to gain security access more times than the server's security strategy will allow. +- 0x37 - requiredTimeDelayNotExpired - This NRC indicates that the requested action will not be taken because + the client's latest attempt to gain security access was initiated before the server's required timeout period had + elapsed. +- 0x38 - secureDataTransmissionRequired - This NRC indicates that the requested service will not be taken because + the requested action is required to be sent using a secured communication channel. +- 0x39 - secureDataTransmissionNotAllowed - This NRC indicates that this message was received using the + SecuredDataTransmission (SID 0x84) service. However, the requested action is not allowed to be sent using + the SecuredDataTransmission (0x84) service. +- 0x3A - secureDataVerificationFailed - This NRC indicates that the message failed in the security sub-layer. +- 0x3B-0x4F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x50 - Certificate verification failed, Invalid Time Period - Date and time of the server does not match + the validity period of the Certificate. +- 0x51 - Certificate verification failed, Invalid Signature - Signature of the Certificate could not be verified. +- 0x52 - Certificate verification failed, Invalid Chain of Trust - Certificate could not be verified against stored + information about the issuing authority. +- 0x53 - Certificate verification failed, Invalid Type - Certificate does not match the current requested use case. +- 0x54 - Certificate verification failed, Invalid Format - Certificate could not be evaluated because the format + requirement has not been met. +- 0x55 - Certificate verification failed, Invalid Content - Certificate could not be verified because the content + does not match. +- 0x56 - Certificate verification failed, Invalid Scope - The scope of the Certificate does not match the contents + of the server. +- 0x57 - Certificate verification failed, Invalid Certificate (revoked) - Certificate received from client is invalid, + because the server has revoked access for some reason. +- 0x58 - Ownership verification failed - Delivered Ownership does not match the provided challenge or could not + verified with the own private key. +- 0x59 - Challenge calculation failed - The challenge could not be calculated on the server side. +- 0x5A - Setting Access Rights failed - The server could not set the access rights. +- 0x5B - Session key creation/derivation failed - The server could not create or derive a session key. +- 0x5C - Configuration data usage failed - The server could not work with the provided configuration data. +- 0x5D - DeAuthentication failed - DeAuthentication was not successful, server could still be unprotected. +- 0x5E-0x6F - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x70 - uploadDownloadNotAccepted - This NRC indicates that an attempt to upload/download to a server's memory + cannot be accomplished due to some fault conditions. +- 0x71 - transferDataSuspended - This NRC indicates that a data transfer operation was halted due to some fault. + The active transferData sequence shall be aborted. +- 0x72 - generalProgrammingFailure - This NRC indicates that the server detected an error when erasing or programming + a memory location in the permanent memory device (e.g. Flash Memory). +- 0x73 - wrongBlockSequenceCounter - This NRC indicates that the server detected an error in the sequence of + blockSequenceCounter values. Note that the repetition of a TransferData request message with a blockSequenceCounter + equal to the one included in the previous TransferData request message shall be accepted by the server. +- 0x74-0x77 - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x78 - requestCorrectlyReceived-ResponsePending - This NRC indicates that the request message was received correctly, + and that all parameters in the request message were valid (these checks can be delayed until after sending this NRC + if executing the boot software), but the action to be performed is not yet completed and the server is not yet ready + to receive another request. As soon as the requested service has been completed, the server shall send a positive + response message or negative response message with a response code different from this. +- 0x79-0x7D - ISO Reserved - This range of values is reserved for future definition by ISO 14229 Standard. +- 0x7E - SubFunctionNotSupportedInActiveSession - This NRC indicates that the requested action will not be taken + because the server does not support the requested SubFunction in the session currently active. This NRC shall only + be used when the requested SubFunction is known to be supported in another session, otherwise response code + SubFunctionNotSupported shall be used. +- 0x7F - serviceNotSupportedInActiveSession - This NRC indicates that the requested action will not be taken because + the server does not support the requested service in the session currently active. This NRC shall only be used when + the requested service is known to be supported in another session, otherwise response code serviceNotSupported + shall be used. +- 0x80 - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. +- 0x81 - rpmTooHigh - This NRC indicates that the requested action will not be taken because the server prerequisite + condition for RPM is not met (current RPM is above a preprogrammed maximum threshold). +- 0x82 - rpmTooLow - This NRC indicates that the requested action will not be taken because the server prerequisite + condition for RPM is not met (current RPM is below a preprogrammed minimum threshold). +- 0x83 - engineIsRunning - This NRC is required for those actuator tests which cannot be actuated while the Engine + is running. This is different from RPM too high negative response, and shall be allowed. +- 0x84 - engineIsNotRunning - This NRC is required for those actuator tests which cannot be actuated unless + the Engine is running. This is different from RPM too low negative response, and shall be allowed. +- 0x85 - engineRunTimeTooLow - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for engine run time is not met (current engine run time is below a preprogrammed limit). +- 0x86 - temperatureTooHigh - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for temperature is not met (current temperature is above a preprogrammed maximum threshold). +- 0x87 - temperatureTooLow - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for temperature is not met (current temperature is below a preprogrammed minimum threshold). +- 0x88 - vehicleSpeedTooHigh - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for vehicle speed is not met (current VS is above a preprogrammed maximum threshold). +- 0x89 - vehicleSpeedTooLow - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for vehicle speed is not met (current VS is below a preprogrammed minimum threshold). +- 0x8A - throttle/PedalTooHigh - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for throttle/pedal position is not met (current throttle/pedal position is above + a preprogrammed maximum threshold). +- 0x8B - throttle/PedalTooLow - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for throttle/pedal position is not met (current throttle/pedal position is below + a preprogrammed minimum threshold). +- 0x8C - transmissionRangeNotInNeutral - This NRC indicates that the requested action will not be taken because + the server prerequisite condition for being in neutral is not met (current transmission range is not in neutral). +- 0x8D - transmissionRangeNotInGear - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for being in gear is not met (current transmission range is not in gear). +- 0x8E - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. +- 0x8F - brakeSwitch(es)NotClosed (Brake Pedal not pressed or not applied) - This NRC indicates that for safety + reasons, this is required for certain tests before it begins, and shall be maintained for the entire duration of + the test. +- 0x90 - shifterLeverNotInPark - This NRC indicates that for safety reasons, this is required for certain tests before + it begins, and shall be maintained for the entire duration of the test. +- 0x91 - torqueConverterClutchLocked - This NRC indicates that the requested action will not be taken because + the server prerequisite condition for torque converter clutch is not met (current torque converter clutch status + above a preprogrammed limit or locked). +- 0x92 - voltageTooHigh - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for voltage at the primary pin of the server (ECU) is not met (current voltage is above + a preprogrammed maximum threshold). +- 0x93 - voltageTooLow - This NRC indicates that the requested action will not be taken because the server + prerequisite condition for voltage at the primary pin of the server (ECU) is not met (current voltage is below + a preprogrammed minimum threshold). +- 0x94 - ResourceTemporarilyNotAvailable - This NRC indicates that the server has received the request but + the requested action could not be performed by the server because an application which is necessary to supply + the requested information is temporality not available. This NRC is in general supported by each diagnostic service, + as not otherwise stated in the data link specific implementation document, therefore it is not listed in the list + of applicable response codes of the diagnostic services. +- 0x95-0xEF - reservedForSpecificConditionsNotCorrect - This range of values is reserved for future definition + condition not correct scenarios by ISO 14229 Standard. +- 0xF0-0xFE - vehicleManufacturerSpecificConditionsNotCorrect - This range of values is reserved for vehicle + manufacturer specific condition not correct scenarios. +- 0xFF - ISO Reserved - This value is reserved for future definition by ISO 14229 Standard. .. _knowledge-base-addressing: @@ -541,8 +544,9 @@ Addressing Addressing determines model of UDS communication. We distinguish following addressing types: - - Physical_ - - Functional_ + +- Physical_ +- Functional_ .. _knowledge-base-physical-addressing: @@ -556,7 +560,7 @@ an information that a response is not required (further explained in `response behaviour to physically addressed request`_ chapter). .. note:: You do not need a direct physical connection between a client and a server to have physically addressed - communication as all messages shall be routed to a target of each message. + communication as all messages shall be routed to a target of each message. Response behaviour to physically addressed request @@ -607,21 +611,22 @@ Expected server behaviour in case of receiving physically addressed request mess | | NO | --- | | NRC = SNS or SNSIAS | Servers sends negative response with NRC 0x11 or 0x7F | +--------------------+-------------------+-------------------------+-------------------+---------------------+-------------------------------------------------------------------------------------------------------------+ -Where: - - SPRMIB - flag informing whether Suppress Positive Response Message Indication Bit is set in the received request - message - - SID supported - flag informing whether Service Identifier in the received request message is supported by the server - - SF supported - flag informing whether SubFunction in the received request message is supported by the server - - DataParam supported - information whether values of data parameters (e.g. DIDs, RIDs, DTCStatusMask) in the received - request message are supported by the server - - NRC - Negative Response Code - - ROOR - NRC 0x31 (requestOutOfRange) - - SNS - NRC 0x11 (serviceNotSupported) - - SNSIAS - NRC 0x7F (serviceNotSupportedInActiveSession) - - SFNS - NRC 0x12 (SubFunctionNotSupported) - - SFNSIAS - NRC 0x7E (SubFunctionNotSupportedInActiveSession) - - XX - NRC code that is supported by the server and suitable to the current situation (e.g. NRC 0x21 busyRepeatRequest - if server is currently overloaded and cannot process next request message) +where: + +- SPRMIB - flag informing whether Suppress Positive Response Message Indication Bit is set in the received request + message +- SID supported - flag informing whether Service Identifier in the received request message is supported by the server +- SF supported - flag informing whether SubFunction in the received request message is supported by the server +- DataParam supported - information whether values of data parameters (e.g. DIDs, RIDs, DTCStatusMask) in the received + request message are supported by the server +- NRC - Negative Response Code +- ROOR - NRC 0x31 (requestOutOfRange) +- SNS - NRC 0x11 (serviceNotSupported) +- SNSIAS - NRC 0x7F (serviceNotSupportedInActiveSession) +- SFNS - NRC 0x12 (SubFunctionNotSupported) +- SFNSIAS - NRC 0x7E (SubFunctionNotSupportedInActiveSession) +- XX - NRC code that is supported by the server and suitable to the current situation (e.g. NRC 0x21 busyRepeatRequest + if server is currently overloaded and cannot process next request message) .. _knowledge-base-functional-addressing: @@ -634,7 +639,7 @@ takes place. A server shall only respond to certain functionally addressed reque `response behaviour to functionally addressed request`_ chapter. .. note:: Some types of buses (e.g. LIN) might also support broadcast communication which slightly change expected - server behaviour. When broadcast communication is used, then a server response is never expected by a client. + server behaviour. When broadcast communication is used, then a server response is never expected by a client. Response behaviour to functionally addressed request @@ -685,13 +690,14 @@ Expected server behaviour in case of receiving functionally addressed request me | | NO | --- | | --- | Server does not send a response. | +--------------------+-------------------+-------------------------+-------------------+----------+-------------------------------------------------------------------------------------------------------------+ -Where: - - SPRMIB - flag informing whether Suppress Positive Response Message Indication Bit is set in the received request - message - - SID supported - flag informing whether Service Identifier in the received request message is supported by the server - - SF supported - flag informing whether SubFunction in the received request message is supported by the server - - DataParam supported - information whether values of data parameters (e.g. DIDs, RIDs, DTCStatusMask) in the received - request message are supported by the server - - NRC - Negative Response Code - - XX - NRC code that is supported by the server and suitable to the current situation (e.g. NRC 0x21 busyRepeatRequest - if server is currently overloaded and cannot process next request message) +where: + +- SPRMIB - flag informing whether Suppress Positive Response Message Indication Bit is set in the received request + message +- SID supported - flag informing whether Service Identifier in the received request message is supported by the server +- SF supported - flag informing whether SubFunction in the received request message is supported by the server +- DataParam supported - information whether values of data parameters (e.g. DIDs, RIDs, DTCStatusMask) in the received + request message are supported by the server +- NRC - Negative Response Code +- XX - NRC code that is supported by the server and suitable to the current situation (e.g. NRC 0x21 busyRepeatRequest + if server is currently overloaded and cannot process next request message) diff --git a/docs/source/pages/knowledge_base/osi_model.rst b/docs/source/pages/knowledge_base/osi_model.rst index baa20360..530a80f1 100644 --- a/docs/source/pages/knowledge_base/osi_model.rst +++ b/docs/source/pages/knowledge_base/osi_model.rst @@ -37,67 +37,71 @@ Full list of standards is included in the table below: | | | ISO 11898-3 | | | | | +--------------+-------------+-------------+-------------+-------------+----------------+-------------+ -Where: - - OSI Layer - OSI Model Layer for which standards are relevant - - Common - standards mentioned in this column are always relevant for UDS communication regardless of bus used - - CAN - standards which are specific for UDS on CAN implementation - - FlexRay - standards which are specific for UDS on FlexRay implementation - - Ethernet - standards which are specific for UDS on IP implementation - - K-Line - standards which are specific for UDS on K-Line implementation - - LIN - standards which are specific for UDS on LIN implementation +where: + +- OSI Layer - OSI Model Layer for which standards are relevant +- Common - standards mentioned in this column are always relevant for UDS communication regardless of bus used +- CAN - standards which are specific for UDS on CAN implementation +- FlexRay - standards which are specific for UDS on FlexRay implementation +- Ethernet - standards which are specific for UDS on IP implementation +- K-Line - standards which are specific for UDS on K-Line implementation +- LIN - standards which are specific for UDS on LIN implementation UDS Functionalities ------------------- An overview of features that are required to fully implement UDS protocol is presented in the table below: -+--------------+-------------------------------------------+-------------------------------------------------------+ -| OSI Layer | Functionalities | Implementation | -+==============+===========================================+=======================================================+ -| Layer 7 | - diagnostic messages support | - :mod:`uds.message` | -| Application | | | -+--------------+-------------------------------------------+-------------------------------------------------------+ -| Layer 6 | - diagnostic messages data interpretation | *To be provided with Database feature.* | -| Presentation | | | -| | - messaging database import from a file | | -| | | | -| | - messaging database export to a file | | -+--------------+-------------------------------------------+-------------------------------------------------------+ -| Layer 5 | - Client simulation | *To be provided with Client feature.* | -| Session | | | -| | - Server simulation | *To be provided with Server feature.* | -+--------------+-------------------------------------------+-------------------------------------------------------+ -| Layer 4 | - UDS packet support | - :mod:`uds.packet` | -| Transport | | | -| | - bus specific segmentation | - :mod:`uds.segmentation` | -| | | | -| | - bus specific packets transmission | - :mod:`uds.transport_interface` | -| | | | -| | | - :mod:`uds.can` | -| | | | -+--------------+ | *To be extended with support for:* | -| Layer 3 | | | -| Network | | - *Ethernet* | -| | | | -| | | - *LIN* | -| | | | -| | | - *K-Line* | -| | | | -| | | - *FlexRay* | -+--------------+-------------------------------------------+-------------------------------------------------------+ -| Layer 2 | - frames transmission | External python packages for bus handling: | -| Data | | | -| | - frames receiving | - CAN: | -+--------------+ | | -| Layer 1 | | - `python-can `_ | -| Physical | | | -| | | *More packages handling other buses to be decided.* | -+--------------+-------------------------------------------+-------------------------------------------------------+ - -Where: - - OSI Layer - considered OSI Model Layer - - Functionalities - functionalities required in the implementation to handle considered UDS OSI layer - - Implementation - UDS package implementation that provides mentioned functionalities ++--------------+-------------------------------------------+-----------------------------------------------------+ +| OSI Layer | Functionalities | Implementation | ++==============+===========================================+=====================================================+ +| Layer 7 | - diagnostic messages support | - :mod:`uds.message` | +| Application | | | ++--------------+-------------------------------------------+-----------------------------------------------------+ +| Layer 6 | - diagnostic messages data interpretation | *To be provided with Database feature.* | +| Presentation | | | +| | - messaging database import from a file | | +| | | | +| | - messaging database export to a file | | ++--------------+-------------------------------------------+-----------------------------------------------------+ +| Layer 5 | - Client simulation | *To be provided with Client feature.* | +| Session | | | +| | - Server simulation | *To be provided with Server feature.* | +| | | | +| | - sniffing UDS communication | *To be provided with Sniffer feature.* | ++--------------+-------------------------------------------+-----------------------------------------------------+ +| Layer 4 | - UDS packet support | - :mod:`uds.packet` | +| Transport | | | +| | - bus specific segmentation | - :mod:`uds.segmentation` | +| | | | +| | - bus specific packets transmission | - :mod:`uds.transport_interface` | +| | | | +| | | - :mod:`uds.can` | +| | | | ++--------------+ | *To be extended with support for:* | +| Layer 3 | | | +| Network | | - *Ethernet* | +| | | | +| | | - *LIN* | +| | | | +| | | - *K-Line* | +| | | | +| | | - *FlexRay* | ++--------------+-------------------------------------------+-----------------------------------------------------+ +| Layer 2 | - frames transmission | External python packages for bus handling: | +| Data | | | +| | - frames receiving | - CAN: | ++--------------+ | | +| Layer 1 | | - python-can | +| Physical | | | +| | | *More packages handling other buses to be decided.* | ++--------------+-------------------------------------------+-----------------------------------------------------+ + +where: + +- OSI Layer - considered OSI Model Layer +- Functionalities - functionalities required in the implementation to handle considered UDS OSI layer +- Implementation - UDS package implementation that provides mentioned functionalities Protocol Data Units @@ -125,8 +129,8 @@ To make things simpler for the users and our developers, in the implementation w Implementation of frames is usually provided by external packages. .. figure:: ../../diagrams/KnowledgeBase-PDUs.png - :alt: UDS PDUs - :figclass: align-center - :width: 100% + :alt: UDS PDUs + :figclass: align-center + :width: 100% - UDS Protocol Data Units on different layers of OSI Model. + UDS Protocol Data Units on different layers of OSI Model. diff --git a/docs/source/pages/knowledge_base/packet.rst b/docs/source/pages/knowledge_base/packet.rst index 45ab6624..64e9532b 100644 --- a/docs/source/pages/knowledge_base/packet.rst +++ b/docs/source/pages/knowledge_base/packet.rst @@ -9,9 +9,10 @@ There are some packets which does not carry any diagnostic message data as they other packets. UDS packet consists of following fields: - - `Network Address Information`_ (N_AI) - packet addressing - - `Network Data Field`_ (N_Data) - packet data - - `Network Protocol Control Information`_ (N_PCI) - packet type + + - `Network Address Information`_ (N_AI) - packet addressing + - `Network Data Field`_ (N_Data) - packet data + - `Network Protocol Control Information`_ (N_PCI) - packet type .. _knowledge-base-n-ai: @@ -67,7 +68,6 @@ influenced by UDS protocol) are listed below: There are two formats of CAN ID: - Standard (11-bit Identifier) - - Extended (29-bit identifier) - Data Length Code (DLC) @@ -116,7 +116,7 @@ influenced by UDS protocol) are listed below: +-----+--------------------------+----------------------------+---------------------+ .. note:: To learn more about CAN bus and CAN frame structure, you are encouraged to visit - `e-learning portal of Vector Informatik GmbH `_. + `e-learning portal of Vector Informatik GmbH `_. .. _knowledge-base-can-addressing: @@ -127,17 +127,19 @@ Each CAN packet addressing format describes a different way of providing `Networ recipients of CAN packets. The exchange of UDS Packets on CAN is supported by three addressing formats: - - :ref:`Normal addressing ` - - :ref:`Extended addressing ` - - :ref:`Mixed addressing ` + +- :ref:`Normal addressing ` +- :ref:`Extended addressing ` +- :ref:`Mixed addressing ` .. warning:: Addressing format must be predefined and configured before any CAN packet is received as every - CAN packet addressing format determines a different way of decoding CAN packets information - (`Network Address Information`_, `Network Data Field`_ and `Network Protocol Control Information`_) - that is not compatible with other addressing formats. + CAN packet addressing format determines a different way of decoding CAN packets information + (`Network Address Information`_, `Network Data Field`_ and `Network Protocol Control Information`_) + that is not compatible with other addressing formats. -.. note:: Regardless of addressing format used, to transmit a :ref:`functionally addressed ` - message over CAN, a sender is allowed to use :ref:`Single Frame ` packets only. +.. note:: Regardless of addressing format used, to transmit + a :ref:`functionally addressed ` message over CAN, a sender is allowed to use + :ref:`Single Frame ` packets only. .. _knowledge-base-can-normal-addressing: @@ -148,14 +150,18 @@ If normal addressing format is used, then the value of CAN Identifier carries an Basing on CAN Identifier value, it is possible to distinguish :ref:`an addressing type `, a sender and a target/targets entities of a packet. +.. note:: With normal addressing, both 11-bit (standard) and 29-bit (extended) CAN Identifiers are allowed. + Following parameters specifies `Network Address Information`_ when Normal Addressing is used: - - CAN ID + +- CAN ID - informs about transmitting and receiving nodes .. note:: Correspondence between `Network Address Information`_ and the value of CAN Identifier is left open for - a network designer unless :ref:`normal fixed addressing ` subformat is used. + a network designer unless :ref:`normal fixed addressing ` sub-format + is used. .. note:: `Network Protocol Control Information`_ is placed in the **first byte** of - :ref:`CAN frame data field ` if normal addressing format is used. + :ref:`CAN frame data field ` if normal addressing format is used. .. _knowledge-base-can-normal-fixed-addressing: @@ -165,30 +171,83 @@ Normal Fixed Addressing Normal fixed addressing format is a special case of :ref:`normal addressing ` in which the mapping of the address information into the CAN identifier is further defined. -.. note:: For normal fixed addressing, only 29-bit (extended) CAN Identifiers are allowed. +.. note:: With normal fixed addressing, only 29-bit (extended) CAN Identifiers are allowed. Following parameters specifies `Network Address Information`_ when Normal Fixed Addressing is used: - - CAN ID (with embedded **Target Address** and **Source Address**) - -CAN Identifier values used for UDS communication using normal fixed addressing: - - For :ref:`physical addressed ` messages, CAN Identifier value is defined - as presented below: - .. code-block:: +- CAN ID (with embedded **Target Address** and **Source Address**) - **Source Address** informs about transmitting node + and **Target Address** informs about receiving node - CAN_ID = 0x18DATTSS - - - For :ref:`functional addressed ` messages, CAN Identifier value is defined - as presented below: - - .. code-block:: +CAN Identifier values used for UDS communication using normal fixed addressing: - CAN_ID = 0x18DBTTSS +- For :ref:`physical addressed ` messages, CAN Identifier value is defined + as presented below: + + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | | Priority | Reserved Bit | Data Page | Protocol data | Target | Source | Data | + | | | | | unit format | Address | Address | | + +================+==========+==============+===========+===============+=========+=========+===============+ + | Bits number | 3 | 1 | 1 | 8 | 8 | 8 | 16-512 | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | Content | 0 - 7 | 0 | 0 | 218 | N_TA | N_SA | N_PCI, N_Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN field | CAN Identifier | CAN Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN ID bits | 28-26 | 25 | 24 | 23-16 | 15-8 | 7-0 | --- | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN data bytes | --- | --- | --- | --- | --- | --- | 1-64 | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + + .. code-block:: + + # assuming priority parameter equals 0 + CAN_ID = 0xDATTSS + + # assuming priority parameter equals 6 (default value) + CAN_ID = 0x18DATTSS + + # assuming priority parameter equals 7 + CAN_ID = 0x1CDATTSS + + +- For :ref:`functional addressed ` messages, CAN Identifier value is defined + as presented below: + + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | | Priority | Reserved Bit | Data Page | Protocol data | Target | Source | Data | + | | | | | unit format | Address | Address | | + +================+==========+==============+===========+===============+=========+=========+===============+ + | Bits number | 3 | 1 | 1 | 8 | 8 | 8 | 16-512 | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | Content | 0 - 7 | 0 | 0 | 219 | N_TA | N_SA | N_PCI, N_Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN field | CAN Identifier | CAN Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN ID bits | 28-26 | 25 | 24 | 23-16 | 15-8 | 7-0 | --- | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + | CAN data bytes | --- | --- | --- | --- | --- | --- | 1-64 | + +----------------+----------+--------------+-----------+---------------+---------+---------+---------------+ + + .. code-block:: + + # assuming priority parameter equals 0 + CAN_ID = 0xDBTTSS + + # assuming priority parameter equals 6 (default value) + CAN_ID = 0x18DBTTSS + + # assuming priority parameter equals 7 + CAN_ID = 0x1CDBTTSS where: - - CAN_ID - value of **CAN Identifier** - - TT - two (hexadecimal) digits of a 8-bit **Target Address** value - - SS - two (hexadecimal) digits of a 8-bit **Source Address** value + +- CAN_ID - value of **CAN Identifier** +- TT - two (hexadecimal) digits of a 8-bit **Target Address** value +- SS - two (hexadecimal) digits of a 8-bit **Source Address** value +- N_TA - Network **Target Address** parameter +- N_SA - Network **Source Address** parameter +- :ref:`N_PCI ` - Network Protocol Control Information +- :ref:`N_Data ` - Network Data Field .. _knowledge-base-can-extended-addressing: @@ -199,9 +258,13 @@ If extended addressing format is used, then the value of **the first CAN frame b a UDS packet and remaining `Network Address Information`_ (a sending entity and :ref:`an addressing type `) are determined by CAN Identifier value. +.. note:: With extended addressing, both 11-bit (standard) and 29-bit (extended) CAN Identifiers are allowed. + Following parameters specifies `Network Address Information`_ when Extended Addressing is used: - - CAN ID - - Target Address (located in the first data byte of a :ref:`CAN Frame `) + +- CAN ID - identifies network and message direction +- Target Address (located in the first data byte of a :ref:`CAN Frame `) - informs about + receiving and transmitting nodes within the network .. note:: `Network Protocol Control Information`_ is placed in the **second byte** of :ref:`CAN frame data field ` if extended addressing format is used. @@ -226,8 +289,11 @@ If mixed addressing format is used with 11-bit CAN Identifiers, then the value o the CAN Identifier and a combination of these data forms the entire `Network Address Information`_ of a CAN packet. Following parameters specifies `Network Address Information`_ when Extended Addressing is used: - - CAN ID - - Addressing Extension (located in the first data byte of a :ref:`CAN Frame `) + +- CAN ID - informs about transmitting and receiving nodes withing the network (combining with **Addressing Extension** + identifies those) +- Addressing Extension (located in the first data byte of a :ref:`CAN Frame `) - selects + network (the same value is used during communication in both directions) .. _knowledge-base-can-mixed-29-bit-addressing: @@ -239,28 +305,83 @@ the CAN Identifier (that contains **Target Address** and **Sender Address** valu a combination of these data forms the entire `Network Address Information`_ of a CAN packet. Following parameters specifies `Network Address Information`_ when Extended Addressing is used: - - CAN ID (with embedded **Target Address** and **Source Address**) - - Addressing Extension (located in the first data byte of a :ref:`CAN Frame `) -CAN Identifier values used for UDS communication using mixed 29-bit addressing: - - For :ref:`physical addressed ` messages, CAN Identifier value is defined - as presented below: - - .. code-block:: - - CAN_ID = 0x18CETTSS - - - For :ref:`functional addressed ` messages, CAN Identifier value is defined - as presented below: +- CAN ID (with embedded **Target Address** and **Source Address**) - **Source Address** informs about transmitting node + and **Target Address** informs about receiving node in the network (combining with **Addressing Extension** identifies + those) +- Addressing Extension (located in the first data byte of a :ref:`CAN Frame `) - selects + network (the same value is used during communication in both directions) - .. code-block:: +CAN Identifier values used for UDS communication using mixed 29-bit addressing: - CAN_ID = 0x18CDTTSS +- For :ref:`physical addressed ` messages, CAN Identifier value is defined + as presented below: + + +----------------+----------+--------------+-----------+---------------+---------+---------+----------------------+ + | | Priority | Reserved Bit | Data Page | Protocol data | Target | Source | Data | + | | | | | unit format | Address | Address | | + +================+==========+==============+===========+===============+=========+=========+======+===============+ + | Bits number | 3 | 1 | 1 | 8 | 8 | 8 | 8 | 16-504 | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | Content | 0 - 7 | 0 | 0 | 206 | N_TA | N_SA | N_AE | N_PCI, N_Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN field | CAN Identifier | CAN Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN ID bits | 28-26 | 25 | 24 | 23-16 | 15-8 | 7-0 | --- | --- | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN data bytes | --- | --- | --- | --- | --- | --- | 1 | 2-64 | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + + .. code-block:: + + # assuming priority parameter equals 0 + CAN_ID = 0xCETTSS + + # assuming priority parameter equals 6 (default value) + CAN_ID = 0x18CETTSS + + # assuming priority parameter equals 7 + CAN_ID = 0x1CCETTSS + +- For :ref:`functional addressed ` messages, CAN Identifier value is defined + as presented below: + + +----------------+----------+--------------+-----------+---------------+---------+---------+----------------------+ + | | Priority | Reserved Bit | Data Page | Protocol data | Target | Source | Data | + | | | | | unit format | Address | Address | | + +================+==========+==============+===========+===============+=========+=========+======+===============+ + | Bits number | 3 | 1 | 1 | 8 | 8 | 8 | 8 | 16-504 | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | Content | 0 - 7 | 0 | 0 | 205 | N_TA | N_SA | N_AE | N_PCI, N_Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN field | CAN Identifier | CAN Data | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN ID bits | 28-26 | 25 | 24 | 23-16 | 15-8 | 7-0 | --- | --- | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + | CAN data bytes | --- | --- | --- | --- | --- | --- | 1 | 2-64 | + +----------------+----------+--------------+-----------+---------------+---------+---------+------+---------------+ + + .. code-block:: + + # assuming priority parameter equals 0 + CAN_ID = 0xCDTTSS + + # assuming priority parameter equals 6 (default value) + CAN_ID = 0x18CDTTSS + + # assuming priority parameter equals 7 + CAN_ID = 0x1CCDTTSS where: - - CAN_ID - value of **CAN Identifier** - - TT - two (hexadecimal) digits of a 8-bit **Target Address** value - - SS - two (hexadecimal) digits of a 8-bit **Source Address** value + +- CAN_ID - value of **CAN Identifier** +- TT - two (hexadecimal) digits of a 8-bit **Target Address** value +- SS - two (hexadecimal) digits of a 8-bit **Source Address** value +- N_TA - Network **Target Address** parameter +- N_SA - Network **Source Address** parameter +- N_AE - Network **Addressing Extension** parameter +- :ref:`N_PCI ` - Network Protocol Control Information +- :ref:`N_Data ` - Network Data Field .. _knowledge-base-can-data-field: @@ -290,10 +411,11 @@ The only exception is usage of `CAN Frame Data Optimization`_. +-----+------------------------------------------------------------------------+ where: - - DLC - Data Length Code of a :ref:`CAN frame ` + +- DLC - Data Length Code of a :ref:`CAN frame ` .. note:: Number of bytes that carry diagnostic message payload depends on a type and a format of a CAN packet as it is - presented in :ref:`the table with CAN packets formats `. + presented in :ref:`the table with CAN packets formats `. .. _knowledge-base-can-frame-data-padding: @@ -308,7 +430,7 @@ If not specified differently, the default value 0xCC shall be used for the frame insertions and bit alteration on the wire. .. note:: CAN frame data padding is mandatory for :ref:`CAN frames ` with DLC>8 and - optional for frames with DLC=8. + optional for frames with DLC=8. .. _knowledge-base-can-data-optimization: @@ -322,15 +444,15 @@ that is required to sent a desired number of data bytes in a single CAN packet. .. note:: CAN Frame Data Optimization might always be used for CAN Packets with less than 8 bytes of data to send. -.. warning:: CAN Frame Data Optimization might not always be able to replace `CAN Frame Data Padding`_ when CAN FD is used. - This is a consequence of DLC values from 9 to 15 meaning as these values are mapped into CAN frame data bytes numbers - in a non-linear way (e.g. DLC=9 represents 12 data bytes). +.. warning:: CAN Frame Data Optimization might not always be able to replace `CAN Frame Data Padding`_ when CAN FD + is used. This is a consequence of DLC values from 9 to 15 meaning as these values are mapped into CAN frame data + bytes numbers in a non-linear way (e.g. DLC=9 represents 12 data bytes). - Example: + Example: - *When a CAN Packet with 47 bytes of data is planned for a transmission, then DLC=14 can be used instead of DLC=15,* - *to choose 48-byte instead of 64-byte long CAN frame. Unfortunately, the last byte of CAN Frame data has to be padded* - *as there is no way to send over CAN a frame with exactly 47 bytes of data.* + *When a CAN Packet with 47 bytes of data is planned for a transmission, then DLC=14 can be used instead of DLC=15,* + *to choose 48-byte instead of 64-byte long CAN frame. Unfortunately, the last byte of CAN Frame data has to be * + *padded as there is no way to send over CAN a frame with exactly 47 bytes of data.* .. _knowledge-base-can-n-pci: @@ -340,11 +462,12 @@ CAN Packet Types According to ISO 15765-2, CAN bus supports 4 types of UDS packets. List of all values of `Network Protocol Control Information`_ supported by CAN bus: - - 0x0 - :ref:`Single Frame ` - - 0x1 - :ref:`First Frame ` - - 0x2 - :ref:`Consecutive Frame ` - - 0x3 - :ref:`Flow Control ` - - 0x4-0xF - values range reserved for future extension by ISO 15765 + +- 0x0 - :ref:`Single Frame ` +- 0x1 - :ref:`First Frame ` +- 0x2 - :ref:`Consecutive Frame ` +- 0x3 - :ref:`Flow Control ` +- 0x4-0xF - values range reserved for future extension by ISO 15765 The format of all CAN packets is presented in the table below. @@ -377,14 +500,15 @@ The format of all CAN packets is presented in the table below. +-------------------+----------+----------+---------+---------+---------+---------+---------+-----+ where: - - DLC - Data Length Code of a CAN frame, it is equal to number of data bytes carried by this CAN frame - - SF_DL - :ref:`Single Frame Data Length ` - - FF_DL - :ref:`First Frame Data Length ` - - SN - :ref:`Sequence Number ` - - FS - :ref:`Flow Status ` - - BS - :ref:`Block Size ` - - ST_min - :ref:`Separation Time minimum ` - - N/A - Not Applicable (byte does not carry any information) + +- DLC - Data Length Code of a CAN frame, it is equal to number of data bytes carried by this CAN frame +- SF_DL - :ref:`Single Frame Data Length ` +- FF_DL - :ref:`First Frame Data Length ` +- SN - :ref:`Sequence Number ` +- FS - :ref:`Flow Status ` +- BS - :ref:`Block Size ` +- ST_min - :ref:`Separation Time minimum ` +- N/A - Not Applicable (byte does not carry any information) .. _knowledge-base-can-single-frame: @@ -407,7 +531,7 @@ carried by every Single Frame as presented in SF_DL specifies number of diagnostic message payload bytes transmitted in a Single Frame. .. note:: Maximal value of SF_DL depends on Single Frame :ref:`addressing format ` - and :ref:`DLC of a CAN message ` that carries this packet. + and :ref:`DLC of a CAN message ` that carries this packet. .. _knowledge-base-can-first-frame: @@ -430,7 +554,7 @@ First Frame. FF_DL specifies number of diagnostic message payload bytes of a dia was initiated by a First Frame. .. note:: Maximal value of FF_DL is 4294967295 (0xFFFFFFFF). It means that CAN bus is capable of transmitting - diagnostic messages that contains up to nearly 4,3 GB of payload bytes. + diagnostic messages that contains up to nearly 4,3 GB of payload bytes. .. _knowledge-base-can-consecutive-frame: @@ -452,12 +576,13 @@ Sequence Number Sequence Number (SN) is 4-bit value used to specify the order of Consecutive Frames. The rules of proper Sequence Number value assignment are following: - - SN value of the first :ref:`Consecutive Frame ` that directly follows - a :ref:`First Frame ` shall be set to 1 - - SN shall be incremented by 1 for each following :ref:`Consecutive Frame ` - - SN value shall not be affected by :ref:`Flow Control ` frames - - when SN reaches the value of 15, it shall wraparound and be set to 0 in the next - :ref:`Consecutive Frame ` + + - SN value of the first :ref:`Consecutive Frame ` that directly follows + a :ref:`First Frame ` shall be set to 1 + - SN shall be incremented by 1 for each following :ref:`Consecutive Frame ` + - SN value shall not be affected by :ref:`Flow Control ` frames + - when SN reaches the value of 15, it shall wraparound and be set to 0 in the next + :ref:`Consecutive Frame ` .. _knowledge-base-can-flow-control: @@ -468,9 +593,10 @@ Flow Control (FC) is used by receiving CAN entities to instruct sending entities transmission of :ref:`Consecutive Frames `. Flow Control packet contains following parameters: - - :ref:`Flow Status ` - - :ref:`Block Size ` - - :ref:`Separation Time Minimum ` + +- :ref:`Flow Status ` +- :ref:`Block Size ` +- :ref:`Separation Time Minimum ` .. _knowledge-base-can-flow-status: @@ -481,48 +607,50 @@ Flow Status (FS) is 4-bit value that is used to inform a sending network entity a Consecutive Frames transmission. Values of Flow Status: - - 0x0 - ContinueToSend (CTS) - ContinueToSend value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded - with CTS) is ready to receive a maximum of :ref:`Block Size ` number of - :ref:`Consecutive Frames `. +- 0x0 - ContinueToSend (CTS) - Reception of a :ref:`Flow Control ` frame with ContinueToSend value shall cause - the sender to resume ConsecutiveFrames sending. + ContinueToSend value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded + with CTS) is ready to receive a maximum of :ref:`Block Size ` number of + :ref:`Consecutive Frames `. - - 0x1 - wait (WAIT) + Reception of a :ref:`Flow Control ` frame with ContinueToSend value shall cause + the sender to resume ConsecutiveFrames sending. - Wait value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded with WAIT) - is not ready to receive another :ref:`Consecutive Frames `. +- 0x1 - wait (WAIT) - Reception of a :ref:`Flow Control ` frame with WAIT value shall cause - the sender to pause ConsecutiveFrames sending and wait for another - :ref:`Flow Control ` frame. + Wait value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded with WAIT) + is not ready to receive another :ref:`Consecutive Frames `. - Values of :ref:`Block Size ` and :ref:`STmin ` in - the :ref:`Flow Control ` frame (that contains WAIT value of Flow Status) - are not relevant and shall be ignored. + Reception of a :ref:`Flow Control ` frame with WAIT value shall cause + the sender to pause ConsecutiveFrames sending and wait for another + :ref:`Flow Control ` frame. - - 0x2 - Overflow (OVFLW) + Values of :ref:`Block Size ` and :ref:`STmin ` in + the :ref:`Flow Control ` frame (that contains WAIT value of Flow Status) + are not relevant and shall be ignored. - Overflow value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded with OVFLW) - is not able to receive a full diagnostic message as it is too big and reception of the message would result in - `Buffer Overflow `_ on receiving side. In other words, the value of - :ref:`FF_DL ` exceeds the buffer size of the receiving entity. +- 0x2 - Overflow (OVFLW) - Reception of a :ref:`Flow Control ` frame with Overflow value shall cause - the sender to abort the transmission of a diagnostic message. + Overflow value of Flow Status informs a sender of a diagnostic message that receiving entity (that responded + with OVFLW) is not able to receive a full diagnostic message as it is too big and reception of the message would + result in `Buffer Overflow `_ on receiving side. + In other words, the value of :ref:`FF_DL ` exceeds the buffer size of + the receiving entity. - Overflow value shall only be sent in a :ref:`Flow Control ` frame that directly - follows a :ref:`First Frame `. + Reception of a :ref:`Flow Control ` frame with Overflow value shall cause + the sender to abort the transmission of a diagnostic message. - Values of :ref:`Block Size ` and :ref:`STmin ` in - the :ref:`Flow Control ` frame (that contains OVFLW value of Flow Status) - are not relevant and shall be ignored. + Overflow value shall only be sent in a :ref:`Flow Control ` frame that directly + follows a :ref:`First Frame `. - - 0x3-0xF - Reserved + Values of :ref:`Block Size ` and :ref:`STmin ` in + the :ref:`Flow Control ` frame (that contains OVFLW value of Flow Status) + are not relevant and shall be ignored. - This range of values is reserved for future extension by ISO 15765. +- 0x3-0xF - Reserved + + This range of values is reserved for future extension by ISO 15765. .. _knowledge-base-can-block-size: @@ -533,21 +661,22 @@ Block Size (BS) is a one byte value specified by receiving entity that informs a :ref:`Consecutive Frames ` to be sent in a one block of packets. Block Size values: - - 0x00 - The value 0 of the Block Size parameter informs a sender that no more - :ref:`Flow Control ` frames shall be sent during the transmission - of the segmented message. +- 0x00 + + The value 0 of the Block Size parameter informs a sender that no more + :ref:`Flow Control ` frames shall be sent during the transmission + of the segmented message. - Reception of Block Size = 0 shall cause the sender to send all remaining - :ref:`Consecutive Frames ` without any stop for further - :ref:`Flow Control ` frames from the receiving entity. + Reception of Block Size = 0 shall cause the sender to send all remaining + :ref:`Consecutive Frames ` without any stop for further + :ref:`Flow Control ` frames from the receiving entity. - - 0x01-0xFF +- 0x01-0xFF - This range of Block Size values informs a sender the maximum number of - :ref:`Consecutive Frames ` that can be transmitted without an intermediate - :ref:`Flow Control ` frames from the receiving entity. + This range of Block Size values informs a sender the maximum number of + :ref:`Consecutive Frames ` that can be transmitted without an intermediate + :ref:`Flow Control ` frames from the receiving entity. .. _knowledge-base-can-st-min: @@ -558,34 +687,35 @@ Separation Time minimum (STmin) is a one byte value specified by receiving entit between the transmission of two following :ref:`Consecutive Frames `. STmin values: - - 0x00-0x7F - Separation Time minimum range 0-127 ms - The value of STmin in this range represents the value in milliseconds (ms). +- 0x00-0x7F - Separation Time minimum range 0-127 ms + + The value of STmin in this range represents the value in milliseconds (ms). - 0x00 = 0 ms + 0x00 = 0 ms - 0xFF = 127 ms + 0xFF = 127 ms - - 0x80-0xF0 - Reserved +- 0x80-0xF0 - Reserved - This range of values is reserved for future extension by ISO 15765. + This range of values is reserved for future extension by ISO 15765. - - 0xF1-0xF9 - Separation Time minimum range 100-900 μs +- 0xF1-0xF9 - Separation Time minimum range 100-900 μs - The value of STmin in this range represents the value in microseconds (μs) according to the formula: + The value of STmin in this range represents the value in microseconds (μs) according to the formula: - .. code-block:: + .. code-block:: - (STmin - 0xF0) * 100 μs + (STmin - 0xF0) * 100 μs - Meaning of example values: + Meaning of example values: - 0xF1 -> 100 μs + 0xF1 -> 100 μs - 0xF5 -> 500 μs + 0xF5 -> 500 μs - 0xF9 -> 900 μs + 0xF9 -> 900 μs - - 0xFA-0xFF - Reserved +- 0xFA-0xFF - Reserved - This range of values is reserved for future extension by ISO 15765. + This range of values is reserved for future extension by ISO 15765. diff --git a/docs/source/pages/user_guide/segmentation.rst b/docs/source/pages/user_guide/segmentation.rst index 86dfe3cb..a934f9b5 100644 --- a/docs/source/pages/user_guide/segmentation.rst +++ b/docs/source/pages/user_guide/segmentation.rst @@ -34,7 +34,7 @@ Following functionalities are provided by :class:`~uds.segmentation.can_segmente # define Addressing Information for a CAN Node can_node_addressing_information = uds.can.CanAddressingInformation( - addressing_format=uds.can.CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=uds.can.CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -48,7 +48,7 @@ Following functionalities are provided by :class:`~uds.segmentation.can_segmente # change CAN Segmenter configuration can_segmenter.addressing_information = uds.can.CanAddressingInformation( - uds.can.CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + uds.can.CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x612}, rx_physical={"can_id": 0x611}, tx_functional={"can_id": 0x6FE}, diff --git a/docs/source/pages/user_guide/transport/can.rst b/docs/source/pages/user_guide/transport/can.rst index 04babd70..5ccb7824 100644 --- a/docs/source/pages/user_guide/transport/can.rst +++ b/docs/source/pages/user_guide/transport/can.rst @@ -80,7 +80,7 @@ the user perspective it does not provide any additional features to common_ impl # define Addressing Information for a CAN Node can_node_addressing_information = uds.can.CanAddressingInformation( - addressing_format=uds.can.CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=uds.can.CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/docs/source/tables/CAN/CAN_ID_mixed_functional.tgn b/docs/source/tables/CAN/CAN_ID_mixed_functional.tgn new file mode 100644 index 00000000..1f84fda2 --- /dev/null +++ b/docs/source/tables/CAN/CAN_ID_mixed_functional.tgn @@ -0,0 +1 @@ +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"","cspan":1,"rspan":1,"markup":[]},{"value":"Priority","cspan":1,"rspan":1,"markup":[1,8]},{"value":"Reserved Bit","cspan":1,"rspan":1,"markup":[1,12]},{"value":"Data Page","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Protocol data\nunit format","cspan":1,"rspan":1,"markup":[1,25]},{"value":"Target\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Source\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Data","cspan":2,"rspan":1,"markup":[1,4]},{"value":"Data","cspan":-1,"rspan":1,"markup":[1,4]}],[{"value":"Bits number","cspan":1,"rspan":1,"markup":[1,11]},{"value":"3","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"16-504","cspan":1,"rspan":1,"markup":[1,6]}],[{"value":"Content","cspan":1,"rspan":1,"markup":[1,7]},{"value":"0 - 7","cspan":1,"rspan":1,"markup":[1,5]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"205","cspan":1,"rspan":1,"markup":[1,3]},{"value":"N_TA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_SA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_AE","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_PCI, N_Data","cspan":1,"rspan":1,"markup":[1,13]}],[{"value":"CAN field","cspan":1,"rspan":1,"markup":[1,9]},{"value":"CAN Identifier","cspan":6,"rspan":1,"markup":[1,14]},{"value":"","cspan":-1,"rspan":1,"markup":[]},{"value":"","cspan":-2,"rspan":1,"markup":[]},{"value":"","cspan":-3,"rspan":1,"markup":[]},{"value":"","cspan":-4,"rspan":1,"markup":[]},{"value":"","cspan":-5,"rspan":1,"markup":[]},{"value":"CAN Data","cspan":2,"rspan":1,"markup":[1,8]},{"value":"CAN Data","cspan":-1,"rspan":1,"markup":[1,8]}],[{"value":"CAN ID bits","cspan":1,"rspan":1,"markup":[1,11]},{"value":"28-26","cspan":1,"rspan":1,"markup":[1,5]},{"value":"25","cspan":1,"rspan":1,"markup":[1,2]},{"value":"24","cspan":1,"rspan":1,"markup":[1,2]},{"value":"23-16","cspan":1,"rspan":1,"markup":[1,5]},{"value":"15-8","cspan":1,"rspan":1,"markup":[1,4]},{"value":"7-0","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]}],[{"value":"CAN data bytes","cspan":1,"rspan":1,"markup":[1,14]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"2-64","cspan":1,"rspan":1,"markup":[1,4]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/docs/source/tables/CAN/CAN_ID_mixed_physical.tgn b/docs/source/tables/CAN/CAN_ID_mixed_physical.tgn new file mode 100644 index 00000000..b95a17fe --- /dev/null +++ b/docs/source/tables/CAN/CAN_ID_mixed_physical.tgn @@ -0,0 +1 @@ +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"","cspan":1,"rspan":1,"markup":[]},{"value":"Priority","cspan":1,"rspan":1,"markup":[1,8]},{"value":"Reserved Bit","cspan":1,"rspan":1,"markup":[1,12]},{"value":"Data Page","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Protocol data\nunit format","cspan":1,"rspan":1,"markup":[1,25]},{"value":"Target\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Source\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Data","cspan":2,"rspan":1,"markup":[1,4]},{"value":"Data","cspan":-1,"rspan":1,"markup":[1,4]}],[{"value":"Bits number","cspan":1,"rspan":1,"markup":[1,11]},{"value":"3","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"16-504","cspan":1,"rspan":1,"markup":[1,6]}],[{"value":"Content","cspan":1,"rspan":1,"markup":[1,7]},{"value":"0 - 7","cspan":1,"rspan":1,"markup":[1,5]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"206","cspan":1,"rspan":1,"markup":[1,3]},{"value":"N_TA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_SA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_AE","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_PCI, N_Data","cspan":1,"rspan":1,"markup":[1,13]}],[{"value":"CAN field","cspan":1,"rspan":1,"markup":[1,9]},{"value":"CAN Identifier","cspan":6,"rspan":1,"markup":[1,14]},{"value":"","cspan":-1,"rspan":1,"markup":[]},{"value":"","cspan":-2,"rspan":1,"markup":[]},{"value":"","cspan":-3,"rspan":1,"markup":[]},{"value":"","cspan":-4,"rspan":1,"markup":[]},{"value":"","cspan":-5,"rspan":1,"markup":[]},{"value":"CAN Data","cspan":2,"rspan":1,"markup":[1,8]},{"value":"CAN Data","cspan":-1,"rspan":1,"markup":[1,8]}],[{"value":"CAN ID bits","cspan":1,"rspan":1,"markup":[1,11]},{"value":"28-26","cspan":1,"rspan":1,"markup":[1,5]},{"value":"25","cspan":1,"rspan":1,"markup":[1,2]},{"value":"24","cspan":1,"rspan":1,"markup":[1,2]},{"value":"23-16","cspan":1,"rspan":1,"markup":[1,5]},{"value":"15-8","cspan":1,"rspan":1,"markup":[1,4]},{"value":"7-0","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]}],[{"value":"CAN data bytes","cspan":1,"rspan":1,"markup":[1,14]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"2-64","cspan":1,"rspan":1,"markup":[1,4]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/docs/source/tables/CAN/CAN_ID_normal_fixed_functional.tgn b/docs/source/tables/CAN/CAN_ID_normal_fixed_functional.tgn new file mode 100644 index 00000000..968ca0af --- /dev/null +++ b/docs/source/tables/CAN/CAN_ID_normal_fixed_functional.tgn @@ -0,0 +1 @@ +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"","cspan":1,"rspan":1,"markup":[]},{"value":"Priority","cspan":1,"rspan":1,"markup":[1,8]},{"value":"Reserved Bit","cspan":1,"rspan":1,"markup":[1,12]},{"value":"Data Page","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Protocol data\nunit format","cspan":1,"rspan":1,"markup":[1,25]},{"value":"Target\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Source\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Data","cspan":1,"rspan":1,"markup":[1,4]}],[{"value":"Bits number","cspan":1,"rspan":1,"markup":[1,11]},{"value":"3","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"16-512","cspan":1,"rspan":1,"markup":[1,6]}],[{"value":"Content","cspan":1,"rspan":1,"markup":[1,7]},{"value":"0 - 7","cspan":1,"rspan":1,"markup":[1,5]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"219","cspan":1,"rspan":1,"markup":[1,3]},{"value":"N_TA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_SA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_PCI, N_Data","cspan":1,"rspan":1,"markup":[1,13]}],[{"value":"CAN field","cspan":1,"rspan":1,"markup":[1,9]},{"value":"CAN Identifier","cspan":6,"rspan":1,"markup":[1,14]},{"value":"","cspan":-1,"rspan":1,"markup":[]},{"value":"","cspan":-2,"rspan":1,"markup":[]},{"value":"","cspan":-3,"rspan":1,"markup":[]},{"value":"","cspan":-4,"rspan":1,"markup":[]},{"value":"","cspan":-5,"rspan":1,"markup":[]},{"value":"CAN Data","cspan":1,"rspan":1,"markup":[1,8]}],[{"value":"CAN ID bits","cspan":1,"rspan":1,"markup":[1,11]},{"value":"28-26","cspan":1,"rspan":1,"markup":[1,5]},{"value":"25","cspan":1,"rspan":1,"markup":[1,2]},{"value":"24","cspan":1,"rspan":1,"markup":[1,2]},{"value":"23-16","cspan":1,"rspan":1,"markup":[1,5]},{"value":"15-8","cspan":1,"rspan":1,"markup":[1,4]},{"value":"7-0","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]}],[{"value":"CAN data bytes","cspan":1,"rspan":1,"markup":[1,14]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"1-64","cspan":1,"rspan":1,"markup":[1,4]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/docs/source/tables/CAN/CAN_ID_normal_fixed_physical.tgn b/docs/source/tables/CAN/CAN_ID_normal_fixed_physical.tgn new file mode 100644 index 00000000..6d7352e8 --- /dev/null +++ b/docs/source/tables/CAN/CAN_ID_normal_fixed_physical.tgn @@ -0,0 +1 @@ +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"","cspan":1,"rspan":1,"markup":[]},{"value":"Priority","cspan":1,"rspan":1,"markup":[1,8]},{"value":"Reserved Bit","cspan":1,"rspan":1,"markup":[1,12]},{"value":"Data Page","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Protocol data\nunit format","cspan":1,"rspan":1,"markup":[1,25]},{"value":"Target\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Source\nAddress","cspan":1,"rspan":1,"markup":[1,14]},{"value":"Data","cspan":1,"rspan":1,"markup":[1,4]}],[{"value":"Bits number","cspan":1,"rspan":1,"markup":[1,11]},{"value":"3","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"1","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"8","cspan":1,"rspan":1,"markup":[1,1]},{"value":"16-512","cspan":1,"rspan":1,"markup":[1,6]}],[{"value":"Content","cspan":1,"rspan":1,"markup":[1,7]},{"value":"0 - 7","cspan":1,"rspan":1,"markup":[1,5]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"0","cspan":1,"rspan":1,"markup":[1,1]},{"value":"218","cspan":1,"rspan":1,"markup":[1,3]},{"value":"N_TA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_SA","cspan":1,"rspan":1,"markup":[1,4]},{"value":"N_PCI, N_Data","cspan":1,"rspan":1,"markup":[1,13]}],[{"value":"CAN field","cspan":1,"rspan":1,"markup":[1,9]},{"value":"CAN Identifier","cspan":6,"rspan":1,"markup":[1,14]},{"value":"","cspan":-1,"rspan":1,"markup":[]},{"value":"","cspan":-2,"rspan":1,"markup":[]},{"value":"","cspan":-3,"rspan":1,"markup":[]},{"value":"","cspan":-4,"rspan":1,"markup":[]},{"value":"","cspan":-5,"rspan":1,"markup":[]},{"value":"CAN Data","cspan":1,"rspan":1,"markup":[1,8]}],[{"value":"CAN ID bits","cspan":1,"rspan":1,"markup":[1,11]},{"value":"28-26","cspan":1,"rspan":1,"markup":[1,5]},{"value":"25","cspan":1,"rspan":1,"markup":[1,2]},{"value":"24","cspan":1,"rspan":1,"markup":[1,2]},{"value":"23-16","cspan":1,"rspan":1,"markup":[1,5]},{"value":"15-8","cspan":1,"rspan":1,"markup":[1,4]},{"value":"7-0","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]}],[{"value":"CAN data bytes","cspan":1,"rspan":1,"markup":[1,14]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"---","cspan":1,"rspan":1,"markup":[1,3]},{"value":"1-64","cspan":1,"rspan":1,"markup":[1,4]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/docs/source/tables/OSI_model_functionalities.tgn b/docs/source/tables/OSI_model_functionalities.tgn index 00322cb0..fd917233 100644 --- a/docs/source/tables/OSI_model_functionalities.tgn +++ b/docs/source/tables/OSI_model_functionalities.tgn @@ -1 +1 @@ -{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"OSI Layer","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Functionalities","cspan":1,"rspan":1,"markup":[1,15]},{"value":"Implementation","cspan":1,"rspan":1,"markup":[1,14]}],[{"value":"Layer 7\nApplication","cspan":1,"rspan":1,"markup":[1,19]},{"value":"- diagnostic messages support","cspan":1,"rspan":1,"markup":[1,29]},{"value":"- :mod:`uds.message`","cspan":1,"rspan":1,"markup":[1,20]}],[{"value":"Layer 6\nPresentation","cspan":1,"rspan":1,"markup":[1,20]},{"value":"- diagnostic messages data interpretation\n\n- messaging database import from a file\n\n- messaging database export to a file","cspan":1,"rspan":1,"markup":[1,121]},{"value":"*To be provided with Database feature.*","cspan":1,"rspan":1,"markup":[1,39]}],[{"value":"Layer 5\nSession","cspan":1,"rspan":1,"markup":[1,15]},{"value":"- Client simulation\n\n- Server simulation","cspan":1,"rspan":1,"markup":[1,40]},{"value":"*To be provided with Client feature.*\n\n*To be provided with Server feature.*","cspan":1,"rspan":1,"markup":[1,76]}],[{"value":"Layer 4\nTransport","cspan":1,"rspan":1,"markup":[1,17]},{"value":"- UDS packet support\n\n- bus specific segmentation\n\n- bus specific packets transmission","cspan":1,"rspan":2,"markup":[1,86]},{"value":"- :mod:`uds.packet`\n\n- :mod:`uds.segmentation`\n\n- :mod:`uds.transport_interface`\n\n- :mod:`uds.can`\n\n*To be extended with support for:*\n\n- *Ethernet*\n\n- *LIN*\n\n- *K-Line*\n\n- *FlexRay*","cspan":1,"rspan":2,"markup":[1,182]}],[{"value":"Layer 3\nNetwork","cspan":1,"rspan":1,"markup":[1,15]},{"value":"","cspan":1,"rspan":-1,"markup":[]},{"value":"","cspan":1,"rspan":-1,"markup":[]}],[{"value":"Layer 2\nData","cspan":1,"rspan":1,"markup":[1,12]},{"value":"- frames transmission\n\n- frames receiving","cspan":1,"rspan":2,"markup":[1,41]},{"value":"External python packages for bus handling:\n\n-  CAN:\n\n  - `python-can `_\n\n*More packages handling other buses to be decided.*","cspan":1,"rspan":2,"markup":[1,159]}],[{"value":"Layer 1\nPhysical","cspan":1,"rspan":1,"markup":[1,16]},{"value":"","cspan":1,"rspan":-1,"markup":[]},{"value":"","cspan":1,"rspan":-1,"markup":[]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"OSI Layer","cspan":1,"rspan":1,"markup":[1,9]},{"value":"Functionalities","cspan":1,"rspan":1,"markup":[1,15]},{"value":"Implementation","cspan":1,"rspan":1,"markup":[1,14]}],[{"value":"Layer 7\nApplication","cspan":1,"rspan":1,"markup":[1,19]},{"value":"- diagnostic messages support","cspan":1,"rspan":1,"markup":[1,29]},{"value":"- :mod:`uds.message`","cspan":1,"rspan":1,"markup":[1,20]}],[{"value":"Layer 6\nPresentation","cspan":1,"rspan":1,"markup":[1,20]},{"value":"- diagnostic messages data interpretation\n\n- messaging database import from a file\n\n- messaging database export to a file","cspan":1,"rspan":1,"markup":[1,121]},{"value":"*To be provided with Database feature.*","cspan":1,"rspan":1,"markup":[1,39]}],[{"value":"Layer 5\nSession","cspan":1,"rspan":1,"markup":[1,15]},{"value":"- Client simulation\n\n- Server simulation\n\n- sniffing UDS communication","cspan":1,"rspan":1,"markup":[1,70]},{"value":"*To be provided with Client feature.*\n\n*To be provided with Server feature.*\n\n*To be provided with Sniffer feature.*","cspan":1,"rspan":1,"markup":[1,116]}],[{"value":"Layer 4\nTransport","cspan":1,"rspan":1,"markup":[1,17]},{"value":"- UDS packet support\n\n- bus specific segmentation\n\n- bus specific packets transmission","cspan":1,"rspan":2,"markup":[1,86]},{"value":"- :mod:`uds.packet`\n\n- :mod:`uds.segmentation`\n\n- :mod:`uds.transport_interface`\n\n- :mod:`uds.can`\n\n*To be extended with support for:*\n\n- *Ethernet*\n\n- *LIN*\n\n- *K-Line*\n\n- *FlexRay*","cspan":1,"rspan":2,"markup":[1,182]}],[{"value":"Layer 3\nNetwork","cspan":1,"rspan":1,"markup":[1,15]},{"value":"","cspan":1,"rspan":-1,"markup":[]},{"value":"","cspan":1,"rspan":-1,"markup":[]}],[{"value":"Layer 2\nData","cspan":1,"rspan":1,"markup":[1,12]},{"value":"- frames transmission\n\n- frames receiving","cspan":1,"rspan":2,"markup":[1,41]},{"value":"External python packages for bus handling:\n\n-  CAN:\n\n  - python-can\n\n*More packages handling other buses to be decided.*","cspan":1,"rspan":2,"markup":[1,120]}],[{"value":"Layer 1\nPhysical","cspan":1,"rspan":1,"markup":[1,16]},{"value":"","cspan":1,"rspan":-1,"markup":[]},{"value":"","cspan":1,"rspan":-1,"markup":[]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/docs/source/tables/features_implementation_status.tgn b/docs/source/tables/features_implementation_status.tgn index 215da23e..01e6501d 100644 --- a/docs/source/tables/features_implementation_status.tgn +++ b/docs/source/tables/features_implementation_status.tgn @@ -1 +1 @@ -{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"Feature","cspan":1,"rspan":1,"markup":[1,7]},{"value":"Implementation Status","cspan":1,"rspan":1,"markup":[1,21]}],[{"value":"UDS Messages and Packets","cspan":1,"rspan":1,"markup":[1,24]},{"value":"Available since version `0.0.2\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Packets Reception and Transmission","cspan":1,"rspan":1,"markup":[1,38]},{"value":"Available since version `0.3.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Messages Reception and Transmission","cspan":1,"rspan":1,"markup":[1,39]},{"value":"Available since version `1.0.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"Messages Segmentation","cspan":1,"rspan":1,"markup":[1,21]},{"value":"Available since version `0.2.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Packets Desegmentation","cspan":1,"rspan":1,"markup":[1,26]},{"value":"Available since version `0.2.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"Support for Services with multiple responses","cspan":1,"rspan":1,"markup":[1,44]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"Client Simulation","cspan":1,"rspan":1,"markup":[1,17]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"Server Simulation","cspan":1,"rspan":1,"markup":[1,17]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"Support for Messages Databases","cspan":1,"rspan":1,"markup":[1,30]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file +{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"center","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5},"border_color":""}}]],"model":{"rows":[[{"value":"Feature","cspan":1,"rspan":1,"markup":[1,7]},{"value":"Implementation Status","cspan":1,"rspan":1,"markup":[1,21]}],[{"value":"UDS Messages and Packets","cspan":1,"rspan":1,"markup":[1,24]},{"value":"Available since version `0.0.2\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Packets Reception and Transmission","cspan":1,"rspan":1,"markup":[1,38]},{"value":"Available since version `0.3.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Messages Reception and Transmission","cspan":1,"rspan":1,"markup":[1,39]},{"value":"Available since version `1.0.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"Messages Segmentation","cspan":1,"rspan":1,"markup":[1,21]},{"value":"Available since version `0.2.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"UDS Packets Desegmentation","cspan":1,"rspan":1,"markup":[1,26]},{"value":"Available since version `0.2.0\n`_","cspan":1,"rspan":1,"markup":[1,73]}],[{"value":"Client Simulation","cspan":1,"rspan":1,"markup":[1,17]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"Server Simulation","cspan":1,"rspan":1,"markup":[1,17]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"UDS Sniffer","cspan":1,"rspan":1,"markup":[1,11]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}],[{"value":"Support for Messages Databases","cspan":1,"rspan":1,"markup":[1,30]},{"value":"Planned","cspan":1,"rspan":1,"markup":[1,7]}]]},"theme":null,"fixed_layout":false,"markup":{"instances":[{},{"style":{"fontWeight":"","fontStyle":"","textDecoration":"","color":"","backgroundColor":""}},null]},"options":{}} \ No newline at end of file diff --git a/examples/can/python-can/kvaser/receive_message.py b/examples/can/python-can/kvaser/receive_message.py index 43230d42..4d4b1043 100644 --- a/examples/can/python-can/kvaser/receive_message.py +++ b/examples/can/python-can/kvaser/receive_message.py @@ -13,7 +13,7 @@ def main(): # configure Addressing Information of a CAN Node (example values) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/receive_message_asyncio.py b/examples/can/python-can/kvaser/receive_message_asyncio.py index 24843ba9..8b649eb8 100644 --- a/examples/can/python-can/kvaser/receive_message_asyncio.py +++ b/examples/can/python-can/kvaser/receive_message_asyncio.py @@ -13,7 +13,7 @@ async def main(): # configure Addressing Information of a CAN Node (example values) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/receive_packet.py b/examples/can/python-can/kvaser/receive_packet.py index 3b5f017a..d1db6bdd 100644 --- a/examples/can/python-can/kvaser/receive_packet.py +++ b/examples/can/python-can/kvaser/receive_packet.py @@ -13,7 +13,7 @@ def main(): # configure Addressing Information of a CAN Node (example values) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/receive_packet_asyncio.py b/examples/can/python-can/kvaser/receive_packet_asyncio.py index bd397eb4..cad76c76 100644 --- a/examples/can/python-can/kvaser/receive_packet_asyncio.py +++ b/examples/can/python-can/kvaser/receive_packet_asyncio.py @@ -13,7 +13,7 @@ async def main(): # configure Addressing Information of a CAN Node (example values) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_and_receive_message.py b/examples/can/python-can/kvaser/send_and_receive_message.py index e69b0f6c..7d1c7310 100644 --- a/examples/can/python-can/kvaser/send_and_receive_message.py +++ b/examples/can/python-can/kvaser/send_and_receive_message.py @@ -16,7 +16,7 @@ def main(): # configure Addressing Information of a CAN Nodes (example values) ai_receive = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_and_receive_message_asyncio.py b/examples/can/python-can/kvaser/send_and_receive_message_asyncio.py index 44d27039..6a67d66f 100644 --- a/examples/can/python-can/kvaser/send_and_receive_message_asyncio.py +++ b/examples/can/python-can/kvaser/send_and_receive_message_asyncio.py @@ -15,7 +15,7 @@ async def main(): # configure Addressing Information of a CAN Nodes (example values) ai_receive = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_and_receive_packet.py b/examples/can/python-can/kvaser/send_and_receive_packet.py index 11f543ae..0aa2b3c2 100644 --- a/examples/can/python-can/kvaser/send_and_receive_packet.py +++ b/examples/can/python-can/kvaser/send_and_receive_packet.py @@ -14,7 +14,7 @@ def main(): # configure Addressing Information of a CAN Nodes (example values) ai_receive = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_and_receive_packet_asyncio.py b/examples/can/python-can/kvaser/send_and_receive_packet_asyncio.py index 3623f993..3a564106 100644 --- a/examples/can/python-can/kvaser/send_and_receive_packet_asyncio.py +++ b/examples/can/python-can/kvaser/send_and_receive_packet_asyncio.py @@ -15,13 +15,13 @@ async def main(): # configure Addressing Information of a CAN Node (example values) ai_receive = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, rx_functional={"can_id": 0x6FE}) ai_send = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x612}, rx_physical={"can_id": 0x611}, tx_functional={"can_id": 0x6FE}, diff --git a/examples/can/python-can/kvaser/send_message.py b/examples/can/python-can/kvaser/send_message.py index 74c6710f..e968367f 100644 --- a/examples/can/python-can/kvaser/send_message.py +++ b/examples/can/python-can/kvaser/send_message.py @@ -16,7 +16,7 @@ def main(): # configure Addressing Information of a CAN Node (example values) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_message_asyncio.py b/examples/can/python-can/kvaser/send_message_asyncio.py index 4fb41968..cde8283e 100644 --- a/examples/can/python-can/kvaser/send_message_asyncio.py +++ b/examples/can/python-can/kvaser/send_message_asyncio.py @@ -17,7 +17,7 @@ async def main(): # configure Addressing Information of a CAN Node (example values set) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_packet.py b/examples/can/python-can/kvaser/send_packet.py index 698117c8..b07b707d 100644 --- a/examples/can/python-can/kvaser/send_packet.py +++ b/examples/can/python-can/kvaser/send_packet.py @@ -16,7 +16,7 @@ def main(): # configure Addressing Information of a CAN Node (example values set) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/examples/can/python-can/kvaser/send_packet_asyncio.py b/examples/can/python-can/kvaser/send_packet_asyncio.py index f05060a2..710d1c00 100644 --- a/examples/can/python-can/kvaser/send_packet_asyncio.py +++ b/examples/can/python-can/kvaser/send_packet_asyncio.py @@ -17,7 +17,7 @@ async def main(): # configure Addressing Information of a CAN Node (example values set) addressing_information = CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/tests/software_tests/can/test_abstract_addressing_information.py b/tests/software_tests/can/test_abstract_addressing_information.py index a2a70887..0c792c3b 100644 --- a/tests/software_tests/can/test_abstract_addressing_information.py +++ b/tests/software_tests/can/test_abstract_addressing_information.py @@ -39,6 +39,11 @@ def test_init(self, rx_physical, tx_physical, rx_functional, tx_functional): assert self.mock_addressing_information.tx_packets_physical_ai == tx_physical assert self.mock_addressing_information.rx_packets_functional_ai == rx_functional assert self.mock_addressing_information.tx_packets_functional_ai == tx_functional + self.mock_addressing_information._validate_node_ai.assert_called_once_with( + rx_packets_physical_ai=self.mock_addressing_information.rx_packets_physical_ai, + tx_packets_physical_ai=self.mock_addressing_information.tx_packets_physical_ai, + rx_packets_functional_ai=self.mock_addressing_information.rx_packets_functional_ai, + tx_packets_functional_ai=self.mock_addressing_information.tx_packets_functional_ai) # rx_packets_physical_ai diff --git a/tests/software_tests/can/test_addressing_information.py b/tests/software_tests/can/test_addressing_information.py index 36b10101..ecedf660 100644 --- a/tests/software_tests/can/test_addressing_information.py +++ b/tests/software_tests/can/test_addressing_information.py @@ -21,16 +21,6 @@ def setup_method(self): self.mock_can_id_handler_class = self._patcher_can_id_handler_class.start() self._patcher_validate_addressing_format = patch(f"{SCRIPT_LOCATION}.CanAddressingFormat.validate_member") self.mock_validate_addressing_format = self._patcher_validate_addressing_format.start() - self._patcher_normal_11bit_ai_class = patch(f"{SCRIPT_LOCATION}.Normal11BitCanAddressingInformation") - self.mock_normal_11bit_ai_class = self._patcher_normal_11bit_ai_class.start() - self._patcher_normal_fixed_ai_class = patch(f"{SCRIPT_LOCATION}.NormalFixedCanAddressingInformation") - self.mock_normal_fixed_ai_class = self._patcher_normal_fixed_ai_class.start() - self._patcher_extended_ai_class = patch(f"{SCRIPT_LOCATION}.ExtendedCanAddressingInformation") - self.mock_extended_ai_class = self._patcher_extended_ai_class.start() - self._patcher_mixed_11bit_ai_class = patch(f"{SCRIPT_LOCATION}.Mixed11BitCanAddressingInformation") - self.mock_mixed_11bit_ai_class = self._patcher_mixed_11bit_ai_class.start() - self._patcher_mixed_29bit_ai_class = patch(f"{SCRIPT_LOCATION}.Mixed29BitCanAddressingInformation") - self.mock_mixed_29bit_ai_class = self._patcher_mixed_29bit_ai_class.start() self._patcher_validate_raw_bytes = patch(f"{SCRIPT_LOCATION}.validate_raw_bytes") self.mock_validate_raw_bytes = self._patcher_validate_raw_bytes.start() self._patcher_validate_raw_byte = patch(f"{SCRIPT_LOCATION}.validate_raw_byte") @@ -39,11 +29,6 @@ def setup_method(self): def teardown_method(self): self._patcher_can_id_handler_class.stop() self._patcher_validate_addressing_format.stop() - self._patcher_normal_11bit_ai_class.stop() - self._patcher_normal_fixed_ai_class.stop() - self._patcher_extended_ai_class.stop() - self._patcher_mixed_11bit_ai_class.stop() - self._patcher_mixed_29bit_ai_class.stop() self._patcher_validate_raw_bytes.stop() self._patcher_validate_raw_byte.stop() @@ -156,7 +141,7 @@ def test_decode_ai_data_bytes__not_implemented(self, mock_validate_ai_data_bytes mock_validate_ai_data_bytes.assert_called_once_with(addressing_format=addressing_format, ai_data_bytes=ai_data_bytes) - @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.NORMAL_FIXED_ADDRESSING]) @pytest.mark.parametrize("ai_data_bytes", [[], (0xCF,)]) @patch(f"{SCRIPT_LOCATION}.CanAddressingInformation.validate_ai_data_bytes") @@ -190,7 +175,7 @@ def test_decode_ai_data_bytes__mixed(self, mock_validate_ai_data_bytes, addressi # encode_ai_data_bytes - @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.NORMAL_FIXED_ADDRESSING]) @pytest.mark.parametrize("target_address, address_extension", [ (None, None), @@ -257,40 +242,71 @@ class TestCanAddressingInformationIntegration: """Integration tests for `CanAddressingInformation` class.""" @pytest.mark.parametrize("input_params, expected_attributes", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + # Normal + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "rx_physical": {"can_id": 0x601}, "tx_physical": {"can_id": 0x602}, "rx_functional": {"can_id": 0x6FE}, "tx_functional": {"can_id": 0x6FF}}, - {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x601, "target_address": None, "source_address": None, "address_extension": None}, - "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x602, "target_address": None, "source_address": None, "address_extension": None}, - "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, "can_id": 0x6FE, "target_address": None, "source_address": None, "address_extension": None}, - "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, "can_id": 0x6FF, "target_address": None, "source_address": None, "address_extension": None}}), + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, + "rx_physical": {"can_id": 0x1}, + "tx_physical": {"can_id": 0x2}, + "rx_functional": {"can_id": 0x1FFFFFFE}, + "tx_functional": {"can_id": 0x1FFFFFFF}}, + {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0x1, + "target_address": None, + "source_address": None, + "address_extension": None}, + "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0x2, + "target_address": None, + "source_address": None, + "address_extension": None}, + "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x1FFFFFFE, + "target_address": None, + "source_address": None, + "address_extension": None}, + "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x1FFFFFFF, + "target_address": None, + "source_address": None, + "address_extension": None}}), + # Normal Fixed ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, "rx_physical": {"can_id": 0x18DA0E2B}, "tx_physical": {"target_address": 0x2B, "source_address": 0x0E}, "rx_functional": {"can_id": 0x18DBFEDC, "target_address": 0xFE}, - "tx_functional": {"can_id": 0x18DBFD92, "target_address": 0xFD, "source_address": 0x92}}, + "tx_functional": {"can_id": 0x18DBDCFE, "target_address": 0xDC, "source_address": 0xFE}}, {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x18DA0E2B, @@ -311,10 +327,40 @@ class TestCanAddressingInformationIntegration: "address_extension": None}, "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, - "can_id": 0x18DBFD92, - "target_address": 0xFD, - "source_address": 0x92, + "can_id": 0x18DBDCFE, + "target_address": 0xDC, + "source_address": 0xFE, + "address_extension": None}}), + ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + "rx_physical": {"can_id": 0xDA00FF}, + "tx_physical": {"can_id": 0xDAFF00}, + "rx_functional": {"can_id": 0x1CDBFF00}, + "tx_functional": {"can_id": 0x1CDB00FF, "target_address": 0x00, "source_address": 0xFF}}, + {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0xDA00FF, + "target_address": 0x00, + "source_address": 0xFF, + "address_extension": None}, + "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0xDAFF00, + "target_address": 0xFF, + "source_address": 0x00, + "address_extension": None}, + "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x1CDBFF00, + "target_address": 0xFF, + "source_address": 0x00, + "address_extension": None}, + "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x1CDB00FF, + "target_address": 0x00, + "source_address": 0xFF, "address_extension": None}}), + # Extended ({"addressing_format": CanAddressingFormat.EXTENDED_ADDRESSING, "rx_physical": {"can_id": 0x621, "target_address": 0x1F}, "tx_physical": {"can_id": 0x621, "target_address": 0x91}, @@ -344,11 +390,12 @@ class TestCanAddressingInformationIntegration: "target_address": 0x83, "source_address": None, "address_extension": None}}), + # Mixed 11-bit ({"addressing_format": CanAddressingFormat.MIXED_11BIT_ADDRESSING, "rx_physical": {"can_id": 0x641, "address_extension": 0x00}, - "tx_physical": {"can_id": 0x642, "address_extension": 0xFF}, + "tx_physical": {"can_id": 0x642, "address_extension": 0x00}, "rx_functional": {"can_id": 0x6DE, "address_extension": 0xFE}, - "tx_functional": {"can_id": 0x6DF, "address_extension": 0xFF}}, + "tx_functional": {"can_id": 0x6DF, "address_extension": 0xFE}}, {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_11BIT_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x641, @@ -358,7 +405,7 @@ class TestCanAddressingInformationIntegration: "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_11BIT_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x642, - "address_extension": 0xFF, + "address_extension": 0x00, "target_address": None, "source_address": None}, "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_11BIT_ADDRESSING, @@ -370,14 +417,15 @@ class TestCanAddressingInformationIntegration: "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_11BIT_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, "can_id": 0x6DF, - "address_extension": 0xFF, + "address_extension": 0xFE, "target_address": None, "source_address": None}}), + # Mixed 29-bit ({"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, "rx_physical": {"can_id": 0x18CE1234, "target_address": 0x12, "source_address": 0x34, "address_extension": 0x00}, - "tx_physical": {"can_id": 0x18CEFF0F, "target_address": 0xFF, "address_extension": 0x5E}, - "rx_functional": {"can_id": 0x18CDFF00, "address_extension": 0xFE}, - "tx_functional": {"target_address": 0x09, "source_address": 0x23, "address_extension": 0xFF}}, + "tx_physical": {"can_id": 0x18CE3412, "source_address": 0x12, "address_extension": 0x00}, + "rx_functional": {"can_id": 0x18CDBD87, "target_address": 0xBD, "address_extension": 0xFF}, + "tx_functional": {"target_address": 0x87, "source_address": 0xBD, "address_extension": 0xFF}}, {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, "can_id": 0x18CE1234, @@ -386,22 +434,51 @@ class TestCanAddressingInformationIntegration: "address_extension": 0x00}, "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, - "can_id": 0x18CEFF0F, + "can_id": 0x18CE3412, + "target_address": 0x34, + "source_address": 0x12, + "address_extension": 0x00}, + "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x18CDBD87, + "target_address": 0xBD, + "source_address": 0x87, + "address_extension": 0xFF}, + "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, + "addressing_type": AddressingType.FUNCTIONAL, + "can_id": 0x18CD87BD, + "target_address": 0x87, + "source_address": 0xBD, + "address_extension": 0xFF}}), + ({"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, + "rx_physical": {"can_id": 0xCE00FF, "address_extension": 0x32}, + "tx_physical": {"can_id": 0xCEFF00, "address_extension": 0x32}, + "rx_functional": {"can_id": 0x1CCDFF00, "address_extension": 0xA1}, + "tx_functional": {"can_id": 0x1CCD00FF, "address_extension": 0xA1}}, + {"rx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0xCE00FF, + "target_address": 0x00, + "source_address": 0xFF, + "address_extension": 0x32}, + "tx_packets_physical_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, + "addressing_type": AddressingType.PHYSICAL, + "can_id": 0xCEFF00, "target_address": 0xFF, - "source_address": 0x0F, - "address_extension": 0x5E}, + "source_address": 0x00, + "address_extension": 0x32}, "rx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, - "can_id": 0x18CDFF00, + "can_id": 0x1CCDFF00, "target_address": 0xFF, "source_address": 0x00, - "address_extension": 0xFE}, + "address_extension": 0xA1}, "tx_packets_functional_ai": {"addressing_format": CanAddressingFormat.MIXED_29BIT_ADDRESSING, "addressing_type": AddressingType.FUNCTIONAL, - "can_id": 0x18CD0923, - "target_address": 0x09, - "source_address": 0x23, - "address_extension": 0xFF}}), + "can_id": 0x1CCD00FF, + "target_address": 0x00, + "source_address": 0xFF, + "address_extension": 0xA1}}), ]) def test_new(self, input_params, expected_attributes): ai = CanAddressingInformation(**input_params) diff --git a/tests/software_tests/can/test_consecutive_frame.py b/tests/software_tests/can/test_consecutive_frame.py index 3ac8b2c7..3fb9032b 100644 --- a/tests/software_tests/can/test_consecutive_frame.py +++ b/tests/software_tests/can/test_consecutive_frame.py @@ -495,7 +495,7 @@ class TestCanSingleFrameHandlerIntegration: # create_valid_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x9A], "sequence_number": 0}, [0x20, 0x9A]), ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -524,7 +524,7 @@ def test_create_valid_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanConsecutiveFrameHandler.create_valid_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x9A], "dlc": 1, "sequence_number": 0}, @@ -555,7 +555,7 @@ def test_create_valid_frame_data__invalid(self, kwargs): # create_any_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [], "dlc": 1, "sequence_number": 0}, [0x20]), @@ -579,7 +579,7 @@ def test_create_any_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanConsecutiveFrameHandler.create_any_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x9A], "dlc": 1, "sequence_number": 0}, @@ -605,7 +605,7 @@ def test_create_any_frame_data__invalid(self, kwargs): # validate_frame_data @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x20, 0x12, 0x34, 0x45, 0x67, 0x89, 0x9A, 0xBC)), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x20, 0x12, 0x34, 0x45, 0x67, 0x89, 0x9A, 0xBC)), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, (0x2F, 0x2F)), (CanAddressingFormat.EXTENDED_ADDRESSING, (0xF0, 0x26, 0x00)), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, [0x30, 0x21] + (46 * [0xFF])), @@ -616,7 +616,7 @@ def test_validate_frame_data__valid(self, addressing_format, raw_frame_data): raw_frame_data=raw_frame_data) is None @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, [0x20]), + (CanAddressingFormat.NORMAL_ADDRESSING, [0x20]), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, tuple([0x2F] + ([0xFF] * 64))), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x2F, 0x2F]), (CanAddressingFormat.MIXED_29BIT_ADDRESSING, (0x8B, 0x2E)), diff --git a/tests/software_tests/can/test_extended_addressing_information.py b/tests/software_tests/can/test_extended_addressing_information.py index 9e6b610b..d724bf7b 100644 --- a/tests/software_tests/can/test_extended_addressing_information.py +++ b/tests/software_tests/can/test_extended_addressing_information.py @@ -85,3 +85,57 @@ def test_validate_packet_ai__valid(self, addressing_type, can_id, target_address self.mock_can_id_handler_class.is_extended_addressed_can_id.assert_called_once_with(can_id) self.mock_validate_addressing_type.assert_called_once_with(addressing_type) self.mock_validate_raw_byte.assert_called_once_with(target_address) + + # _validate_node_ai + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1, "target_address": 2}, + {"can_id": 2, "target_address": 1}, + {"can_id": 3, "target_address": 4}, + {"can_id": 3, "target_address": 4}, + ), + ( + {"can_id": 0x4321, "target_address": 0xFF}, + {"can_id": 0x4321, "target_address": 0xFF}, + {"can_id": 0x4321, "target_address": 0xFE}, + {"can_id": 0x4321, "target_address": 0xFD}, + ), + ]) + def test_validate_node_ai__inconsistent(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + with pytest.raises(InconsistentArgumentsError): + ExtendedCanAddressingInformation._validate_node_ai(rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1, "target_address": 2}, + {"can_id": 2, "target_address": 1}, + {"can_id": 3, "target_address": 4}, + {"can_id": 4, "target_address": 3}, + ), + ( + {"can_id": 0x4321, "target_address": 0xFF}, + {"can_id": 0x4321, "target_address": 0x00}, + {"can_id": 0x4321, "target_address": 0xFE}, + {"can_id": 0x4321, "target_address": 0xFD}, + ), + ( + {"can_id": 0xABC1, "target_address": 0xFF}, + {"can_id": 0xABC2, "target_address": 0xFF}, + {"can_id": 0xABC3, "target_address": 0xFF}, + {"can_id": 0xABC4, "target_address": 0xFF}, + ), + ]) + def test_validate_node_ai__valid(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + assert ExtendedCanAddressingInformation._validate_node_ai( + rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) is None diff --git a/tests/software_tests/can/test_first_frame.py b/tests/software_tests/can/test_first_frame.py index 8e4351f3..e22f7799 100644 --- a/tests/software_tests/can/test_first_frame.py +++ b/tests/software_tests/can/test_first_frame.py @@ -515,7 +515,7 @@ class TestCanFirstFrameHandlerIntegration: # create_valid_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "dlc": 8, "ff_dl": 0xFED, "payload": [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]}, [0x1F, 0xED, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]), @@ -545,7 +545,7 @@ def test_create_valid_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanFirstFrameHandler.create_valid_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "dlc": 7, "ff_dl": 0xFED, "payload": [0x12, 0x34, 0x56, 0x78, 0x9A]}, @@ -578,7 +578,7 @@ def test_create_valid_frame_data__invalid(self, kwargs): # create_any_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "dlc": 7, "ff_dl": 0xFED, "long_ff_dl_format": False, @@ -613,7 +613,7 @@ def test_create_any_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanFirstFrameHandler.create_any_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "dlc": 7, "ff_dl": 0x1000, "long_ff_dl_format": False, @@ -651,7 +651,7 @@ def test_create_any_frame_data__invalid(self, kwargs): # decode_ff_dl @pytest.mark.parametrize("addressing_format, raw_frame_data, expected_ff_dl", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x10, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE), 0x12), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x10, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE), 0x12), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x1F, 0xED] + list(range(62)), 0xFED), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x10, 0x10, 0x00, 0xF0, 0xD1, 0xE2, 0xC3] + list(range(50, 92)), 0xF0D1E2C3), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, [0xC4, 0x10, 0x00, 0xF0, 0xD1, 0xE2, 0xC3, 0xD4], 0xF0D1E2C3), @@ -664,7 +664,7 @@ def test_decode_ff_dl(self, addressing_format, raw_frame_data, expected_ff_dl): # validate_frame_data @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x10, 0x08, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x10, 0x08, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x10, 0x00, 0x00, 0x00, 0x10, 0x00] + list(range(58))), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x10, 0x1F, 0xFF] + list(range(100, 121))), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0x0F, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)), @@ -675,7 +675,7 @@ def test_validate_frame_data__valid(self, addressing_format, raw_frame_data): raw_frame_data=raw_frame_data) is None @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x10, 0x07, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x10, 0x07, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x10, 0x00, 0x00, 0x00, 0x0F, 0xFF] + list(range(58))), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x10, 0x10, 0x15] + list(range(100, 121))), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0x0F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)), diff --git a/tests/software_tests/can/test_flow_control.py b/tests/software_tests/can/test_flow_control.py index 7319bdb1..86f9580e 100644 --- a/tests/software_tests/can/test_flow_control.py +++ b/tests/software_tests/can/test_flow_control.py @@ -655,7 +655,7 @@ class TestCanFlowControlHandlerIntegration: # create_valid_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "flow_status": CanFlowStatus.Overflow}, [0x32, 0xCC, 0xCC]), ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, "flow_status": CanFlowStatus.ContinueToSend, @@ -688,7 +688,7 @@ def test_create_valid_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanFlowControlHandler.create_valid_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "flow_status": CanFlowStatus.Overflow, "dlc": 4}, {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -717,7 +717,7 @@ def test_create_valid_frame_data__invalid(self, kwargs): # create_any_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "flow_status": CanFlowStatus.ContinueToSend, "dlc": 1}, [0x30]), ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -747,7 +747,7 @@ def test_create_any_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanFlowControlHandler.create_any_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "flow_status": 0x10, "dlc": 3}, {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -777,7 +777,7 @@ def test_create_any_frame_data__invalid(self, kwargs): # validate_frame_data @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, [0x30, 0x12, 0x34]), + (CanAddressingFormat.NORMAL_ADDRESSING, [0x30, 0x12, 0x34]), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, (0x31, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA)), (CanAddressingFormat.EXTENDED_ADDRESSING, (0xA1, 0x32, 0xCC, 0xCC)), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0xBC, 0x30, 0xCC, 0xCC)), @@ -788,7 +788,7 @@ def test_validate_frame_data__valid(self, addressing_format, raw_frame_data): raw_frame_data=raw_frame_data) is None @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, [0x30, 0x12]), + (CanAddressingFormat.NORMAL_ADDRESSING, [0x30, 0x12]), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, (0x31, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA)), (CanAddressingFormat.EXTENDED_ADDRESSING, (0xA1, 0x32, 0xCC)), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0xBC, 0x34, 0xCC, 0xCC)), diff --git a/tests/software_tests/can/test_frame_fields.py b/tests/software_tests/can/test_frame_fields.py index a5aa7939..23b76741 100644 --- a/tests/software_tests/can/test_frame_fields.py +++ b/tests/software_tests/can/test_frame_fields.py @@ -1,5 +1,5 @@ import pytest -from mock import call, patch +from mock import Mock, call, patch from uds.can.frame_fields import AddressingType, CanAddressingFormat, CanDlcHandler, CanIdHandler @@ -47,7 +47,7 @@ def test_decode_can_id__mixed_29bit(self, mock_decode_mixed_addressed_29bit_can_ self.mock_validate_addressing_format.assert_called_once_with(CanAddressingFormat.MIXED_29BIT_ADDRESSING) mock_decode_mixed_addressed_29bit_can_id.assert_called_once_with(can_id) - @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + @pytest.mark.parametrize("addressing_format", [CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.EXTENDED_ADDRESSING, CanAddressingFormat.MIXED_11BIT_ADDRESSING]) @pytest.mark.parametrize("can_id", [0, 0x20000]) @@ -88,13 +88,14 @@ def test_decode_normal_fixed_addressed_can_id__validation_error(self, mock_valid @pytest.mark.parametrize("addressing_type, target_address, source_address, can_id", [ (AddressingType.PHYSICAL, 0x12, 0x34, 0x18DA1234), (AddressingType.FUNCTIONAL, 0xFE, 0xDC, 0x18DBFEDC), - (AddressingType.PHYSICAL, 0x00, 0xFF, 0x18DA00FF), - (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x18DBFF00), + (AddressingType.PHYSICAL, 0x00, 0xFF, 0xDA00FF), + (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x1CDBFF00), ]) def test_decode_normal_fixed_addressed_can_id__valid(self, can_id, addressing_type, target_address, source_address): decoded_values = CanIdHandler.decode_normal_fixed_addressed_can_id(can_id=can_id) assert isinstance(decoded_values, dict) - assert set(decoded_values.keys()) == {CanIdHandler.ADDRESSING_TYPE_NAME, CanIdHandler.TARGET_ADDRESS_NAME, + assert set(decoded_values.keys()) == {CanIdHandler.ADDRESSING_TYPE_NAME, + CanIdHandler.TARGET_ADDRESS_NAME, CanIdHandler.SOURCE_ADDRESS_NAME} assert decoded_values[CanIdHandler.ADDRESSING_TYPE_NAME] == addressing_type assert decoded_values[CanIdHandler.TARGET_ADDRESS_NAME] == target_address @@ -128,13 +129,14 @@ def test_decode_mixed_addressed_29bit_can_id__validation_error(self, mock_valida @pytest.mark.parametrize("addressing_type, target_address, source_address, can_id", [ (AddressingType.PHYSICAL, 0x12, 0x34, 0x18CE1234), (AddressingType.FUNCTIONAL, 0xFE, 0xDC, 0x18CDFEDC), - (AddressingType.PHYSICAL, 0x00, 0xFF, 0x18CE00FF), - (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x18CDFF00), + (AddressingType.PHYSICAL, 0x00, 0xFF, 0xCE00FF), + (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x1CCDFF00), ]) def test_decode_mixed_addressed_29bit_can_id(self, can_id, addressing_type, target_address, source_address): decoded_values = CanIdHandler.decode_mixed_addressed_29bit_can_id(can_id=can_id) assert isinstance(decoded_values, dict) - assert set(decoded_values.keys()) == {CanIdHandler.ADDRESSING_TYPE_NAME, CanIdHandler.TARGET_ADDRESS_NAME, + assert set(decoded_values.keys()) == {CanIdHandler.ADDRESSING_TYPE_NAME, + CanIdHandler.TARGET_ADDRESS_NAME, CanIdHandler.SOURCE_ADDRESS_NAME} assert decoded_values[CanIdHandler.ADDRESSING_TYPE_NAME] == addressing_type assert decoded_values[CanIdHandler.TARGET_ADDRESS_NAME] == target_address @@ -158,13 +160,36 @@ def test_generate_normal_fixed_addressed_can_id__not_implemented(self, addressin (AddressingType.PHYSICAL, 0x00, 0xFF, 0x18DA00FF), (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x18DBFF00), ]) - def test_generate_normal_fixed_addressed_can_id__valid(self, addressing_type, target_address, source_address, - expected_can_id): + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.validate_priority") + def test_generate_normal_fixed_addressed_can_id__valid_without_priority(self, mock_validate_priority, + addressing_type, + target_address, source_address, + expected_can_id): assert CanIdHandler.encode_normal_fixed_addressed_can_id(addressing_type=addressing_type, target_address=target_address, source_address=source_address) == expected_can_id self.mock_validate_raw_byte.assert_has_calls([call(target_address), call(source_address)], any_order=True) self.mock_validate_addressing_type.assert_called_once_with(addressing_type) + mock_validate_priority.assert_called_once_with(CanIdHandler.DEFAULT_PRIORITY_VALUE) + + @pytest.mark.parametrize("addressing_type, priority, target_address, source_address, expected_can_id", [ + (AddressingType.PHYSICAL, 0b000, 0x12, 0x34, 0xDA1234), + (AddressingType.FUNCTIONAL, 0b011, 0xFE, 0xDC, 0xCDBFEDC), + (AddressingType.PHYSICAL, 0b101, 0x00, 0xFF, 0x14DA00FF), + (AddressingType.FUNCTIONAL, 0b111, 0xFF, 0x00, 0x1CDBFF00), + ]) + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.validate_priority") + def test_generate_normal_fixed_addressed_can_id__valid_with_priority(self, mock_validate_priority, + addressing_type, priority, + target_address, source_address, + expected_can_id): + assert CanIdHandler.encode_normal_fixed_addressed_can_id(addressing_type=addressing_type, + target_address=target_address, + source_address=source_address, + priority=priority) == expected_can_id + self.mock_validate_raw_byte.assert_has_calls([call(target_address), call(source_address)], any_order=True) + self.mock_validate_addressing_type.assert_called_once_with(addressing_type) + mock_validate_priority.assert_called_once_with(priority) # encode_mixed_addressed_29bit_can_id @@ -184,13 +209,36 @@ def test_generate_mixed_addressed_29bit_can_id__not_implemented(self, addressing (AddressingType.PHYSICAL, 0x00, 0xFF, 0x18CE00FF), (AddressingType.FUNCTIONAL, 0xFF, 0x00, 0x18CDFF00), ]) - def test_generate_mixed_addressed_29bit_can_id__valid(self, addressing_type, target_address, source_address, - expected_can_id): + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.validate_priority") + def test_generate_mixed_addressed_29bit_can_id__valid_without_priority(self, mock_validate_priority, + addressing_type, + target_address, source_address, + expected_can_id): assert CanIdHandler.encode_mixed_addressed_29bit_can_id(addressing_type=addressing_type, target_address=target_address, source_address=source_address) == expected_can_id self.mock_validate_raw_byte.assert_has_calls([call(target_address), call(source_address)], any_order=True) self.mock_validate_addressing_type.assert_called_once_with(addressing_type) + mock_validate_priority.assert_called_once_with(CanIdHandler.DEFAULT_PRIORITY_VALUE) + + @pytest.mark.parametrize("addressing_type, priority, target_address, source_address, expected_can_id", [ + (AddressingType.PHYSICAL, 0b000, 0x12, 0x34, 0xCE1234), + (AddressingType.FUNCTIONAL, 0b011, 0xFE, 0xDC, 0xCCDFEDC), + (AddressingType.PHYSICAL, 0b101, 0x00, 0xFF, 0x14CE00FF), + (AddressingType.FUNCTIONAL, 0b111, 0xFF, 0x00, 0x1CCDFF00), + ]) + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.validate_priority") + def test_generate_mixed_addressed_29bit_can_id__valid_with_priority(self, mock_validate_priority, + addressing_type, priority, + target_address, source_address, + expected_can_id): + assert CanIdHandler.encode_mixed_addressed_29bit_can_id(addressing_type=addressing_type, + target_address=target_address, + source_address=source_address, + priority=priority) == expected_can_id + self.mock_validate_raw_byte.assert_has_calls([call(target_address), call(source_address)], any_order=True) + self.mock_validate_addressing_type.assert_called_once_with(addressing_type) + mock_validate_priority.assert_called_once_with(priority) # is_compatible_can_id @@ -210,15 +258,15 @@ def test_is_compatible_can_id__not_implemented_error(self, can_id, can_addressin ("some CAN ID", "some addressing"), (CanIdHandler.MAX_STANDARD_VALUE, AddressingType.PHYSICAL), ]) - @patch(f"{SCRIPT_LOCATION}.CanIdHandler.is_normal_11bit_addressed_can_id") + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.is_normal_addressed_can_id") @patch(f"{SCRIPT_LOCATION}.CanIdHandler.validate_can_id") - def test_is_compatible_can_id__normal_11bit(self, mock_validate_can_id, mock_is_normal_11bit_addressed_can_id, - can_id, addressing_type): - assert CanIdHandler.is_compatible_can_id(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + def test_is_compatible_can_id__normal(self, mock_validate_can_id, mock_is_normal_addressed_can_id, + can_id, addressing_type): + assert CanIdHandler.is_compatible_can_id(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, addressing_type=addressing_type, - can_id=can_id) == mock_is_normal_11bit_addressed_can_id.return_value - mock_is_normal_11bit_addressed_can_id.assert_called_once_with(can_id=can_id) - self.mock_validate_addressing_format.assert_called_once_with(CanAddressingFormat.NORMAL_11BIT_ADDRESSING) + can_id=can_id) == mock_is_normal_addressed_can_id.return_value + mock_is_normal_addressed_can_id.assert_called_once_with(can_id=can_id) + self.mock_validate_addressing_format.assert_called_once_with(CanAddressingFormat.NORMAL_ADDRESSING) mock_validate_can_id.assert_called_once_with(can_id) @pytest.mark.parametrize("can_id, addressing_type", [ @@ -281,54 +329,88 @@ def test_is_compatible_can_id__mixed_29bit(self, mock_validate_can_id, mock_is_m self.mock_validate_addressing_format.assert_called_once_with(CanAddressingFormat.MIXED_29BIT_ADDRESSING) mock_validate_can_id.assert_called_once_with(can_id) - # is_normal_11bit_addressed_can_id + # is_normal_addressed_can_id - @pytest.mark.parametrize("value", [0, 0x99999]) - @patch(f"{SCRIPT_LOCATION}.CanIdHandler.is_standard_can_id") - def test_is_normal_11bit_addressed_can_id(self, mock_is_standard_can_id, value): - assert CanIdHandler.is_normal_11bit_addressed_can_id(value) == mock_is_standard_can_id.return_value - mock_is_standard_can_id.assert_called_once_with(value) + @patch(f"{SCRIPT_LOCATION}.CanIdHandler.is_can_id") + def test_is_normal_addressed_can_id(self, mock_is_can_id): + value = Mock() + assert CanIdHandler.is_normal_addressed_can_id(value) == mock_is_can_id.return_value + mock_is_can_id.assert_called_once_with(value) # is_normal_fixed_addressed_can_id - @pytest.mark.parametrize("value", [CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET, - CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0x1234, - CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF, - CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET, - CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0xDEBA, - CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF]) + @pytest.mark.parametrize("value", [CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + 0x1234 + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xDEBA + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET)]) def test_is_normal_fixed_addressed_can_id__without_addressing__true(self, value): assert CanIdHandler.is_normal_fixed_addressed_can_id(value) is True self.mock_validate_addressing_type.assert_not_called() - @pytest.mark.parametrize("value", [CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET - 1, - CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0x10000]) + @pytest.mark.parametrize("value", [CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) - 1, + CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) + 0x10000]) def test_is_normal_fixed_addressed_can_id__without_addressing__false(self, value): assert CanIdHandler.is_normal_fixed_addressed_can_id(value) is False self.mock_validate_addressing_type.assert_not_called() @pytest.mark.parametrize("value, addressing_type", [ - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET, AddressingType.PHYSICAL), - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0x1234, AddressingType.PHYSICAL), - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF, AddressingType.PHYSICAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET, AddressingType.FUNCTIONAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0xDEBA, AddressingType.FUNCTIONAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF, AddressingType.FUNCTIONAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + 0x1234 + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xDEBA + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), ]) def test_is_normal_fixed_addressed_can_id__with_addressing__true(self, value, addressing_type): + self.mock_validate_addressing_type.return_value = addressing_type assert CanIdHandler.is_normal_fixed_addressed_can_id(value, addressing_type=addressing_type) is True self.mock_validate_addressing_type.assert_called_once_with(addressing_type) @pytest.mark.parametrize("value, addressing_type", [ - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET - 1, AddressingType.PHYSICAL), - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0x10000, AddressingType.PHYSICAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET - 1, AddressingType.FUNCTIONAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0x10000, AddressingType.FUNCTIONAL), - (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET, AddressingType.FUNCTIONAL), - (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET, AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) - 1, + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0x10000 + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), (0, AddressingType.PHYSICAL), ]) def test_is_normal_fixed_addressed_can_id__with_addressing__false(self, value, addressing_type): + self.mock_validate_addressing_type.return_value = addressing_type assert CanIdHandler.is_normal_fixed_addressed_can_id(value, addressing_type=addressing_type) is False self.mock_validate_addressing_type.assert_called_once_with(addressing_type) @@ -350,46 +432,79 @@ def test_is_mixed_11bit_addressed_can_id(self, mock_is_standard_can_id, value): # is_mixed_29bit_addressed_can_id - @pytest.mark.parametrize("value", [CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET, - CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0x1234, - CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF, - CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET, - CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0xDEBA, - CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF]) + @pytest.mark.parametrize("value", [CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + 0x1234 + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xDEBA + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET)]) def test_is_mixed_29bit_addressed_can_id__without_addressing__true(self, value): assert CanIdHandler.is_mixed_29bit_addressed_can_id(value) is True self.mock_validate_addressing_type.assert_not_called() - @pytest.mark.parametrize("value", [CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET - 1, - CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0x10000, - 0]) + @pytest.mark.parametrize("value", [CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) - 1, + CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) + 0x10000]) def test_is_mixed_29bit_addressed_can_id__without_addressing__false(self, value): assert CanIdHandler.is_mixed_29bit_addressed_can_id(value) is False self.mock_validate_addressing_type.assert_not_called() @pytest.mark.parametrize("value, addressing_type", [ - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET, AddressingType.PHYSICAL), - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0x1234, AddressingType.PHYSICAL), - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF, AddressingType.PHYSICAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET, AddressingType.FUNCTIONAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0xDEBA, AddressingType.FUNCTIONAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF, AddressingType.FUNCTIONAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + 0x1234 + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xDEBA + + (CanIdHandler.DEFAULT_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), ]) def test_is_mixed_29bit_addressed_can_id__with_addressing__true(self, value, addressing_type): + self.mock_validate_addressing_type.return_value = addressing_type assert CanIdHandler.is_mixed_29bit_addressed_can_id(value, addressing_type=addressing_type) is True self.mock_validate_addressing_type.assert_called_once_with(addressing_type) @pytest.mark.parametrize("value, addressing_type", [ - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET - 1, AddressingType.PHYSICAL), - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0x10000, AddressingType.PHYSICAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET - 1, AddressingType.FUNCTIONAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0x10000, AddressingType.FUNCTIONAL), - (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET, AddressingType.FUNCTIONAL), - (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET, AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET) - 1, + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + + (CanIdHandler.MIN_EXTENDED_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0xFFFF + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.PHYSICAL), + (CanIdHandler.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + 0x10000 + + (CanIdHandler.MAX_PRIORITY_VALUE << CanIdHandler.PRIORITY_BIT_OFFSET), + AddressingType.FUNCTIONAL), (0, AddressingType.PHYSICAL), ]) def test_is_mixed_29bit_addressed_can_id__with_addressing__false(self, value, addressing_type): - assert CanIdHandler.is_mixed_29bit_addressed_can_id(value, addressing_type=addressing_type) is False + self.mock_validate_addressing_type.return_value = addressing_type + assert CanIdHandler.is_normal_fixed_addressed_can_id(value, addressing_type=addressing_type) is False self.mock_validate_addressing_type.assert_called_once_with(addressing_type) # is_can_id @@ -494,6 +609,122 @@ def test_validate_can_id__valid(self, mock_is_can_id, mock_is_standard_can_id, m mock_is_standard_can_id.assert_called_once_with(value) mock_is_extended_can_id.assert_not_called() + # validate_priority + + @patch(f"{SCRIPT_LOCATION}.isinstance") + def test_validate_priority__type_error(self, mock_isinstance): + mock_isinstance.return_value = False + value = Mock() + with pytest.raises(TypeError): + CanIdHandler.validate_priority(value) + mock_isinstance.assert_called_once_with(value, int) + + @pytest.mark.parametrize("value", [CanIdHandler.MIN_PRIORITY_VALUE - 1, + CanIdHandler.MAX_PRIORITY_VALUE + 1]) + @patch(f"{SCRIPT_LOCATION}.isinstance") + def test_validate_priority__value_error(self, mock_isinstance, value): + mock_isinstance.return_value = True + with pytest.raises(ValueError): + CanIdHandler.validate_priority(value) + mock_isinstance.assert_called_once_with(value, int) + + @pytest.mark.parametrize("value", [CanIdHandler.MIN_PRIORITY_VALUE, + CanIdHandler.DEFAULT_PRIORITY_VALUE - 1, + CanIdHandler.MAX_PRIORITY_VALUE]) + @patch(f"{SCRIPT_LOCATION}.isinstance") + def test_validate_priority__valid(self, mock_isinstance, value): + mock_isinstance.return_value = True + assert CanIdHandler.validate_priority(value) is None + mock_isinstance.assert_called_once_with(value, int) + + +@pytest.mark.integration +class TestCanIdHandlerIntegration: + """Integration tests for `TestCanIdHandler` class.""" + + @pytest.mark.parametrize("addressing_type", list(AddressingType)) + @pytest.mark.parametrize("target_address", [0x00, 0x1A, 0xFF]) + @pytest.mark.parametrize("source_address", [0x9C, 0xB2, 0xFE]) + def test_encode_decode_normal_fixed_can_id(self, addressing_type, target_address, source_address): + can_id = CanIdHandler.encode_normal_fixed_addressed_can_id(addressing_type=addressing_type, + target_address=target_address, + source_address=source_address) + assert CanIdHandler.decode_can_id(addressing_format=CanAddressingFormat.NORMAL_FIXED_ADDRESSING, + can_id=can_id) == { + CanIdHandler.ADDRESSING_TYPE_NAME: addressing_type, + CanIdHandler.TARGET_ADDRESS_NAME: target_address, + CanIdHandler.SOURCE_ADDRESS_NAME: source_address + } + + @pytest.mark.parametrize("addressing_type", list(AddressingType)) + @pytest.mark.parametrize("target_address", [0x00, 0x1A, 0xFF]) + @pytest.mark.parametrize("source_address", [0x9C, 0xB2, 0xFE]) + def test_encode_decode_mixed_29bit_can_id(self, addressing_type, target_address, source_address): + can_id = CanIdHandler.encode_mixed_addressed_29bit_can_id(addressing_type=addressing_type, + target_address=target_address, + source_address=source_address) + assert CanIdHandler.decode_can_id(addressing_format=CanAddressingFormat.MIXED_29BIT_ADDRESSING, + can_id=can_id) == { + CanIdHandler.ADDRESSING_TYPE_NAME: addressing_type, + CanIdHandler.TARGET_ADDRESS_NAME: target_address, + CanIdHandler.SOURCE_ADDRESS_NAME: source_address + } + + @pytest.mark.parametrize("addressing_format, can_id, expected_can_id_ai", [ + # Normal + (CanAddressingFormat.NORMAL_ADDRESSING, 0x12345, + CanIdHandler.CanIdAIAlias(addressing_type=None, target_address=None, source_address=None)), + # Normal Fixed + (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, 0xDAFF00, + CanIdHandler.CanIdAIAlias(addressing_type=AddressingType.PHYSICAL, target_address=0xFF, source_address=0x00)), + (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, 0x1CDBC85A, + CanIdHandler.CanIdAIAlias(addressing_type=AddressingType.FUNCTIONAL, target_address=0xC8, source_address=0x5A)), + # Extended + (CanAddressingFormat.EXTENDED_ADDRESSING, 0xDBC85A, + CanIdHandler.CanIdAIAlias(addressing_type=None, target_address=None, source_address=None)), + # Mixed 11bit + (CanAddressingFormat.MIXED_11BIT_ADDRESSING, 0x6FE, + CanIdHandler.CanIdAIAlias(addressing_type=None, target_address=None, source_address=None)), + # Mixed 29bit + (CanAddressingFormat.MIXED_29BIT_ADDRESSING, 0xCEFF00, + CanIdHandler.CanIdAIAlias(addressing_type=AddressingType.PHYSICAL, target_address=0xFF, source_address=0x00)), + (CanAddressingFormat.MIXED_29BIT_ADDRESSING, 0x1CCDC85A, + CanIdHandler.CanIdAIAlias(addressing_type=AddressingType.FUNCTIONAL, target_address=0xC8, source_address=0x5A)), + ]) + def test_decode_can_id(self, addressing_format, can_id, expected_can_id_ai): + assert CanIdHandler.decode_can_id(addressing_format=addressing_format, can_id=can_id) == expected_can_id_ai + + @pytest.mark.parametrize("can_id, addressing_format, addressing_type, expected_result", [ + # Normal + (CanIdHandler.MAX_EXTENDED_VALUE, CanAddressingFormat.NORMAL_ADDRESSING, AddressingType.PHYSICAL, True), + (CanIdHandler.MIN_STANDARD_VALUE, CanAddressingFormat.NORMAL_ADDRESSING, AddressingType.FUNCTIONAL, True), + # Normal Fixed + (0xDA5432, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.PHYSICAL, True), + (0x1CDB0000, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.PHYSICAL, False), + (0x1DA5432, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.PHYSICAL, False), + (0x1CDB0000, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.FUNCTIONAL, True), + (0xDA5432, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.FUNCTIONAL, False), + (0x2DB0000, CanAddressingFormat.NORMAL_FIXED_ADDRESSING, AddressingType.FUNCTIONAL, False), + # Extended + (CanIdHandler.MAX_EXTENDED_VALUE, CanAddressingFormat.EXTENDED_ADDRESSING, AddressingType.PHYSICAL, True), + (CanIdHandler.MIN_STANDARD_VALUE, CanAddressingFormat.EXTENDED_ADDRESSING, AddressingType.FUNCTIONAL, True), + # Mixed 11 bit + (CanIdHandler.MIN_STANDARD_VALUE, CanAddressingFormat.MIXED_11BIT_ADDRESSING, AddressingType.PHYSICAL, True), + (CanIdHandler.MAX_STANDARD_VALUE, CanAddressingFormat.MIXED_11BIT_ADDRESSING, AddressingType.FUNCTIONAL, True), + (CanIdHandler.MIN_EXTENDED_VALUE, CanAddressingFormat.MIXED_11BIT_ADDRESSING, AddressingType.PHYSICAL, False), + # Mixed 29 bit + (0xCE5432, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.PHYSICAL, True), + (0x1CCD0000, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.PHYSICAL, False), + (0x1CE5432, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.PHYSICAL, False), + (0x1CCD0000, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.FUNCTIONAL, True), + (0xCE5432, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.FUNCTIONAL, False), + (0x2CD0000, CanAddressingFormat.MIXED_29BIT_ADDRESSING, AddressingType.FUNCTIONAL, False), + ]) + def test_is_compatible_can_id(self, can_id, addressing_format, addressing_type, expected_result): + assert CanIdHandler.is_compatible_can_id(can_id=can_id, + addressing_type=addressing_type, + addressing_format=addressing_format) == expected_result + class TestCanDlcHandler: """Unit tests for `CanDlcHandler` class.""" @@ -632,37 +863,6 @@ def test_validate_dlc__valid(self, value, exact_match): assert CanDlcHandler.validate_data_bytes_number(value, exact_match) is None -@pytest.mark.integration -class TestCanIdHandlerIntegration: - """Integration tests for `TestCanIdHandler` class.""" - - @pytest.mark.parametrize("target_address", [0x00, 0x1A, 0xFF]) - @pytest.mark.parametrize("source_address", [0x9C, 0xB2, 0xFE]) - def test_encode_decode_normal_fixed_can_id(self, example_addressing_type, target_address, source_address): - can_id = CanIdHandler.encode_normal_fixed_addressed_can_id(addressing_type=example_addressing_type, - target_address=target_address, - source_address=source_address) - assert CanIdHandler.decode_can_id(addressing_format=CanAddressingFormat.NORMAL_FIXED_ADDRESSING, - can_id=can_id) == { - CanIdHandler.ADDRESSING_TYPE_NAME: example_addressing_type, - CanIdHandler.TARGET_ADDRESS_NAME: target_address, - CanIdHandler.SOURCE_ADDRESS_NAME: source_address - } - - @pytest.mark.parametrize("target_address", [0x00, 0x1A, 0xFF]) - @pytest.mark.parametrize("source_address", [0x9C, 0xB2, 0xFE]) - def test_encode_decode_mixed_29bit_can_id(self, example_addressing_type, target_address, source_address): - can_id = CanIdHandler.encode_mixed_addressed_29bit_can_id(addressing_type=example_addressing_type, - target_address=target_address, - source_address=source_address) - assert CanIdHandler.decode_can_id(addressing_format=CanAddressingFormat.MIXED_29BIT_ADDRESSING, - can_id=can_id) == { - CanIdHandler.ADDRESSING_TYPE_NAME: example_addressing_type, - CanIdHandler.TARGET_ADDRESS_NAME: target_address, - CanIdHandler.SOURCE_ADDRESS_NAME: source_address - } - - @pytest.mark.integration class TestCanDlcHandlerIntegration: """Integration tests for `CanDlcHandler` class.""" diff --git a/tests/software_tests/can/test_mixed_addressing_information.py b/tests/software_tests/can/test_mixed_addressing_information.py index 8d3ed9c0..335f02b3 100644 --- a/tests/software_tests/can/test_mixed_addressing_information.py +++ b/tests/software_tests/can/test_mixed_addressing_information.py @@ -87,6 +87,78 @@ def test_validate_ai_mixed_11bit__valid(self, addressing_type, can_id, address_e self.mock_validate_addressing_type.assert_called_once_with(addressing_type) self.mock_validate_raw_byte.assert_called_once_with(address_extension) + # _validate_node_ai + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1, "address_extension": 1}, + {"can_id": 2, "address_extension": 1}, + {"can_id": 3, "address_extension": 4}, + {"can_id": 3, "address_extension": 4}, + ), + ( + {"can_id": 0x4321, "address_extension": 0xFF}, + {"can_id": 0x4321, "address_extension": 0xFF}, + {"can_id": 0x4321, "address_extension": 0xFE}, + {"can_id": 0x4321, "address_extension": 0xFE}, + ), + ( + {"can_id": 0xABC, "address_extension": 0xFF}, + {"can_id": 0xDEF, "address_extension": 0xFF}, + {"can_id": 0xADD, "address_extension": 0xFE}, + {"can_id": 0xFEE, "address_extension": 0xF1}, + ), + ( + {"can_id": 0xABC, "address_extension": 0x4E}, + {"can_id": 0xDEF, "address_extension": 0x43}, + {"can_id": 0xABC, "address_extension": 0x70}, + {"can_id": 0xDEF, "address_extension": 0x70}, + ), + ]) + def test_validate_node_ai__inconsistent(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + with pytest.raises(InconsistentArgumentsError): + Mixed11BitCanAddressingInformation._validate_node_ai(rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1, "address_extension": 1}, + {"can_id": 2, "address_extension": 1}, + {"can_id": 3, "address_extension": 4}, + {"can_id": 4, "address_extension": 4}, + ), + ( + {"can_id": 0x4321, "address_extension": 0xFF}, + {"can_id": 0x4322, "address_extension": 0xFF}, + {"can_id": 0x4323, "address_extension": 0xFE}, + {"can_id": 0x4324, "address_extension": 0xFE}, + ), + ( + {"can_id": 0xABC, "address_extension": 0xFF}, + {"can_id": 0xDEF, "address_extension": 0xFF}, + {"can_id": 0xADD, "address_extension": 0xF1}, + {"can_id": 0xFEE, "address_extension": 0xF1}, + ), + ( + {"can_id": 0xABC, "address_extension": 0x43}, + {"can_id": 0xDEF, "address_extension": 0x43}, + {"can_id": 0xABC, "address_extension": 0x70}, + {"can_id": 0xDEF, "address_extension": 0x70}, + ), + ]) + def test_validate_node_ai__valid(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + assert Mixed11BitCanAddressingInformation._validate_node_ai( + rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) is None + class TestMixed29BitCanAddressingInformation: """Unit tests for `Mixed29BitCanAddressingInformation` class.""" @@ -218,3 +290,69 @@ def test_validate_packet_ai__valid_with_can_id(self, addressing_type, can_id, self.mock_validate_addressing_type.assert_called_once_with(addressing_type) self.mock_validate_raw_byte.assert_called_once_with(address_extension) self.mock_can_id_handler_class.decode_mixed_addressed_29bit_can_id.assert_called_once_with(can_id) + + # _validate_node_ai + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 0xCE1234, "target_address": 0x12, "source_address": 0x34, "address_extension": 0x01}, + {"can_id": 0xCE3413, "target_address": 0x34, "source_address": 0x13, "address_extension": 0x01}, + {"can_id": 0xCD01FF, "target_address": 0x01, "source_address": 0xFF, "address_extension": 0xFF}, + {"can_id": 0xCDFF01, "target_address": 0xFF, "source_address": 0x01, "address_extension": 0xFF}, + ), + ( + {"can_id": 0x18CEFEDC, "target_address": 0xFE, "source_address": 0xDC, "address_extension": 0x00}, + {"can_id": 0x18CEDCDE, "target_address": 0xDC, "source_address": 0xFE, "address_extension": 0x00}, + {"can_id": 0x18CD543F, "target_address": 0x54, "source_address": 0x3F, "address_extension": 0xFF}, + {"can_id": 0x18CD543F, "target_address": 0x54, "source_address": 0x3F, "address_extension": 0xFF}, + ), + ( + {"can_id": 0x1CCEFEDC, "target_address": 0xFE, "source_address": 0xDC, "address_extension": 0xCD}, + {"can_id": 0x1CCEDCDE, "target_address": 0xDC, "source_address": 0xFE, "address_extension": 0xCD}, + {"can_id": 0x10CD543F, "target_address": 0x54, "source_address": 0x3F, "address_extension": 0xCD}, + {"can_id": 0x10CD3F54, "target_address": 0x3F, "source_address": 0x54, "address_extension": 0x01}, + ), + ( + {"can_id": 0xCCE00FF, "target_address": 0x00, "source_address": 0xFF, "address_extension": 0x43}, + {"can_id": 0xCCEFF00, "target_address": 0xFF, "source_address": 0x00, "address_extension": 0x65}, + {"can_id": 0x8CDFF00, "target_address": 0xFF, "source_address": 0x00, "address_extension": 0x43}, + {"can_id": 0x8CD00FF, "target_address": 0x00, "source_address": 0xFF, "address_extension": 0x65}, + ), + ]) + def test_validate_node_ai__inconsistent(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + with pytest.raises(InconsistentArgumentsError): + Mixed29BitCanAddressingInformation._validate_node_ai(rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 0xCE1234, "target_address": 0x12, "source_address": 0x34, "address_extension": 0x01}, + {"can_id": 0xCE3413, "target_address": 0x34, "source_address": 0x12, "address_extension": 0x01}, + {"can_id": 0xCD01FF, "target_address": 0x01, "source_address": 0xFF, "address_extension": 0xFF}, + {"can_id": 0xCDFF01, "target_address": 0xFF, "source_address": 0x01, "address_extension": 0xFF}, + ), + ( + {"can_id": 0x18CEFEDC, "target_address": 0xFE, "source_address": 0xDC, "address_extension": 0x00}, + {"can_id": 0x18CEDCDE, "target_address": 0xDC, "source_address": 0xFE, "address_extension": 0x00}, + {"can_id": 0x18CD543F, "target_address": 0x54, "source_address": 0x3F, "address_extension": 0xFF}, + {"can_id": 0x18CD3F54, "target_address": 0x3F, "source_address": 0x54, "address_extension": 0xFF}, + ), + ( + {"can_id": 0x1CCEFEDC, "target_address": 0xFE, "source_address": 0xDC, "address_extension": 0xCD}, + {"can_id": 0x1CCEDCDE, "target_address": 0xDC, "source_address": 0xFE, "address_extension": 0xCD}, + {"can_id": 0x10CD543F, "target_address": 0x54, "source_address": 0x3F, "address_extension": 0xCD}, + {"can_id": 0x10CD3F54, "target_address": 0x3F, "source_address": 0x54, "address_extension": 0xCD}, + ), + ]) + def test_validate_node_ai__valid(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + assert Mixed29BitCanAddressingInformation._validate_node_ai( + rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) is None diff --git a/tests/software_tests/can/test_normal_addressing_information.py b/tests/software_tests/can/test_normal_addressing_information.py index db9b9281..f023a430 100644 --- a/tests/software_tests/can/test_normal_addressing_information.py +++ b/tests/software_tests/can/test_normal_addressing_information.py @@ -5,7 +5,7 @@ AbstractCanAddressingInformation, CanAddressingFormat, InconsistentArgumentsError, - Normal11BitCanAddressingInformation, + NormalCanAddressingInformation, NormalFixedCanAddressingInformation, UnusedArgumentError, ) @@ -13,11 +13,11 @@ SCRIPT_LOCATION = "uds.can.normal_addressing_information" -class TestNormal11BitCanAddressingInformation: - """Unit tests for `Normal11BitCanAddressingInformation` class.""" +class TestNormalCanAddressingInformation: + """Unit tests for `NormalCanAddressingInformation` class.""" def setup_method(self): - self.mock_addressing_information = Mock(spec=Normal11BitCanAddressingInformation) + self.mock_addressing_information = Mock(spec=NormalCanAddressingInformation) # patching self._patcher_validate_raw_byte = patch(f"{SCRIPT_LOCATION}.validate_raw_byte") self.mock_validate_raw_byte = self._patcher_validate_raw_byte.start() @@ -34,8 +34,8 @@ def teardown_method(self): # addressing_format def test_addressing_format(self): - assert Normal11BitCanAddressingInformation.addressing_format.fget(self.mock_addressing_information) \ - == CanAddressingFormat.NORMAL_11BIT_ADDRESSING + assert NormalCanAddressingInformation.addressing_format.fget(self.mock_addressing_information) \ + == CanAddressingFormat.NORMAL_ADDRESSING # validate_packet_ai @@ -47,30 +47,30 @@ def test_addressing_format(self): ]) def test_validate_packet_ai__inconsistent_arg(self, unsupported_args): with pytest.raises(UnusedArgumentError): - Normal11BitCanAddressingInformation.validate_packet_ai(addressing_type=Mock(), - can_id=Mock(), - **unsupported_args) + NormalCanAddressingInformation.validate_packet_ai(addressing_type=Mock(), + can_id=Mock(), + **unsupported_args) @pytest.mark.parametrize("addressing_type, can_id", [ ("some addressing type", "some id"), (Mock(), 0x7FF), ]) def test_validate_packet_ai__invalid_can_id(self, addressing_type, can_id): - self.mock_can_id_handler_class.is_normal_11bit_addressed_can_id.return_value = False + self.mock_can_id_handler_class.is_normal_addressed_can_id.return_value = False with pytest.raises(InconsistentArgumentsError): - Normal11BitCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, can_id=can_id) + NormalCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, can_id=can_id) self.mock_can_id_handler_class.validate_can_id.assert_called_once_with(can_id) - self.mock_can_id_handler_class.is_normal_11bit_addressed_can_id.assert_called_once_with(can_id) + self.mock_can_id_handler_class.is_normal_addressed_can_id.assert_called_once_with(can_id) @pytest.mark.parametrize("addressing_type, can_id", [ ("some addressing type", "some id"), (Mock(), 0x7FF), ]) def test_validate_packet_ai__valid(self, addressing_type, can_id): - self.mock_can_id_handler_class.is_normal_11bit_addressed_can_id.return_value = True - assert Normal11BitCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, - can_id=can_id) == { - AbstractCanAddressingInformation.ADDRESSING_FORMAT_NAME: CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + self.mock_can_id_handler_class.is_normal_addressed_can_id.return_value = True + assert NormalCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, + can_id=can_id) == { + AbstractCanAddressingInformation.ADDRESSING_FORMAT_NAME: CanAddressingFormat.NORMAL_ADDRESSING, AbstractCanAddressingInformation.ADDRESSING_TYPE_NAME: self.mock_validate_addressing_type.return_value, AbstractCanAddressingInformation.CAN_ID_NAME: can_id, AbstractCanAddressingInformation.TARGET_ADDRESS_NAME: None, @@ -78,9 +78,63 @@ def test_validate_packet_ai__valid(self, addressing_type, can_id): AbstractCanAddressingInformation.ADDRESS_EXTENSION_NAME: None, } self.mock_can_id_handler_class.validate_can_id.assert_called_once_with(can_id) - self.mock_can_id_handler_class.is_normal_11bit_addressed_can_id.assert_called_once_with(can_id) + self.mock_can_id_handler_class.is_normal_addressed_can_id.assert_called_once_with(can_id) self.mock_validate_addressing_type.assert_called_once_with(addressing_type) + # _validate_node_ai + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1}, + {"can_id": 2}, + {"can_id": 3}, + {"can_id": 3}, + ), + ( + {"can_id": 0x4321}, + {"can_id": 0x4321}, + {"can_id": 0x4321}, + {"can_id": 0x4321}, + ), + ]) + def test_validate_node_ai__inconsistent(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + with pytest.raises(InconsistentArgumentsError): + NormalCanAddressingInformation._validate_node_ai(rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 1}, + {"can_id": 2}, + {"can_id": 3}, + {"can_id": 4}, + ), + ( + {"can_id": 0x711}, + {"can_id": 0x712}, + {"can_id": 0x6FE}, + {"can_id": 0x6FF}, + ), + ( + {"can_id": 0xABC1}, + {"can_id": 0xABC2}, + {"can_id": 0xABC3}, + {"can_id": 0xABC4}, + ), + ]) + def test_validate_node_ai__valid(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + assert NormalCanAddressingInformation._validate_node_ai( + rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) is None + class TestNormalFixedCanAddressingInformation: """Unit tests for `NormalFixedCanAddressingInformation` class.""" @@ -211,3 +265,57 @@ def test_validate_packet_ai__valid_with_can_id(self, addressing_type, can_id, ta self.mock_validate_addressing_type.assert_called_once_with(addressing_type) self.mock_validate_raw_byte.assert_not_called() self.mock_can_id_handler_class.decode_normal_fixed_addressed_can_id.assert_called_once_with(can_id) + + # _validate_node_ai + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 0xDA1234, "target_address": 0x12, "source_address": 0x34}, + {"can_id": 0xDA3413, "target_address": 0x34, "source_address": 0x13}, + {"can_id": 0xDB01FF, "target_address": 0x01, "source_address": 0xFF}, + {"can_id": 0xDBFF01, "target_address": 0xFF, "source_address": 0x01}, + ), + ( + {"can_id": 0x18DAFEDC, "target_address": 0xFE, "source_address": 0xDC}, + {"can_id": 0x18DADCDE, "target_address": 0xDC, "source_address": 0xFE}, + {"can_id": 0x18DB543F, "target_address": 0x54, "source_address": 0x3F}, + {"can_id": 0x18DB543F, "target_address": 0x54, "source_address": 0x3F}, + ), + ]) + def test_validate_node_ai__inconsistent(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + with pytest.raises(InconsistentArgumentsError): + NormalFixedCanAddressingInformation._validate_node_ai(rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) + + @pytest.mark.parametrize("rx_packets_physical_ai, tx_packets_physical_ai, " + "rx_packets_functional_ai, tx_packets_functional_ai", [ + ( + {"can_id": 0xDA1234, "target_address": 0x12, "source_address": 0x34}, + {"can_id": 0xDA3412, "target_address": 0x34, "source_address": 0x12}, + {"can_id": 0xDB01FF, "target_address": 0x01, "source_address": 0xFF}, + {"can_id": 0xDBFF01, "target_address": 0xFF, "source_address": 0x01}, + ), + ( + {"can_id": 0x18DAFEDC, "target_address": 0xFE, "source_address": 0xDC}, + {"can_id": 0x18DADCDE, "target_address": 0xDC, "source_address": 0xFE}, + {"can_id": 0x18DB543F, "target_address": 0x54, "source_address": 0x3F}, + {"can_id": 0x18DB3F54, "target_address": 0x3F, "source_address": 0x54}, + ), + ( + {"can_id": 0x1CDA2F71, "target_address": 0x2F, "source_address": 0x71}, + {"can_id": 0x1CDA712F, "target_address": 0x71, "source_address": 0x2F}, + {"can_id": 0x8DB5580, "target_address": 0x55, "source_address": 0x80}, + {"can_id": 0x8DB8055, "target_address": 0x80, "source_address": 0x55}, + ), + ]) + def test_validate_node_ai__valid(self, rx_packets_physical_ai, tx_packets_physical_ai, + rx_packets_functional_ai, tx_packets_functional_ai): + assert NormalFixedCanAddressingInformation._validate_node_ai( + rx_packets_physical_ai=rx_packets_physical_ai, + tx_packets_physical_ai=tx_packets_physical_ai, + rx_packets_functional_ai=rx_packets_functional_ai, + tx_packets_functional_ai=tx_packets_functional_ai) is None diff --git a/tests/software_tests/can/test_single_frame.py b/tests/software_tests/can/test_single_frame.py index 8be0d1b1..a433249d 100644 --- a/tests/software_tests/can/test_single_frame.py +++ b/tests/software_tests/can/test_single_frame.py @@ -678,7 +678,7 @@ class TestCanSingleFrameHandlerIntegration: # create_valid_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x3E]}, [0x01, 0x3E]), ({"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -708,7 +708,7 @@ def test_create_valid_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanSingleFrameHandler.create_valid_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x3E], "dlc": 1}, {"addressing_format": CanAddressingFormat.NORMAL_FIXED_ADDRESSING, @@ -732,7 +732,7 @@ def test_create_valid_frame_data__invalid(self, kwargs): # create_any_frame_data @pytest.mark.parametrize("kwargs, expected_raw_frame_data", [ - ({"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + ({"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x3E], "dlc": 2, "sf_dl_short": 0xF}, @@ -771,7 +771,7 @@ def test_create_any_frame_data__valid(self, kwargs, expected_raw_frame_data): assert CanSingleFrameHandler.create_any_frame_data(**kwargs) == expected_raw_frame_data @pytest.mark.parametrize("kwargs", [ - {"addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + {"addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "payload": [0x3E], "dlc": 1, "sf_dl_short": 0xF}, @@ -799,7 +799,7 @@ def test_create_any_frame_data__invalid(self, kwargs): # decode_sf_dl @pytest.mark.parametrize("addressing_format, raw_frame_data, expected_sf_dl", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x01, 0x3E), 1), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x01, 0x3E), 1), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x00, 0x32] + list(range(20, 82)), 0x32), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFE], 4), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, [0x0A, 0x00, 0x3D] + list(range(100, 161)), 0x3D), @@ -812,7 +812,7 @@ def test_decode_sf_dl(self, addressing_format, raw_frame_data, expected_sf_dl): # validate_frame_data @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x07, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32)), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x07, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32)), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x00, 0x3E] + list(range(0x10, 0x4E))), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x00, 0x00, 0x01] + list(range(0x10, 0x4D))), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0x02, 0x01, 0xFF)), @@ -823,7 +823,7 @@ def test_validate_frame_data__valid(self, addressing_format, raw_frame_data): raw_frame_data=raw_frame_data) is None @pytest.mark.parametrize("addressing_format, raw_frame_data", [ - (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, (0x05, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), + (CanAddressingFormat.NORMAL_ADDRESSING, (0x05, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54)), (CanAddressingFormat.NORMAL_FIXED_ADDRESSING, [0x00, 0x3F] + list(range(0x10, 0x4E))), (CanAddressingFormat.EXTENDED_ADDRESSING, [0x00, 0x01, 0x01] + list(range(0x10, 0x4D))), (CanAddressingFormat.MIXED_11BIT_ADDRESSING, (0x02, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)), diff --git a/tests/software_tests/conftest.py b/tests/software_tests/conftest.py index aee1f116..37f6a6ee 100644 --- a/tests/software_tests/conftest.py +++ b/tests/software_tests/conftest.py @@ -6,7 +6,7 @@ ExtendedCanAddressingInformation, Mixed11BitCanAddressingInformation, Mixed29BitCanAddressingInformation, - Normal11BitCanAddressingInformation, + NormalCanAddressingInformation, NormalFixedCanAddressingInformation, ) from uds.segmentation import CanSegmenter @@ -58,12 +58,12 @@ def example_can_addressing_format(request): @fixture(params=[ - CanSegmenter(addressing_information=Normal11BitCanAddressingInformation(rx_physical={"can_id": 0x643}, - tx_physical={"can_id": 0x644}, - rx_functional={"can_id": 0x7DE}, - tx_functional={"can_id": 0x7DF})), + CanSegmenter(addressing_information=NormalCanAddressingInformation(rx_physical={"can_id": 0x643}, + tx_physical={"can_id": 0x644}, + rx_functional={"can_id": 0x7DE}, + tx_functional={"can_id": 0x7DF})), CanSegmenter(addressing_information=NormalFixedCanAddressingInformation(rx_physical={"target_address": 0x12, "source_address": 0xF8}, - tx_physical={"can_id": 0x18DAF812,"target_address": 0xF8, "source_address": 0x12}, + tx_physical={"can_id": 0x18DAF812, "target_address": 0xF8, "source_address": 0x12}, rx_functional={"can_id": 0x18DB0BFF, "target_address": 0x0B, "source_address": 0xFF}, tx_functional={"target_address": 0xFF, "source_address": 0x0B}), dlc=0xF, @@ -76,14 +76,14 @@ def example_can_addressing_format(request): dlc=0xA, filler_byte=0x55), CanSegmenter(addressing_information=Mixed11BitCanAddressingInformation(rx_physical={"can_id": 0x6FE, "address_extension": 0x6B}, - tx_physical={"can_id": 0x720, "address_extension": 0xD0}, - rx_functional={"can_id": 0x7BD, "address_extension": 0x9C}, - tx_functional={"can_id": 0x7BD, "address_extension": 0xF2}), + tx_physical={"can_id": 0x720, "address_extension": 0x6B}, + rx_functional={"can_id": 0x7BC, "address_extension": 0x9C}, + tx_functional={"can_id": 0x7BD, "address_extension": 0x9C}), use_data_optimization=True), CanSegmenter(addressing_information=Mixed29BitCanAddressingInformation(rx_physical={"can_id": 0x18CEF1E2, "address_extension": 0x6B}, - tx_physical={"can_id": 0x18CEE2F1, "target_address": 0xE2, "source_address": 0xF1, "address_extension": 0xD0}, + tx_physical={"can_id": 0x18CEE2F1, "target_address": 0xE2, "source_address": 0xF1, "address_extension": 0x6B}, rx_functional={"target_address": 0xFF, "source_address": 0xFF, "address_extension": 0x55}, - tx_functional={"can_id": 0x18CDFFFF, "address_extension": 0xEF}), + tx_functional={"can_id": 0x18CDFFFF, "address_extension": 0x55}), dlc=0xF, filler_byte=0xAA), ]) diff --git a/tests/software_tests/transport_interface/can_transport_interface/__init__.py b/tests/software_tests/packet/can/__init__.py similarity index 100% rename from tests/software_tests/transport_interface/can_transport_interface/__init__.py rename to tests/software_tests/packet/can/__init__.py diff --git a/tests/software_tests/packet/test_abstract_can_packet_container.py b/tests/software_tests/packet/can/test_abstract_can_container.py similarity index 99% rename from tests/software_tests/packet/test_abstract_can_packet_container.py rename to tests/software_tests/packet/can/test_abstract_can_container.py index c51da523..eb77c401 100644 --- a/tests/software_tests/packet/test_abstract_can_packet_container.py +++ b/tests/software_tests/packet/can/test_abstract_can_container.py @@ -1,14 +1,14 @@ import pytest from mock import Mock, patch -from uds.packet.abstract_can_packet_container import ( +from uds.packet.can.abstract_can_container import ( AbstractCanAddressingInformation, AbstractCanPacketContainer, CanPacketType, ) from uds.transmission_attributes import AddressingType -SCRIPT_LOCATION = "uds.packet.abstract_can_packet_container" +SCRIPT_LOCATION = "uds.packet.can.abstract_can_container" class TestAbstractCanPacketContainer: diff --git a/tests/software_tests/packet/test_can_packet.py b/tests/software_tests/packet/can/test_can_packet.py similarity index 96% rename from tests/software_tests/packet/test_can_packet.py rename to tests/software_tests/packet/can/test_can_packet.py index 20baae1e..5a0963a4 100644 --- a/tests/software_tests/packet/test_can_packet.py +++ b/tests/software_tests/packet/can/test_can_packet.py @@ -2,7 +2,7 @@ from mock import Mock, call, patch from uds.can import CanFlowStatus -from uds.packet.can_packet import ( +from uds.packet.can.can_packet import ( DEFAULT_FILLER_BYTE, AbstractCanAddressingInformation, AddressingType, @@ -12,7 +12,7 @@ CanPacketType, ) -SCRIPT_LOCATION = "uds.packet.can_packet" +SCRIPT_LOCATION = "uds.packet.can.can_packet" class TestCanPacket: @@ -27,8 +27,8 @@ def setup_method(self): self.mock_can_dlc_handler_class = self._patcher_can_dlc_handler_class.start() self._patcher_ai_class = patch(f"{SCRIPT_LOCATION}.CanAddressingInformation") self.mock_ai_class = self._patcher_ai_class.start() - self._patcher_normal_11bit_ai_class = patch(f"{SCRIPT_LOCATION}.Normal11BitCanAddressingInformation") - self.mock_normal_11bit_ai_class = self._patcher_normal_11bit_ai_class.start() + self._patcher_normal_ai_class = patch(f"{SCRIPT_LOCATION}.NormalCanAddressingInformation") + self.mock_normal_ai_class = self._patcher_normal_ai_class.start() self._patcher_normal_fixed_ai_class = patch(f"{SCRIPT_LOCATION}.NormalFixedCanAddressingInformation") self.mock_normal_fixed_ai_class = self._patcher_normal_fixed_ai_class.start() self._patcher_extended_ai_class = patch(f"{SCRIPT_LOCATION}.ExtendedCanAddressingInformation") @@ -56,7 +56,7 @@ def teardown_method(self): self._patcher_warn.stop() self._patcher_can_dlc_handler_class.stop() self._patcher_ai_class.stop() - self._patcher_normal_11bit_ai_class.stop() + self._patcher_normal_ai_class.stop() self._patcher_normal_fixed_ai_class.stop() self._patcher_extended_ai_class.stop() self._patcher_mixed_11bit_ai_class.stop() @@ -77,7 +77,7 @@ def teardown_method(self): ]) @pytest.mark.parametrize("addressing_type, addressing_format, dlc", [ ("some addressing type", "some addressing format", "some dlc"), - (AddressingType.FUNCTIONAL, CanAddressingFormat.NORMAL_11BIT_ADDRESSING, 8), + (AddressingType.FUNCTIONAL, CanAddressingFormat.NORMAL_ADDRESSING, 8), ]) @pytest.mark.parametrize("can_id, target_address, source_address, address_extension", [ (None, 1, 2, 3), @@ -129,12 +129,12 @@ def test_set_address_information__unknown_addressing_format(self, addressing_for ("something", "CAN ID"), (AddressingType.PHYSICAL, 0x754), ]) - def test_set_address_information__normal_11_bit(self, addressing_type, can_id): + def test_set_address_information__normal(self, addressing_type, can_id): CanPacket.set_address_information(self=self.mock_can_packet, addressing_type=addressing_type, - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, can_id=can_id) - self.mock_can_packet.set_address_information_normal_11bit.assert_called_once_with( + self.mock_can_packet.set_address_information_normal.assert_called_once_with( addressing_type=addressing_type, can_id=can_id) self.mock_warn.assert_not_called() @@ -142,16 +142,16 @@ def test_set_address_information__normal_11_bit(self, addressing_type, can_id): ("something", "CAN ID", "TA", "SA", "AE"), (AddressingType.PHYSICAL, 0x754, 0x31, 0xD0, 0xE3), ]) - def test_set_address_information__normal_11_bit_with_warn(self, addressing_type, can_id, + def test_set_address_information__normal_with_warn(self, addressing_type, can_id, target_address, source_address, address_extension): CanPacket.set_address_information(self=self.mock_can_packet, addressing_type=addressing_type, - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, can_id=can_id, target_address=target_address, source_address=source_address, address_extension=address_extension) - self.mock_can_packet.set_address_information_normal_11bit.assert_called_once_with( + self.mock_can_packet.set_address_information_normal.assert_called_once_with( addressing_type=addressing_type, can_id=can_id) self.mock_warn.assert_called_once() @@ -277,23 +277,23 @@ def test_set_address_information__mixed_29bit(self, addressing_type, can_id, address_extension=address_extension) self.mock_warn.assert_not_called() - # set_address_information_normal_11bit + # set_address_information_normal @pytest.mark.parametrize("can_id, addressing_type", [ ("some CAN ID", "some addressing type"), (0x64A, AddressingType.PHYSICAL), ]) - def test_set_address_information_normal_11bit(self, can_id, addressing_type): - CanPacket.set_address_information_normal_11bit(self=self.mock_can_packet, - addressing_type=addressing_type, - can_id=can_id) - self.mock_normal_11bit_ai_class.validate_packet_ai.assert_called_once_with( + def test_set_address_information_normal(self, can_id, addressing_type): + CanPacket.set_address_information_normal(self=self.mock_can_packet, + addressing_type=addressing_type, + can_id=can_id) + self.mock_normal_ai_class.validate_packet_ai.assert_called_once_with( addressing_type=addressing_type, can_id=can_id) self.mock_can_packet._CanPacket__validate_unambiguous_ai_change.assert_called_once_with( - CanAddressingFormat.NORMAL_11BIT_ADDRESSING) + CanAddressingFormat.NORMAL_ADDRESSING) self.mock_addressing_type_class.assert_called_once_with(addressing_type) self.mock_can_packet._CanPacket__update_ai_data_byte.assert_called_once_with() - assert self.mock_can_packet._CanPacket__addressing_format == CanAddressingFormat.NORMAL_11BIT_ADDRESSING + assert self.mock_can_packet._CanPacket__addressing_format == CanAddressingFormat.NORMAL_ADDRESSING assert self.mock_can_packet._CanPacket__addressing_type == self.mock_addressing_type_class.return_value assert self.mock_can_packet._CanPacket__can_id == can_id assert self.mock_can_packet._CanPacket__target_address is None @@ -783,7 +783,7 @@ def test_validate_unambiguous_ai_change__incompatible(self, new_addressing_forma # __update_ai_data_byte - @pytest.mark.parametrize("addressing_format", ["some CAN Addressing", CanAddressingFormat.NORMAL_11BIT_ADDRESSING]) + @pytest.mark.parametrize("addressing_format", ["some CAN Addressing", CanAddressingFormat.NORMAL_ADDRESSING]) @pytest.mark.parametrize("raw_frame_data", [(0x12, 0x34), tuple(range(10))]) def test_update_ai_data_byte__ignore(self, addressing_format, raw_frame_data): self.mock_can_packet._CanPacket__raw_frame_data = None @@ -792,7 +792,7 @@ def test_update_ai_data_byte__ignore(self, addressing_format, raw_frame_data): assert self.mock_can_packet._CanPacket__raw_frame_data is None self.mock_ai_class.encode_ai_data_bytes.assert_not_called() - @pytest.mark.parametrize("addressing_format", ["some CAN Addressing", CanAddressingFormat.NORMAL_11BIT_ADDRESSING]) + @pytest.mark.parametrize("addressing_format", ["some CAN Addressing", CanAddressingFormat.NORMAL_ADDRESSING]) @pytest.mark.parametrize("raw_frame_data", [(0x12, 0x34), tuple(range(10))]) @pytest.mark.parametrize("ai_data_bytes", [[], [0xF2]]) def test_update_ai_data_byte(self, addressing_format, raw_frame_data, ai_data_bytes): @@ -889,17 +889,17 @@ class TestCanPacketIntegration: "st_min": None}), # FC ({"packet_type": CanPacketType.FLOW_CONTROL, - "addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "addressing_type": AddressingType.PHYSICAL, - "can_id": 0x688, + "can_id": 0x12688, "flow_status": CanFlowStatus.ContinueToSend, "block_size": 0xF9, "st_min": 0xE0}, {"raw_frame_data": (0x30, 0xF9, 0xE0), "addressing_type": AddressingType.PHYSICAL, - "addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "packet_type": CanPacketType.FLOW_CONTROL, - "can_id": 0x688, + "can_id": 0x12688, "dlc": 3, "target_address": None, "source_address": None, diff --git a/tests/software_tests/packet/test_can_packet_record.py b/tests/software_tests/packet/can/test_can_packet_record.py similarity index 98% rename from tests/software_tests/packet/test_can_packet_record.py rename to tests/software_tests/packet/can/test_can_packet_record.py index 45dd23c9..a504e023 100644 --- a/tests/software_tests/packet/test_can_packet_record.py +++ b/tests/software_tests/packet/can/test_can_packet_record.py @@ -4,7 +4,7 @@ from mock import Mock, patch from uds.can import CanFlowStatus -from uds.packet.can_packet_record import ( +from uds.packet.can.can_packet_record import ( AbstractCanAddressingInformation, CanAddressingFormat, CanPacketRecord, @@ -14,7 +14,7 @@ ) from uds.transmission_attributes import AddressingType, TransmissionDirection -SCRIPT_LOCATION = "uds.packet.can_packet_record" +SCRIPT_LOCATION = "uds.packet.can.can_packet_record" class TestCanPacketRecord: @@ -245,11 +245,11 @@ class TestCanPacketRecordIntegration: data=[0x01, 0x3E]), "direction": TransmissionDirection.RECEIVED, "addressing_type": AddressingType.PHYSICAL, - "addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "transmission_time": datetime.now()}, {"raw_frame_data": (0x01, 0x3E), "addressing_type": AddressingType.PHYSICAL, - "addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "packet_type": CanPacketType.SINGLE_FRAME, "payload": (0x3E, ), "data_length": 1, @@ -303,7 +303,7 @@ def test_init__valid(self, kwargs, expected_attribute_values): data=[0xFF] * 8), "direction": TransmissionDirection.TRANSMITTED, "addressing_type": AddressingType.PHYSICAL, - "addressing_format": CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + "addressing_format": CanAddressingFormat.NORMAL_ADDRESSING, "transmission_time": datetime.now()}, {"frame": PythonCanMessage(arbitration_id=0x12345678, is_extended_id=True, diff --git a/tests/software_tests/packet/test_can_packet_type.py b/tests/software_tests/packet/can/test_can_packet_type.py similarity index 95% rename from tests/software_tests/packet/test_can_packet_type.py rename to tests/software_tests/packet/can/test_can_packet_type.py index a6d8686d..7b4d465a 100644 --- a/tests/software_tests/packet/test_can_packet_type.py +++ b/tests/software_tests/packet/can/test_can_packet_type.py @@ -2,7 +2,7 @@ from mock import patch from uds.packet import AbstractUdsPacketType -from uds.packet.can_packet_type import CanPacketType +from uds.packet.can.can_packet_type import CanPacketType class TestCanPacketType: diff --git a/tests/software_tests/segmentation/test_can_segmenter.py b/tests/software_tests/segmentation/test_can_segmenter.py index fe1232a8..763aa594 100644 --- a/tests/software_tests/segmentation/test_can_segmenter.py +++ b/tests/software_tests/segmentation/test_can_segmenter.py @@ -6,7 +6,7 @@ ExtendedCanAddressingInformation, Mixed11BitCanAddressingInformation, Mixed29BitCanAddressingInformation, - Normal11BitCanAddressingInformation, + NormalCanAddressingInformation, NormalFixedCanAddressingInformation, ) from uds.segmentation.can_segmenter import ( @@ -151,7 +151,7 @@ def test_addressing_information__set__type_error(self, value): CanSegmenter.addressing_information.fset(self.mock_can_segmenter, value=value) @pytest.mark.parametrize("value", [Mock(spec=AbstractCanAddressingInformation), - Mock(spec=Normal11BitCanAddressingInformation)]) + Mock(spec=NormalCanAddressingInformation)]) def test_addressing_information__set(self, value): CanSegmenter.addressing_information.fset(self.mock_can_segmenter, value=value) assert self.mock_can_segmenter._CanSegmenter__addressing_information == value @@ -705,10 +705,10 @@ class TestCanSegmenterIntegration: """Integration tests for `CanSegmenter` class.""" @pytest.mark.parametrize("addressing_information, frame_can_id, frame_data", [ - (Normal11BitCanAddressingInformation(rx_physical={"can_id": 0x611}, - tx_physical={"can_id": 0x612}, - rx_functional={"can_id": 0x6FE}, - tx_functional={"can_id": 0x6FF}), 0x611, [0x10, 0x01]), + (NormalCanAddressingInformation(rx_physical={"can_id": 0x611}, + tx_physical={"can_id": 0x612}, + rx_functional={"can_id": 0x6FE}, + tx_functional={"can_id": 0x6FF}), 0x611, [0x10, 0x01]), (NormalFixedCanAddressingInformation(rx_physical={"can_id": 0x18DA1234, "target_address": 0x12, "source_address": 0x34}, tx_physical={"can_id": 0x18DA3412, "target_address": 0x34, "source_address": 0x12}, rx_functional={"can_id": 0x18DBF0E1, "target_address": 0xF0, "source_address": 0xE1}, @@ -718,12 +718,12 @@ class TestCanSegmenterIntegration: rx_functional={"can_id": 0xFEDCBA, "target_address": 0xBB}, tx_functional={"can_id": 0xFEDCBA, "target_address": 0x12}), 0x1234, [0xF0, *range(63)]), (Mixed11BitCanAddressingInformation(rx_physical={"can_id": 0x645, "address_extension": 0x01}, - tx_physical={"can_id": 0x646, "address_extension": 0xFE}, + tx_physical={"can_id": 0x646, "address_extension": 0x01}, rx_functional={"can_id": 0x6DE, "address_extension": 0x05}, - tx_functional={"can_id": 0x6DF, "address_extension": 0xFF}), 0x645, [0x01, 0x3E]), + tx_functional={"can_id": 0x6DF, "address_extension": 0x05}), 0x645, [0x01, 0x3E]), (Mixed29BitCanAddressingInformation(rx_physical={"can_id": 0x18CEC2D0, "address_extension": 0x52, "target_address": 0xC2, "source_address": 0xD0}, - tx_physical={"can_id": 0x18CED0C2, "address_extension": 0xD8, "target_address": 0xD0, "source_address": 0xC2}, - rx_functional={"can_id": 0x18CD7186, "address_extension": 0x05, "target_address": 0x71, "source_address": 0x86}, + tx_physical={"can_id": 0x18CED0C2, "address_extension": 0x52, "target_address": 0xD0, "source_address": 0xC2}, + rx_functional={"can_id": 0x18CD7186, "address_extension": 0xFF, "target_address": 0x71, "source_address": 0x86}, tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), 0x18CEC2D0, [0x52, 0x3E]), ]) def test_is_input_packet__physical(self, addressing_information, frame_can_id, frame_data): @@ -731,10 +731,10 @@ def test_is_input_packet__physical(self, addressing_information, frame_can_id, f assert can_segmenter.is_input_packet(can_id=frame_can_id, data=frame_data) is AddressingType.PHYSICAL @pytest.mark.parametrize("addressing_information, frame_can_id, frame_data", [ - (Normal11BitCanAddressingInformation(rx_physical={"can_id": 0x611}, - tx_physical={"can_id": 0x612}, - rx_functional={"can_id": 0x6FE}, - tx_functional={"can_id": 0x6FF}), 0x6FE, [0x10, 0x01]), + (NormalCanAddressingInformation(rx_physical={"can_id": 0x611}, + tx_physical={"can_id": 0x612}, + rx_functional={"can_id": 0x6FE}, + tx_functional={"can_id": 0x6FF}), 0x6FE, [0x10, 0x01]), (NormalFixedCanAddressingInformation(rx_physical={"can_id": 0x18DA1234, "target_address": 0x12, "source_address": 0x34}, tx_physical={"can_id": 0x18DA3412, "target_address": 0x34, "source_address": 0x12}, rx_functional={"can_id": 0x18DBF0E1, "target_address": 0xF0, "source_address": 0xE1}, @@ -744,23 +744,23 @@ def test_is_input_packet__physical(self, addressing_information, frame_can_id, f rx_functional={"can_id": 0xFEDCBA, "target_address": 0xBB}, tx_functional={"can_id": 0xFEDCBA, "target_address": 0x12}), 0xFEDCBA, [0xBB, *range(63)]), (Mixed11BitCanAddressingInformation(rx_physical={"can_id": 0x645, "address_extension": 0x01}, - tx_physical={"can_id": 0x646, "address_extension": 0xFE}, + tx_physical={"can_id": 0x646, "address_extension": 0x01}, rx_functional={"can_id": 0x6DE, "address_extension": 0x05}, - tx_functional={"can_id": 0x6DF, "address_extension": 0xFF}), 0x6DE, [0x05, 0x3E]), + tx_functional={"can_id": 0x6DF, "address_extension": 0x05}), 0x6DE, [0x05, 0x3E]), (Mixed29BitCanAddressingInformation(rx_physical={"can_id": 0x18CEC2D0, "address_extension": 0x52, "target_address": 0xC2, "source_address": 0xD0}, - tx_physical={"can_id": 0x18CED0C2, "address_extension": 0xD8, "target_address": 0xD0, "source_address": 0xC2}, - rx_functional={"can_id": 0x18CD7186, "address_extension": 0x05, "target_address": 0x71, "source_address": 0x86}, - tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), 0x18CD7186, [0x05, 0x3E]), + tx_physical={"can_id": 0x18CED0C2, "address_extension": 0x52, "target_address": 0xD0, "source_address": 0xC2}, + rx_functional={"can_id": 0x18CD7186, "address_extension": 0xFF, "target_address": 0x71, "source_address": 0x86}, + tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), 0x18CD7186, [0xFF, 0x02, 0x3E, 0x00]), ]) def test_is_input_packet__functional(self, addressing_information, frame_can_id, frame_data): can_segmenter = CanSegmenter(addressing_information=addressing_information) assert can_segmenter.is_input_packet(can_id=frame_can_id, data=frame_data) is AddressingType.FUNCTIONAL @pytest.mark.parametrize("addressing_information, frame_can_id, frame_data", [ - (Normal11BitCanAddressingInformation(rx_physical={"can_id": 0x611}, - tx_physical={"can_id": 0x612}, - rx_functional={"can_id": 0x6FE}, - tx_functional={"can_id": 0x6FF}), 0x6FF, [0x10, 0x01]), + (NormalCanAddressingInformation(rx_physical={"can_id": 0x611}, + tx_physical={"can_id": 0x612}, + rx_functional={"can_id": 0x6FE}, + tx_functional={"can_id": 0x6FF}), 0x6FF, [0x10, 0x01]), (NormalFixedCanAddressingInformation(rx_physical={"can_id": 0x18DA1234, "target_address": 0x12, "source_address": 0x34}, tx_physical={"can_id": 0x18DA3412, "target_address": 0x34, "source_address": 0x12}, rx_functional={"can_id": 0x18DBF0E1, "target_address": 0xF0, "source_address": 0xE1}, @@ -770,23 +770,23 @@ def test_is_input_packet__functional(self, addressing_information, frame_can_id, rx_functional={"can_id": 0xFEDCBA, "target_address": 0xBB}, tx_functional={"can_id": 0xFEDCBA, "target_address": 0x12}), 0xFEDCBA, [0xF0, *range(63)]), (Mixed11BitCanAddressingInformation(rx_physical={"can_id": 0x645, "address_extension": 0x01}, - tx_physical={"can_id": 0x646, "address_extension": 0xFE}, + tx_physical={"can_id": 0x646, "address_extension": 0x01}, rx_functional={"can_id": 0x6DE, "address_extension": 0x05}, - tx_functional={"can_id": 0x6DF, "address_extension": 0xFF}), 0x646, [0xFE, 0x3E]), + tx_functional={"can_id": 0x6DF, "address_extension": 0x05}), 0x646, [0xFE, 0x3E]), (Mixed29BitCanAddressingInformation(rx_physical={"can_id": 0x18CEC2D0, "address_extension": 0x52, "target_address": 0xC2, "source_address": 0xD0}, - tx_physical={"can_id": 0x18CED0C2, "address_extension": 0xD8, "target_address": 0xD0, "source_address": 0xC2}, - rx_functional={"can_id": 0x18CD7186, "address_extension": 0x05, "target_address": 0x71, "source_address": 0x86}, - tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), 0x18CD7186, [0x52, 0x3E]), + tx_physical={"can_id": 0x18CED0C2, "address_extension": 0x52, "target_address": 0xD0, "source_address": 0xC2}, + rx_functional={"can_id": 0x18CD7186, "address_extension": 0xFF, "target_address": 0x71, "source_address": 0x86}, + tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), 0x18CEC2D0, [0xFF, 0x3E]), ]) def test_is_input_packet__false(self, addressing_information, frame_can_id, frame_data): can_segmenter = CanSegmenter(addressing_information=addressing_information) assert can_segmenter.is_input_packet(can_id=frame_can_id, data=frame_data) is None @pytest.mark.parametrize("addressing_information", [ - Normal11BitCanAddressingInformation(rx_physical={"can_id": 0x611}, - tx_physical={"can_id": 0x612}, - rx_functional={"can_id": 0x6FE}, - tx_functional={"can_id": 0x6FF}), + NormalCanAddressingInformation(rx_physical={"can_id": 0x611}, + tx_physical={"can_id": 0x612}, + rx_functional={"can_id": 0x6FE}, + tx_functional={"can_id": 0x6FF}), NormalFixedCanAddressingInformation(rx_physical={"can_id": 0x18DA1234, "target_address": 0x12, "source_address": 0x34}, tx_physical={"can_id": 0x18DA3412, "target_address": 0x34, "source_address": 0x12}, rx_functional={"can_id": 0x18DBF0E1, "target_address": 0xF0, "source_address": 0xE1}, @@ -796,12 +796,12 @@ def test_is_input_packet__false(self, addressing_information, frame_can_id, fram rx_functional={"can_id": 0xFEDCBA, "target_address": 0xBB}, tx_functional={"can_id": 0xFEDCBA, "target_address": 0x12}), Mixed11BitCanAddressingInformation(rx_physical={"can_id": 0x645, "address_extension": 0x01}, - tx_physical={"can_id": 0x646, "address_extension": 0xFE}, + tx_physical={"can_id": 0x646, "address_extension": 0x01}, rx_functional={"can_id": 0x6DE, "address_extension": 0x05}, - tx_functional={"can_id": 0x6DF, "address_extension": 0xFF}), + tx_functional={"can_id": 0x6DF, "address_extension": 0x05}), Mixed29BitCanAddressingInformation(rx_physical={"can_id": 0x18CEC2D0, "address_extension": 0x52, "target_address": 0xC2, "source_address": 0xD0}, - tx_physical={"can_id": 0x18CED0C2, "address_extension": 0xD8, "target_address": 0xD0, "source_address": 0xC2}, - rx_functional={"can_id": 0x18CD7186, "address_extension": 0x05, "target_address": 0x71, "source_address": 0x86}, + tx_physical={"can_id": 0x18CED0C2, "address_extension": 0x52, "target_address": 0xD0, "source_address": 0xC2}, + rx_functional={"can_id": 0x18CD7186, "address_extension": 0xFF, "target_address": 0x71, "source_address": 0x86}, tx_functional={"can_id": 0x18CD8671, "address_extension": 0xFF}), ]) @pytest.mark.parametrize("flow_Status, block_size, st_min", [ diff --git a/tests/software_tests/transport_interface/can/__init__.py b/tests/software_tests/transport_interface/can/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/software_tests/transport_interface/can_transport_interface/test_common.py b/tests/software_tests/transport_interface/can/test_common.py similarity index 99% rename from tests/software_tests/transport_interface/can_transport_interface/test_common.py rename to tests/software_tests/transport_interface/can/test_common.py index e2071244..1749fe07 100644 --- a/tests/software_tests/transport_interface/can_transport_interface/test_common.py +++ b/tests/software_tests/transport_interface/can/test_common.py @@ -4,7 +4,7 @@ from mock import MagicMock, Mock, patch from uds.packet import CanPacketRecord -from uds.transport_interface.can_transport_interface.common import ( +from uds.transport_interface.can.common import ( AbstractCanAddressingInformation, AbstractCanTransportInterface, AbstractFlowControlParametersGenerator, @@ -13,7 +13,7 @@ UdsMessageRecord, ) -SCRIPT_LOCATION = "uds.transport_interface.can_transport_interface.common" +SCRIPT_LOCATION = "uds.transport_interface.can.common" class TestAbstractCanTransportInterface: diff --git a/tests/software_tests/transport_interface/can_transport_interface/test_python_can.py b/tests/software_tests/transport_interface/can/test_python_can.py similarity index 99% rename from tests/software_tests/transport_interface/can_transport_interface/test_python_can.py rename to tests/software_tests/transport_interface/can/test_python_can.py index f5884f88..19c48dbc 100644 --- a/tests/software_tests/transport_interface/can_transport_interface/test_python_can.py +++ b/tests/software_tests/transport_interface/can/test_python_can.py @@ -5,7 +5,7 @@ from uds.can import CanAddressingFormat, CanAddressingInformation from uds.transmission_attributes import AddressingType -from uds.transport_interface.can_transport_interface.python_can import ( +from uds.transport_interface.can.python_can import ( AbstractCanTransportInterface, BusABC, CanFlowStatus, @@ -17,7 +17,7 @@ UdsMessage, ) -SCRIPT_LOCATION = "uds.transport_interface.can_transport_interface.python_can" +SCRIPT_LOCATION = "uds.transport_interface.can.python_can" class TestPyCanTransportInterface: @@ -1693,7 +1693,7 @@ class TestPyCanTransportInterfaceIntegration: { "can_bus_manager": Mock(spec=BusABC), "addressing_information": CanAddressingInformation( - addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, rx_physical={"can_id": 0x641}, tx_physical={"can_id": 0x642}, rx_functional={"can_id": 0x6FE}, diff --git a/tests/system_tests/transport_interface/can_transport_interface/test_python_can.py b/tests/system_tests/transport_interface/can_transport_interface/test_python_can.py index d87a01d3..4616a901 100644 --- a/tests/system_tests/transport_interface/can_transport_interface/test_python_can.py +++ b/tests/system_tests/transport_interface/can_transport_interface/test_python_can.py @@ -46,7 +46,7 @@ def teardown_class(self): @pytest.mark.parametrize("packet_type, addressing_type, addressing_information, packet_type_specific_kwargs", [ (CanPacketType.SINGLE_FRAME, AddressingType.FUNCTIONAL, - CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -150,7 +150,7 @@ def test_send_packet(self, packet_type, addressing_type, addressing_information, @pytest.mark.parametrize("addressing_type, addressing_information, frame", [ (AddressingType.PHYSICAL, - CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -229,7 +229,7 @@ def test_receive_packet__timeout(self, addressing_information, addressing_type, sleep((send_after - timeout) * 2 / 1000.) @pytest.mark.parametrize("addressing_information, frame", [ - (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -305,7 +305,7 @@ def test_receive_packet__physical(self, addressing_information, frame, timeout, # assert datetime_before_receive < packet_record.transmission_time < datetime_after_receive @pytest.mark.parametrize("addressing_information, frame", [ - (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -384,7 +384,7 @@ def test_receive_packet__functional(self, addressing_information, frame, timeout @pytest.mark.parametrize("packet_type, addressing_type, addressing_information, packet_type_specific_kwargs", [ (CanPacketType.SINGLE_FRAME, AddressingType.FUNCTIONAL, - CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -490,7 +490,7 @@ async def test_async_send_packet(self, packet_type, addressing_type, addressing_ @pytest.mark.parametrize("addressing_type, addressing_information, frame", [ (AddressingType.PHYSICAL, - CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -551,7 +551,7 @@ async def _send_frame(): sleep(self.DELAY_AFTER_RECEIVING_FRAME / 1000.) @pytest.mark.parametrize("addressing_information, frame", [ - (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -635,7 +635,7 @@ async def _send_frame(): # assert datetime_before_receive < packet_record.transmission_time < datetime_after_receive @pytest.mark.parametrize("addressing_information, frame", [ - (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + (CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, diff --git a/tests/system_tests/transport_interface/conftest.py b/tests/system_tests/transport_interface/conftest.py index 86af748c..c9f1a443 100644 --- a/tests/system_tests/transport_interface/conftest.py +++ b/tests/system_tests/transport_interface/conftest.py @@ -9,7 +9,7 @@ @fixture def example_addressing_information(): """Example Addressing Information of a CAN Node.""" - return CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + return CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x611}, rx_physical={"can_id": 0x612}, tx_functional={"can_id": 0x6FF}, @@ -25,7 +25,7 @@ def example_addressing_information_2nd_node(): Values of example_addressing_information and example_addressing_information_2nd_node are compatible, so these two CAN nodes can communicate with each other over physical and functional addressing. """ - return CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + return CanAddressingInformation(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, tx_physical={"can_id": 0x612}, rx_physical={"can_id": 0x611}, tx_functional={"can_id": 0x6FE}, diff --git a/uds/can/__init__.py b/uds/can/__init__.py index bc6dfd97..1d929637 100644 --- a/uds/can/__init__.py +++ b/uds/can/__init__.py @@ -31,5 +31,5 @@ ) from .frame_fields import DEFAULT_FILLER_BYTE, CanDlcHandler, CanIdHandler from .mixed_addressing_information import Mixed11BitCanAddressingInformation, Mixed29BitCanAddressingInformation -from .normal_addressing_information import Normal11BitCanAddressingInformation, NormalFixedCanAddressingInformation +from .normal_addressing_information import NormalCanAddressingInformation, NormalFixedCanAddressingInformation from .single_frame import CanSingleFrameHandler diff --git a/uds/can/abstract_addressing_information.py b/uds/can/abstract_addressing_information.py index 46020f10..a6be0e97 100644 --- a/uds/can/abstract_addressing_information.py +++ b/uds/can/abstract_addressing_information.py @@ -67,6 +67,10 @@ def __init__(self, self.tx_packets_physical_ai = tx_physical # type: ignore self.rx_packets_functional_ai = rx_functional # type: ignore self.tx_packets_functional_ai = tx_functional # type: ignore + self._validate_node_ai(rx_packets_physical_ai=self.rx_packets_physical_ai, + tx_packets_physical_ai=self.tx_packets_physical_ai, + rx_packets_functional_ai=self.rx_packets_functional_ai, + tx_packets_functional_ai=self.tx_packets_functional_ai) @property @abstractmethod @@ -156,3 +160,24 @@ def validate_packet_ai(cls, :return: Normalized dictionary with the provided information. """ + + @staticmethod + @abstractmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ diff --git a/uds/can/addressing_format.py b/uds/can/addressing_format.py index 49516de8..e788177f 100644 --- a/uds/can/addressing_format.py +++ b/uds/can/addressing_format.py @@ -16,17 +16,17 @@ class CanAddressingFormat(ValidatedEnum, StrEnum): :ref:`Network Address Information (N_AI) ` is provided. """ - NORMAL_11BIT_ADDRESSING: "CanAddressingFormat" = "Normal 11-bit Addressing" # type: ignore - """:ref:`Normal addressing ` format that uses 11-bit CAN Identifiers.""" + NORMAL_ADDRESSING: "CanAddressingFormat" = "Normal Addressing" # type: ignore + """:ref:`Normal addressing ` format.""" NORMAL_FIXED_ADDRESSING: "CanAddressingFormat" = "Normal Fixed Addressing" # type: ignore """:ref:`Normal fixed addressing ` format. - It is a subformat of :ref:`Normal addressing ` which uses 29-bit + It is a sub-format of :ref:`Normal addressing ` which uses 29-bit CAN Identifiers only.""" EXTENDED_ADDRESSING: "CanAddressingFormat" = "Extended Addressing" # type: ignore """:ref:`Extended addressing ` format.""" MIXED_11BIT_ADDRESSING: "CanAddressingFormat" = "Mixed 11-bit Addressing" # type: ignore """:ref:`Mixed addressing with 11-bit CAN ID ` format. - It is a subformat of :ref:`mixed addressing `.""" + It is a sub-format of :ref:`mixed addressing `.""" MIXED_29BIT_ADDRESSING: "CanAddressingFormat" = "Mixed 29-bit Addressing" # type: ignore """:ref:`Mixed addressing with 29-bit CAN ID ` format. - It is a subformat of :ref:`mixed addressing `.""" + It is a sub-format of :ref:`mixed addressing `.""" diff --git a/uds/can/addressing_information.py b/uds/can/addressing_information.py index c07082d1..688bae3a 100644 --- a/uds/can/addressing_information.py +++ b/uds/can/addressing_information.py @@ -22,14 +22,14 @@ from .extended_addressing_information import ExtendedCanAddressingInformation from .frame_fields import CanIdHandler from .mixed_addressing_information import Mixed11BitCanAddressingInformation, Mixed29BitCanAddressingInformation -from .normal_addressing_information import Normal11BitCanAddressingInformation, NormalFixedCanAddressingInformation +from .normal_addressing_information import NormalCanAddressingInformation, NormalFixedCanAddressingInformation class CanAddressingInformation: """CAN Entity (either server or client) Addressing Information.""" ADDRESSING_INFORMATION_MAPPING: Dict[CanAddressingFormat, Type[AbstractCanAddressingInformation]] = { - CanAddressingFormat.NORMAL_11BIT_ADDRESSING: Normal11BitCanAddressingInformation, + CanAddressingFormat.NORMAL_ADDRESSING: NormalCanAddressingInformation, CanAddressingFormat.NORMAL_FIXED_ADDRESSING: NormalFixedCanAddressingInformation, CanAddressingFormat.EXTENDED_ADDRESSING: ExtendedCanAddressingInformation, CanAddressingFormat.MIXED_11BIT_ADDRESSING: Mixed11BitCanAddressingInformation, @@ -170,7 +170,7 @@ def decode_ai_data_bytes(cls, """ cls.validate_ai_data_bytes(addressing_format=addressing_format, ai_data_bytes=ai_data_bytes) - if addressing_format in {CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + if addressing_format in {CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.NORMAL_FIXED_ADDRESSING}: return cls.DataBytesAIParamsAlias() if addressing_format == CanAddressingFormat.EXTENDED_ADDRESSING: @@ -199,7 +199,7 @@ def encode_ai_data_bytes(cls, :return: List of data bytes that carry Addressing Information in CAN frame Data field. """ CanAddressingFormat.validate_member(addressing_format) - if addressing_format in (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + if addressing_format in (CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.NORMAL_FIXED_ADDRESSING): return [] if addressing_format == CanAddressingFormat.EXTENDED_ADDRESSING: diff --git a/uds/can/extended_addressing_information.py b/uds/can/extended_addressing_information.py index 070277db..f6776c2f 100644 --- a/uds/can/extended_addressing_information.py +++ b/uds/can/extended_addressing_information.py @@ -51,11 +51,37 @@ def validate_packet_ai(cls, CanIdHandler.validate_can_id(can_id) # type: ignore validate_raw_byte(target_address) # type: ignore if not CanIdHandler.is_extended_addressed_can_id(can_id): # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with " - f"Extended Addressing Format. Actual value: {can_id}") + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with " + "Extended Addressing Format.") return PacketAIParamsAlias(addressing_format=CanAddressingFormat.EXTENDED_ADDRESSING, addressing_type=addressing_type, can_id=can_id, # type: ignore target_address=target_address, source_address=source_address, address_extension=address_extension) + + @staticmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ + if len({(rx_packets_physical_ai["can_id"], rx_packets_physical_ai["target_address"]), + (tx_packets_physical_ai["can_id"], tx_packets_physical_ai["target_address"]), + (rx_packets_functional_ai["can_id"], rx_packets_functional_ai["target_address"]), + (tx_packets_functional_ai["can_id"], tx_packets_functional_ai["target_address"])}) != 4: + raise InconsistentArgumentsError("Combination of CAN ID and Target Address for incoming and outgoing " + "CAN packets must be unique") diff --git a/uds/can/first_frame.py b/uds/can/first_frame.py index df405641..80a82e5e 100644 --- a/uds/can/first_frame.py +++ b/uds/can/first_frame.py @@ -79,8 +79,7 @@ def create_valid_frame_data(cls, *, frame_length = CanDlcHandler.decode_dlc(dlc) if len(ff_data_bytes) != frame_length: raise InconsistentArgumentsError("Provided value of `payload` contains incorrect number of bytes to fit " - f"them into a valid CAN Frame. You can Use {cls.get_payload_size} to get " - f"the expected value.") + "them into a valid CAN Frame.") return ff_data_bytes @classmethod @@ -124,8 +123,7 @@ def create_any_frame_data(cls, *, frame_length = CanDlcHandler.decode_dlc(dlc) if len(ff_data_bytes) != frame_length: raise InconsistentArgumentsError("Provided value of `payload` contains incorrect number of bytes to fit " - f"them into a valid CAN Frame. You can Use {cls.get_payload_size} to get " - f"the expected value.") + "them into a valid CAN Frame.") return ff_data_bytes @classmethod @@ -224,8 +222,7 @@ def validate_frame_data(cls, addressing_format: CanAddressingFormat, raw_frame_d """ validate_raw_bytes(raw_frame_data) if not cls.is_first_frame(addressing_format=addressing_format, raw_frame_data=raw_frame_data): - raise ValueError(f"Provided `raw_frame_data` value does not carry a First Frame packet. " - f"Actual values: addressing_format={addressing_format}, raw_frame_data={raw_frame_data}") + raise ValueError("Provided `raw_frame_data` value does not carry a First Frame packet.") ff_dl = cls.decode_ff_dl(addressing_format=addressing_format, raw_frame_data=raw_frame_data) ff_dl_data_bytes = cls.__extract_ff_dl_data_bytes(addressing_format=addressing_format, raw_frame_data=raw_frame_data) @@ -263,7 +260,7 @@ def validate_ff_dl(cls, number of payload bytes represented by FF_DL value. """ if not isinstance(ff_dl, int): - raise TypeError(f"Provided value of First Frame Data Length is not integer. Actual type: {type(ff_dl)}") + raise TypeError("Provided value of First Frame Data Length is not int type.") if not 0 <= ff_dl <= cls.MAX_LONG_FF_DL_VALUE: raise ValueError(f"Provided value of First Frame Data Length is out of range. " f"Expected: 0 <= ff_dl <= {cls.MAX_LONG_FF_DL_VALUE}. Actual value: {ff_dl}") diff --git a/uds/can/frame_fields.py b/uds/can/frame_fields.py index a2a47d77..3126df0a 100644 --- a/uds/can/frame_fields.py +++ b/uds/can/frame_fields.py @@ -43,14 +43,24 @@ class CanIdHandler: MAX_EXTENDED_VALUE: int = (1 << 29) - 1 """Maximum value of Extended (29-bit) CAN ID.""" - NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET: int = 0x18DA0000 - """Minimum value of physically addressed CAN ID in Normal Fixed Addressing format.""" - NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET: int = 0x18DB0000 - """Minimum value of functionally addressed CAN ID in Normal Fixed Addressing format.""" - MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET: int = 0x18CE0000 - """Minimum value of physically addressed CAN ID in Mixed 29-bit Addressing format.""" - MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET: int = 0x18CD0000 - """Minimum value of functionally addressed CAN ID in Mixed 29-bit Addressing format.""" + ADDRESSING_MASK: int = 0x3ff0000 + """CAN ID mask for bits enforced by SAE J1939 (Normal Fixed of Mixed 29bit addressing formats).""" + NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE: int = 0xDA0000 + """Masked value of physically addressed CAN ID in Normal Fixed Addressing format.""" + NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE: int = 0xDB0000 + """Masked value of functionally addressed CAN ID in Normal Fixed Addressing format.""" + MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE: int = 0xCE0000 + """Masked value of physically addressed CAN ID in Mixed 29-bit Addressing format.""" + MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE: int = 0xCD0000 + """Masked value of functionally addressed CAN ID in Mixed 29-bit Addressing format.""" + PRIORITY_BIT_OFFSET: int = 26 + """Bit offset of Priority parameter defined by SAE J1939.""" + DEFAULT_PRIORITY_VALUE: int = 0b110 + """Default value of Priority parameter defined by SAE J1939.""" + MIN_PRIORITY_VALUE: int = 0b000 + """Minimal value of Priority parameter defined by SAE J1939.""" + MAX_PRIORITY_VALUE: int = 0b111 + """Maximal value of Priority parameter defined by SAE J1939.""" ADDRESSING_TYPE_NAME: str = "addressing_type" """Name of :ref:`Addressing Type ` parameter in Addressing Information.""" @@ -75,7 +85,7 @@ def decode_can_id(cls, addressing_format: CanAddressingFormat, can_id: int) -> C information are system specific. For example, Addressing Type (even though it always depends on CAN ID value) will not be decoded when - either Normal 11bit, Extended or Mixed 11bit addressing format is used as the Addressing Type (in such case) + either Normal, Extended or Mixed 11bit addressing format is used as the Addressing Type (in such case) depends on system specific behaviour. :param addressing_format: Addressing format used. @@ -92,13 +102,13 @@ def decode_can_id(cls, addressing_format: CanAddressingFormat, can_id: int) -> C return cls.decode_normal_fixed_addressed_can_id(can_id) if addressing_format == CanAddressingFormat.MIXED_29BIT_ADDRESSING: return cls.decode_mixed_addressed_29bit_can_id(can_id) - if addressing_format in (CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + if addressing_format in (CanAddressingFormat.NORMAL_ADDRESSING, CanAddressingFormat.EXTENDED_ADDRESSING, CanAddressingFormat.MIXED_11BIT_ADDRESSING): return cls.CanIdAIAlias(addressing_type=None, target_address=None, source_address=None) # no addressing information can be decoded - raise NotImplementedError(f"Unknown addressing format value was provided: {addressing_format}") + raise NotImplementedError("Unhandled addressing type value was provided.") @classmethod def decode_normal_fixed_addressed_can_id(cls, can_id: int) -> CanIdAIAlias: @@ -116,21 +126,19 @@ def decode_normal_fixed_addressed_can_id(cls, can_id: int) -> CanIdAIAlias: """ cls.validate_can_id(can_id) if not cls.is_normal_fixed_addressed_can_id(can_id): - raise ValueError(f"Provided CAN ID value is out of range. " - f"Expected CAN ID using Normal Fixed Addressing format. Actual value: {can_id}") + raise ValueError("Provided CAN ID value is out of range.") target_address = (can_id >> 8) & 0xFF source_address = can_id & 0xFF - can_id_offset = can_id & (~0xFFFF) # value with Target Address and Source Address information erased - if can_id_offset == cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET: + can_id_masked_value = can_id & cls.ADDRESSING_MASK + if can_id_masked_value == cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE: return cls.CanIdAIAlias(addressing_type=AddressingType.PHYSICAL, target_address=target_address, source_address=source_address) - if can_id_offset == cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET: + if can_id_masked_value == cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE: return cls.CanIdAIAlias(addressing_type=AddressingType.FUNCTIONAL, target_address=target_address, source_address=source_address) - raise NotImplementedError("CAN ID in Normal Fixed Addressing format was provided, but cannot be handled." - f"Actual value: {can_id}") + raise NotImplementedError("CAN ID in Normal Fixed Addressing format was provided, but cannot be handled.") @classmethod def decode_mixed_addressed_29bit_can_id(cls, can_id: int) -> CanIdAIAlias: @@ -148,33 +156,33 @@ def decode_mixed_addressed_29bit_can_id(cls, can_id: int) -> CanIdAIAlias: """ cls.validate_can_id(can_id) if not cls.is_mixed_29bit_addressed_can_id(can_id): - raise ValueError(f"Provided CAN ID value is out of range. " - f"Expected 29-bit CAN ID using Mixed Addressing format. Actual value: {can_id}") + raise ValueError("Provided CAN ID value is out of range.") target_address = (can_id >> 8) & 0xFF source_address = can_id & 0xFF - can_id_offset = can_id & (~0xFFFF) # value with Target Address and Source Address information erased - if can_id_offset == cls.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET: + can_id_masked_value = can_id & cls.ADDRESSING_MASK + if can_id_masked_value == cls.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE: return cls.CanIdAIAlias(addressing_type=AddressingType.PHYSICAL, target_address=target_address, source_address=source_address) - if can_id_offset == cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET: + if can_id_masked_value == cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE: return cls.CanIdAIAlias(addressing_type=AddressingType.FUNCTIONAL, target_address=target_address, source_address=source_address) - raise NotImplementedError("CAN ID in Normal Fixed Addressing format was provided, but cannot be handled." - f"Actual value: {can_id}") + raise NotImplementedError("CAN ID in Normal Fixed Addressing format was provided, but cannot be handled.") @classmethod def encode_normal_fixed_addressed_can_id(cls, addressing_type: AddressingType, target_address: int, - source_address: int) -> int: + source_address: int, + priority: int = DEFAULT_PRIORITY_VALUE) -> int: """ Generate CAN ID value for Normal Fixed CAN Addressing format. :param addressing_type: Addressing type used. - :param target_address: Target address value to use. - :param source_address: Source address value to use. + :param target_address: Target Address value to use. + :param source_address: Source Address value to use. + :param priority: Priority parameter value to use. :raise NotImplementedError: There is missing implementation for the provided Addressing Type. Please create an issue in our `Issues Tracking System `_ @@ -186,23 +194,31 @@ def encode_normal_fixed_addressed_can_id(cls, AddressingType.validate_member(addressing_type) validate_raw_byte(target_address) validate_raw_byte(source_address) + cls.validate_priority(priority) + priority_value = priority << cls.PRIORITY_BIT_OFFSET + target_address_value = target_address << 8 + source_address_value = source_address if addressing_type == AddressingType.PHYSICAL: - return cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + (target_address << 8) + source_address + return (priority_value + cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + target_address_value + + source_address_value) if addressing_type == AddressingType.FUNCTIONAL: - return cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + (target_address << 8) + source_address - raise NotImplementedError(f"Unknown addressing type value was provided: {addressing_type}") + return (priority_value + cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + target_address_value + + source_address_value) + raise NotImplementedError("Unhandled addressing type value was provided.") @classmethod def encode_mixed_addressed_29bit_can_id(cls, addressing_type: AddressingType, target_address: int, - source_address: int) -> int: + source_address: int, + priority: int = DEFAULT_PRIORITY_VALUE) -> int: """ Generate CAN ID value for Mixed 29-bit CAN Addressing format. :param addressing_type: Addressing type used. - :param target_address: Target address value to use. - :param source_address: Source address value to use. + :param target_address: Target Address value to use. + :param source_address: Source Address value to use. + :param priority: Priority parameter value to use. :raise NotImplementedError: There is missing implementation for the provided Addressing Type. Please create an issue in our `Issues Tracking System `_ @@ -214,11 +230,17 @@ def encode_mixed_addressed_29bit_can_id(cls, AddressingType.validate_member(addressing_type) validate_raw_byte(target_address) validate_raw_byte(source_address) + cls.validate_priority(priority) + priority_value = priority << cls.PRIORITY_BIT_OFFSET + target_address_value = target_address << 8 + source_address_value = source_address if addressing_type == AddressingType.PHYSICAL: - return cls.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + (target_address << 8) + source_address + return (priority_value + cls.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + target_address_value + + source_address_value) if addressing_type == AddressingType.FUNCTIONAL: - return cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + (target_address << 8) + source_address - raise NotImplementedError(f"Unknown addressing type value was provided: {addressing_type}") + return (priority_value + cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + target_address_value + + source_address_value) + raise NotImplementedError("Unhandled addressing type value was provided.") @classmethod def is_compatible_can_id(cls, @@ -241,8 +263,8 @@ def is_compatible_can_id(cls, """ cls.validate_can_id(can_id) CanAddressingFormat.validate_member(addressing_format) - if addressing_format == CanAddressingFormat.NORMAL_11BIT_ADDRESSING: - return cls.is_normal_11bit_addressed_can_id(can_id=can_id) + if addressing_format == CanAddressingFormat.NORMAL_ADDRESSING: + return cls.is_normal_addressed_can_id(can_id=can_id) if addressing_format == CanAddressingFormat.NORMAL_FIXED_ADDRESSING: return cls.is_normal_fixed_addressed_can_id(can_id=can_id, addressing_type=addressing_type) if addressing_format == CanAddressingFormat.EXTENDED_ADDRESSING: @@ -251,18 +273,18 @@ def is_compatible_can_id(cls, return cls.is_mixed_11bit_addressed_can_id(can_id=can_id) if addressing_format == CanAddressingFormat.MIXED_29BIT_ADDRESSING: return cls.is_mixed_29bit_addressed_can_id(can_id=can_id, addressing_type=addressing_type) - raise NotImplementedError(f"Missing implementation for: {addressing_format}") + raise NotImplementedError("Unhandled addressing type value was provided.") @classmethod - def is_normal_11bit_addressed_can_id(cls, can_id: int) -> bool: + def is_normal_addressed_can_id(cls, can_id: int) -> bool: """ - Check if the provided value of CAN ID is compatible with Normal 11-bit Addressing format. + Check if the provided value of CAN ID is compatible with Normal Addressing format. :param can_id: Value to check. :return: True if value is a valid CAN ID for Normal 11-bit Addressing format, False otherwise. """ - return cls.is_standard_can_id(can_id) + return cls.is_can_id(can_id) @classmethod def is_normal_fixed_addressed_can_id(cls, @@ -279,14 +301,13 @@ def is_normal_fixed_addressed_can_id(cls, Addressing Type, False otherwise. """ if addressing_type is not None: - AddressingType.validate_member(addressing_type) - if (addressing_type is None or addressing_type == AddressingType.PHYSICAL) \ - and cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET <= can_id \ - <= cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF: + addressing_type = AddressingType.validate_member(addressing_type) + masked_can_id = can_id & cls.ADDRESSING_MASK + if (masked_can_id == cls.NORMAL_FIXED_PHYSICAL_ADDRESSING_MASKED_VALUE + and addressing_type in {None, AddressingType.PHYSICAL}): return True - if (addressing_type is None or addressing_type == AddressingType.FUNCTIONAL) \ - and cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET <= can_id \ - <= cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF: + if (masked_can_id == cls.NORMAL_FIXED_FUNCTIONAL_ADDRESSING_MASKED_VALUE + and addressing_type in {None, AddressingType.FUNCTIONAL}): return True return False @@ -327,14 +348,13 @@ def is_mixed_29bit_addressed_can_id(cls, Addressing Type, False otherwise. """ if addressing_type is not None: - AddressingType.validate_member(addressing_type) - if (addressing_type is None or addressing_type == AddressingType.PHYSICAL) \ - and cls.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET <= can_id \ - <= cls.MIXED_29BIT_PHYSICAL_ADDRESSING_OFFSET + 0xFFFF: + addressing_type = AddressingType.validate_member(addressing_type) + masked_can_id = can_id & cls.ADDRESSING_MASK + if (masked_can_id == cls.MIXED_29BIT_PHYSICAL_ADDRESSING_MASKED_VALUE + and addressing_type in {None, AddressingType.PHYSICAL}): return True - if (addressing_type is None or addressing_type == AddressingType.FUNCTIONAL) \ - and cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET <= can_id \ - <= cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_OFFSET + 0xFFFF: + if (masked_can_id == cls.MIXED_29BIT_FUNCTIONAL_ADDRESSING_MASKED_VALUE + and addressing_type in {None, AddressingType.FUNCTIONAL}): return True return False @@ -387,18 +407,31 @@ def validate_can_id(cls, value: int, extended_can_id: Optional[bool] = None) -> :raise ValueError: Provided value is out of CAN Identifier values range. """ if not isinstance(value, int): - raise TypeError(f"Provided value is not int type. Actual type: {type(value)}") + raise TypeError("Provided value is not int type.") if extended_can_id is None: if not cls.is_can_id(value): - raise ValueError(f"Provided value is out of CAN Identifier values range. Actual value: {value}") + raise ValueError("Provided value is out of CAN Identifier values range.") elif extended_can_id: if not cls.is_extended_can_id(value): - raise ValueError(f"Provided value is out of Extended (29-bit) CAN Identifier values range. " - f"Actual value: {value}") + raise ValueError("Provided value is out of Extended (29-bit) CAN Identifier values range.") else: if not cls.is_standard_can_id(value): - raise ValueError(f"Provided value is out of Standard (11-bit) CAN Identifier values range. " - f"Actual value: {value}") + raise ValueError("Provided value is out of Standard (11-bit) CAN Identifier values range.") + + @classmethod + def validate_priority(cls, value: int) -> None: + """ + Validate whether provided priority value is in line with SAE J1939 definition. + + :param value: Value to validate. + + :raise TypeError: Provided value is not int type. + :raise ValueError: Provided value is out of Priority values range. + """ + if not isinstance(value, int): + raise TypeError("Provided value is not int type.") + if not cls.MIN_PRIORITY_VALUE <= value <= cls.MAX_PRIORITY_VALUE: + raise ValueError("Provided value is not in Priority values range.") class CanDlcHandler: @@ -491,9 +524,9 @@ def validate_dlc(cls, value: int) -> None: :raise ValueError: Provided value is not a valid DLC value. """ if not isinstance(value, int): - raise TypeError(f"Provided value is not int type. Actual type: {type(value)}") + raise TypeError("Provided value is not int type.") if not cls.MIN_DLC_VALUE <= value <= cls.MAX_DLC_VALUE: - raise ValueError(f"Provided value is out of DLC values range. Actual value: {value}") + raise ValueError("Provided value is out of DLC values range.") @classmethod def validate_data_bytes_number(cls, value: int, exact_value: bool = True) -> None: @@ -511,10 +544,10 @@ def validate_data_bytes_number(cls, value: int, exact_value: bool = True) -> Non :raise ValueError: Provided value is not number of data bytes that matches the criteria. """ if not isinstance(value, int): - raise TypeError(f"Provided value is not int type. Actual type: {type(value)}") + raise TypeError("Provided value is not int type.") if exact_value: if cls.__DATA_BYTES_NUMBER_MAPPING.get(value, None) is None: - raise ValueError(f"Provided value is not a valid CAN Frame data bytes number. Actual value: {value}") + raise ValueError("Provided value is not a valid CAN Frame data bytes number.") else: if not cls.MIN_DATA_BYTES_NUMBER <= value <= cls.MAX_DATA_BYTES_NUMBER: - raise ValueError(f"Provided value is out of CAN Frame data bytes number range. Actual value: {value}") + raise ValueError("Provided value is out of CAN Frame data bytes number range.") diff --git a/uds/can/mixed_addressing_information.py b/uds/can/mixed_addressing_information.py index a13dd3b2..444eac5b 100644 --- a/uds/can/mixed_addressing_information.py +++ b/uds/can/mixed_addressing_information.py @@ -51,8 +51,8 @@ def validate_packet_ai(cls, CanIdHandler.validate_can_id(can_id) # type: ignore validate_raw_byte(address_extension) # type: ignore if not CanIdHandler.is_mixed_11bit_addressed_can_id(can_id): # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with " - f"Mixed 11-bit Addressing Format. Actual value: {can_id}") + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with " + "Mixed 11-bit Addressing Format.") return PacketAIParamsAlias(addressing_format=CanAddressingFormat.MIXED_11BIT_ADDRESSING, addressing_type=addressing_type, can_id=can_id, # type: ignore @@ -60,6 +60,38 @@ def validate_packet_ai(cls, source_address=source_address, address_extension=address_extension) + @staticmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ + if rx_packets_physical_ai["address_extension"] != tx_packets_physical_ai["address_extension"]: + raise InconsistentArgumentsError("Addressing Extension parameter must be the same for incoming and " + "outgoing physically addressed CAN packets.") + if rx_packets_functional_ai["address_extension"] != tx_packets_functional_ai["address_extension"]: + raise InconsistentArgumentsError("Addressing Extension parameter must be the same for incoming and " + "outgoing functionally addressed CAN packets.") + if len({(rx_packets_physical_ai["can_id"], rx_packets_physical_ai["address_extension"]), + (tx_packets_physical_ai["can_id"], tx_packets_physical_ai["address_extension"]), + (rx_packets_functional_ai["can_id"], rx_packets_functional_ai["address_extension"]), + (tx_packets_functional_ai["can_id"], tx_packets_functional_ai["address_extension"])}) != 4: + raise InconsistentArgumentsError("Combination of CAN ID and Target Address for incoming and outgoing " + "CAN packets must be unique") + class Mixed29BitCanAddressingInformation(AbstractCanAddressingInformation): """Addressing Information of CAN Entity (either server or client) that uses Mixed 29-bit Addressing format.""" @@ -97,10 +129,8 @@ def validate_packet_ai(cls, validate_raw_byte(address_extension) # type: ignore if can_id is None: if None in (target_address, source_address): - raise InconsistentArgumentsError(f"Values of target_address and source_address must be provided," - f"if can_id value is None for Mixed 29-bit Addressing Format. " - f"Actual values: " - f"target_address={target_address}, source_address={source_address}") + raise InconsistentArgumentsError("Values of target_address and source_address must be provided," + "if can_id value is None for Mixed 29-bit Addressing Format.") validate_raw_byte(target_address) # type: ignore validate_raw_byte(source_address) # type: ignore encoded_can_id = CanIdHandler.encode_mixed_addressed_29bit_can_id( @@ -115,17 +145,50 @@ def validate_packet_ai(cls, address_extension=address_extension) decoded_info = CanIdHandler.decode_mixed_addressed_29bit_can_id(can_id) if addressing_type != decoded_info[CanIdHandler.ADDRESSING_TYPE_NAME]: # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with Addressing Type." - f"Actual values: can_id={can_id}, addressing={addressing_type}") + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with Addressing Type.") if target_address not in (decoded_info[CanIdHandler.TARGET_ADDRESS_NAME], None): # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with Target Address." - f"Actual values: can_id={can_id}, target_address={target_address}") + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with Target Address.") if source_address not in (decoded_info[CanIdHandler.SOURCE_ADDRESS_NAME], None): # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with Source Address." - f"Actual values: can_id={can_id}, source_address={source_address}") + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with Source Address.") return PacketAIParamsAlias(addressing_format=CanAddressingFormat.MIXED_29BIT_ADDRESSING, addressing_type=addressing_type, can_id=can_id, target_address=decoded_info[CanIdHandler.TARGET_ADDRESS_NAME], # type: ignore source_address=decoded_info[CanIdHandler.SOURCE_ADDRESS_NAME], # type: ignore address_extension=address_extension) + + @staticmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ + if rx_packets_physical_ai["address_extension"] != tx_packets_physical_ai["address_extension"]: + raise InconsistentArgumentsError("Addressing Extension parameter must be the same for incoming and " + "outgoing physically addressed CAN packets.") + if rx_packets_functional_ai["address_extension"] != tx_packets_functional_ai["address_extension"]: + raise InconsistentArgumentsError("Addressing Extension parameter must be the same for incoming and " + "outgoing functionally addressed CAN packets.") + if (rx_packets_physical_ai["target_address"] != tx_packets_physical_ai["source_address"] + or rx_packets_physical_ai["source_address"] != tx_packets_physical_ai["target_address"]): + raise InconsistentArgumentsError("Target Address and Source Address for incoming physically addressed " + "CAN packets must equal Source Address and Target Address for outgoing " + "physically addressed CAN packets.") + if (rx_packets_functional_ai["target_address"] != tx_packets_functional_ai["source_address"] + or rx_packets_functional_ai["source_address"] != tx_packets_functional_ai["target_address"]): + raise InconsistentArgumentsError("Target Address and Source Address for incoming functionally addressed " + "CAN packets must equal Source Address and Target Address for outgoing " + "functionally addressed CAN packets.") diff --git a/uds/can/normal_addressing_information.py b/uds/can/normal_addressing_information.py index 6fac3501..493e75c8 100644 --- a/uds/can/normal_addressing_information.py +++ b/uds/can/normal_addressing_information.py @@ -1,6 +1,6 @@ """Implementation of Normal Addressing Information handlers.""" -__all__ = ["Normal11BitCanAddressingInformation", "NormalFixedCanAddressingInformation"] +__all__ = ["NormalCanAddressingInformation", "NormalFixedCanAddressingInformation"] from typing import Optional @@ -12,8 +12,8 @@ from .frame_fields import CanIdHandler -class Normal11BitCanAddressingInformation(AbstractCanAddressingInformation): - """Addressing Information of CAN Entity (either server or client) that uses Normal 11-bit Addressing format.""" +class NormalCanAddressingInformation(AbstractCanAddressingInformation): + """Addressing Information of CAN Entity (either server or client) that uses Normal Addressing format.""" AI_DATA_BYTES_NUMBER: int = 0 """Number of CAN Frame data bytes that are used to carry Addressing Information.""" @@ -21,7 +21,7 @@ class Normal11BitCanAddressingInformation(AbstractCanAddressingInformation): @property def addressing_format(self) -> CanAddressingFormat: """CAN Addressing format used.""" - return CanAddressingFormat.NORMAL_11BIT_ADDRESSING + return CanAddressingFormat.NORMAL_ADDRESSING @classmethod def validate_packet_ai(cls, @@ -31,7 +31,7 @@ def validate_packet_ai(cls, source_address: Optional[int] = None, address_extension: Optional[int] = None) -> PacketAIParamsAlias: """ - Validate Addressing Information parameters of a CAN packet that uses Normal 11-bit Addressing format. + Validate Addressing Information parameters of a CAN packet that uses Normal Addressing format. :param addressing_type: Addressing type to validate. :param can_id: CAN Identifier value to validate. @@ -46,19 +46,44 @@ def validate_packet_ai(cls, """ if (target_address, source_address, address_extension) != (None, None, None): raise UnusedArgumentError("Values of Target Address, Source Address and Address Extension are " - "not supported by Normal 11-bit Addressing format and all must be None.") + "not supported by Normal Addressing format and all must be None.") addressing_type = AddressingType.validate_member(addressing_type) CanIdHandler.validate_can_id(can_id) # type: ignore - if not CanIdHandler.is_normal_11bit_addressed_can_id(can_id): # type: ignore - raise InconsistentArgumentsError(f"Provided value of CAN ID is not compatible with " - f"Normal 11-bit Addressing Format. Actual value: {can_id}") - return PacketAIParamsAlias(addressing_format=CanAddressingFormat.NORMAL_11BIT_ADDRESSING, + if not CanIdHandler.is_normal_addressed_can_id(can_id): # type: ignore + raise InconsistentArgumentsError("Provided value of CAN ID is not compatible with " + "Normal Addressing Format.") + return PacketAIParamsAlias(addressing_format=CanAddressingFormat.NORMAL_ADDRESSING, addressing_type=addressing_type, can_id=can_id, # type: ignore target_address=target_address, source_address=source_address, address_extension=address_extension) + @staticmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ + if len({rx_packets_physical_ai["can_id"], + tx_packets_physical_ai["can_id"], + rx_packets_functional_ai["can_id"], + tx_packets_functional_ai["can_id"]}) != 4: + raise InconsistentArgumentsError("Values of CAN ID for incoming and outgoing CAN packets must be unique.") + class NormalFixedCanAddressingInformation(AbstractCanAddressingInformation): """Addressing Information of CAN Entity (either server or client) that uses Normal Fixed Addressing format.""" @@ -99,10 +124,8 @@ def validate_packet_ai(cls, addressing_type = AddressingType.validate_member(addressing_type) if can_id is None: if None in (target_address, source_address): - raise InconsistentArgumentsError(f"Values of target_address and source_address must be provided," - f"if can_id value is None for Normal Fixed Addressing Format. " - f"Actual values: " - f"target_address={target_address}, source_address={source_address}") + raise InconsistentArgumentsError("Values of target_address and source_address must be provided, " + "if can_id value is None for Normal Fixed Addressing Format.") validate_raw_byte(target_address) # type: ignore validate_raw_byte(source_address) # type: ignore encoded_can_id = CanIdHandler.encode_normal_fixed_addressed_can_id( @@ -131,3 +154,33 @@ def validate_packet_ai(cls, target_address=decoded_info[CanIdHandler.TARGET_ADDRESS_NAME], # type: ignore source_address=decoded_info[CanIdHandler.SOURCE_ADDRESS_NAME], # type: ignore address_extension=address_extension) + + @staticmethod + def _validate_node_ai(rx_packets_physical_ai: PacketAIParamsAlias, + tx_packets_physical_ai: PacketAIParamsAlias, + rx_packets_functional_ai: PacketAIParamsAlias, + tx_packets_functional_ai: PacketAIParamsAlias) -> None: + """ + Validate Node Addressing Information parameters. + + :param rx_packets_physical_ai: Addressing Information parameters of incoming physically addressed + CAN packets to validate. + :param tx_packets_physical_ai: Addressing Information parameters of outgoing physically addressed + CAN packets to validate. + :param rx_packets_functional_ai: Addressing Information parameters of incoming functionally addressed + CAN packets to validate. + :param tx_packets_functional_ai: Addressing Information parameters of outgoing functionally addressed + CAN packets to validate. + + :raise InconsistentArgumentsError: Provided values are not consistent with each other. + """ + if (rx_packets_physical_ai["target_address"] != tx_packets_physical_ai["source_address"] + or rx_packets_physical_ai["source_address"] != tx_packets_physical_ai["target_address"]): + raise InconsistentArgumentsError("Target Address and Source Address for incoming physically addressed " + "CAN packets must equal Source Address and Target Address for outgoing " + "physically addressed CAN packets.") + if (rx_packets_functional_ai["target_address"] != tx_packets_functional_ai["source_address"] + or rx_packets_functional_ai["source_address"] != tx_packets_functional_ai["target_address"]): + raise InconsistentArgumentsError("Target Address and Source Address for incoming functionally addressed " + "CAN packets must equal Source Address and Target Address for outgoing " + "functionally addressed CAN packets.") diff --git a/uds/packet/__init__.py b/uds/packet/__init__.py index 39306295..e14051d4 100644 --- a/uds/packet/__init__.py +++ b/uds/packet/__init__.py @@ -8,7 +8,6 @@ - storing historic information about packets that were either received or transmitted """ -from .abstract_can_packet_container import AbstractCanPacketContainer from .abstract_packet import ( AbstractUdsPacket, AbstractUdsPacketContainer, @@ -19,6 +18,4 @@ PacketsTuple, ) from .abstract_packet_type import AbstractUdsPacketType -from .can_packet import CanPacket -from .can_packet_record import CanPacketRecord -from .can_packet_type import CanPacketType +from .can import AbstractCanPacketContainer, CanPacket, CanPacketRecord, CanPacketType diff --git a/uds/packet/can/__init__.py b/uds/packet/can/__init__.py new file mode 100644 index 00000000..b8c39995 --- /dev/null +++ b/uds/packet/can/__init__.py @@ -0,0 +1,6 @@ +"""UDS packets implementation for CAN bus.""" + +from .abstract_can_container import AbstractCanPacketContainer +from .can_packet import CanPacket +from .can_packet_record import CanPacketRecord +from .can_packet_type import CanPacketType diff --git a/uds/packet/abstract_can_packet_container.py b/uds/packet/can/abstract_can_container.py similarity index 100% rename from uds/packet/abstract_can_packet_container.py rename to uds/packet/can/abstract_can_container.py diff --git a/uds/packet/can_packet.py b/uds/packet/can/can_packet.py similarity index 97% rename from uds/packet/can_packet.py rename to uds/packet/can/can_packet.py index 1ef74666..ac59f082 100644 --- a/uds/packet/can_packet.py +++ b/uds/packet/can/can_packet.py @@ -19,14 +19,14 @@ ExtendedCanAddressingInformation, Mixed11BitCanAddressingInformation, Mixed29BitCanAddressingInformation, - Normal11BitCanAddressingInformation, + NormalCanAddressingInformation, NormalFixedCanAddressingInformation, ) from uds.transmission_attributes import AddressingType from uds.utilities import AmbiguityError, RawBytesAlias, RawBytesTupleAlias, UnusedArgumentWarning -from .abstract_can_packet_container import AbstractCanPacketContainer -from .abstract_packet import AbstractUdsPacket +from ..abstract_packet import AbstractUdsPacket +from .abstract_can_container import AbstractCanPacketContainer from .can_packet_type import CanPacketType @@ -140,9 +140,9 @@ def set_address_information(self, *, with detailed description if you face this error. """ CanAddressingFormat.validate_member(addressing_format) - if addressing_format == CanAddressingFormat.NORMAL_11BIT_ADDRESSING: - self.set_address_information_normal_11bit(addressing_type=addressing_type, - can_id=can_id) # type: ignore + if addressing_format == CanAddressingFormat.NORMAL_ADDRESSING: + self.set_address_information_normal(addressing_type=addressing_type, + can_id=can_id) # type: ignore if (target_address, source_address, address_extension) != (None, None, None): warn(message=f"Unused arguments were provided to {CanPacket.set_address_information}. Expected: None." f"Actual values: target_address={target_address}, source_address={source_address}, " @@ -182,16 +182,16 @@ def set_address_information(self, *, else: raise NotImplementedError(f"Missing implementation for: {addressing_format}") - def set_address_information_normal_11bit(self, addressing_type: AddressingType, can_id: int) -> None: + def set_address_information_normal(self, addressing_type: AddressingType, can_id: int) -> None: """ - Change addressing information for this CAN packet to use Normal 11-bit Addressing format. + Change addressing information for this CAN packet to use Normal Addressing format. :param addressing_type: Addressing type for which this CAN packet is relevant. :param can_id: CAN Identifier value that is used by this packet. """ - Normal11BitCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, can_id=can_id) - self.__validate_unambiguous_ai_change(CanAddressingFormat.NORMAL_11BIT_ADDRESSING) - self.__addressing_format = CanAddressingFormat.NORMAL_11BIT_ADDRESSING + NormalCanAddressingInformation.validate_packet_ai(addressing_type=addressing_type, can_id=can_id) + self.__validate_unambiguous_ai_change(CanAddressingFormat.NORMAL_ADDRESSING) + self.__addressing_format = CanAddressingFormat.NORMAL_ADDRESSING self.__addressing_type = AddressingType(addressing_type) self.__can_id = can_id self.__target_address = None diff --git a/uds/packet/can_packet_record.py b/uds/packet/can/can_packet_record.py similarity index 98% rename from uds/packet/can_packet_record.py rename to uds/packet/can/can_packet_record.py index adf6265f..9a9d603e 100644 --- a/uds/packet/can_packet_record.py +++ b/uds/packet/can/can_packet_record.py @@ -16,8 +16,8 @@ from uds.transmission_attributes import AddressingType, TransmissionDirection from uds.utilities import InconsistentArgumentsError, RawBytesTupleAlias -from .abstract_can_packet_container import AbstractCanPacketContainer -from .abstract_packet import AbstractUdsPacketRecord +from ..abstract_packet import AbstractUdsPacketRecord +from .abstract_can_container import AbstractCanPacketContainer from .can_packet_type import CanPacketType CanFrameAlias = Union[PythonCanMessage] diff --git a/uds/packet/can_packet_type.py b/uds/packet/can/can_packet_type.py similarity index 96% rename from uds/packet/can_packet_type.py rename to uds/packet/can/can_packet_type.py index 20db7d14..d5b245bd 100644 --- a/uds/packet/can_packet_type.py +++ b/uds/packet/can/can_packet_type.py @@ -6,7 +6,7 @@ from uds.can import CanConsecutiveFrameHandler, CanFirstFrameHandler, CanFlowControlHandler, CanSingleFrameHandler -from .abstract_packet_type import AbstractUdsPacketType +from ..abstract_packet_type import AbstractUdsPacketType @unique diff --git a/uds/transport_interface/__init__.py b/uds/transport_interface/__init__.py index adcaba2f..9f3d66c8 100644 --- a/uds/transport_interface/__init__.py +++ b/uds/transport_interface/__init__.py @@ -10,4 +10,4 @@ """ from .abstract_transport_interface import AbstractTransportInterface -from .can_transport_interface import AbstractCanTransportInterface, PyCanTransportInterface +from .can import AbstractCanTransportInterface, PyCanTransportInterface diff --git a/uds/transport_interface/can_transport_interface/__init__.py b/uds/transport_interface/can/__init__.py similarity index 100% rename from uds/transport_interface/can_transport_interface/__init__.py rename to uds/transport_interface/can/__init__.py diff --git a/uds/transport_interface/can_transport_interface/common.py b/uds/transport_interface/can/common.py similarity index 95% rename from uds/transport_interface/can_transport_interface/common.py rename to uds/transport_interface/can/common.py index f3658927..c3c0c7d3 100644 --- a/uds/transport_interface/can_transport_interface/common.py +++ b/uds/transport_interface/can/common.py @@ -158,9 +158,8 @@ def n_as_measured(self) -> Optional[TimeMillisecondsAlias]: Get the last measured value of :ref:`N_As ` time parameter. .. note:: The last measurement comes from the last transmission of Single Frame or First Fame CAN Packet using - either :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.send_packet` - or :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.async_send_packet` - method. + either :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.send_packet` + or :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.async_send_packet` method. :return: Time in milliseconds or None if the value was never measured. """ @@ -196,9 +195,8 @@ def n_ar_measured(self) -> Optional[TimeMillisecondsAlias]: Get the last measured value of :ref:`N_Ar ` time parameter. .. note:: The last measurement comes from the last transmission of Flow Control CAN Packet using either - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.send_packet` or - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.async_send_packet` - method. + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.send_packet` or + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.async_send_packet` method. :return: Time in milliseconds or None if the value was never measured. """ @@ -233,9 +231,8 @@ def n_bs_measured(self) -> Optional[Tuple[TimeMillisecondsAlias, ...]]: Get the last measured values of :ref:`N_Bs ` time parameter. .. note:: The last measurement comes from the last transmission of UDS message using either - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.send_message` or - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.async_send_message` - method. + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.send_message` or + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.async_send_message` method. :return: Tuple with times in milliseconds or None if the values could not be measured. """ @@ -354,9 +351,8 @@ def n_cr_measured(self) -> Optional[Tuple[TimeMillisecondsAlias, ...]]: Get the last measured values of :ref:`N_Cr ` time parameter. .. note:: The last measurement comes from the last reception of UDS message using either - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.receive_message` or - :meth:`~uds.transport_interface.can_transport_interface.AbstractCanTransportInterface.async_receive_message` - method. + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.receive_message` or + :meth:`~uds.transport_interface.can.AbstractCanTransportInterface.async_receive_message` method. :return: Tuple with times in milliseconds or None if the values could not be measured. """ diff --git a/uds/transport_interface/can_transport_interface/python_can.py b/uds/transport_interface/can/python_can.py similarity index 98% rename from uds/transport_interface/can_transport_interface/python_can.py rename to uds/transport_interface/can/python_can.py index bcf8f479..142efc07 100644 --- a/uds/transport_interface/can_transport_interface/python_can.py +++ b/uds/transport_interface/can/python_can.py @@ -80,9 +80,9 @@ def n_as_measured(self) -> Optional[TimeMillisecondsAlias]: .. note:: The last measurement comes from the last transmission of Single Frame or First Fame CAN Packet using either - :meth:`~uds.transport_interface.can_transport_interface.python_can_transport_interface.PyCanTransportInterface.send_packet` + :meth:`~uds.transport_interface.can.python_can_transport_interface.PyCanTransportInterface.send_packet` or - :meth:`~uds.transport_interface.can_transport_interface.python_can_transport_interface.PyCanTransportInterface.async_send_packet` + :meth:`~uds.transport_interface.can.python_can_transport_interface.PyCanTransportInterface.async_send_packet` method. :return: Time in milliseconds or None if the value was never measured. @@ -96,9 +96,9 @@ def n_ar_measured(self) -> Optional[TimeMillisecondsAlias]: Get the last measured value of :ref:`N_Ar ` time parameter. .. note:: The last measurement comes from the last transmission of Flow Control CAN Packet using either - :meth:`~uds.transport_interface.can_transport_interface.python_can_transport_interface.PyCanTransportInterface.send_packet` + :meth:`~uds.transport_interface.can.python_can_transport_interface.PyCanTransportInterface.send_packet` or - :meth:`~uds.transport_interface.can_transport_interface.python_can_transport_interface.PyCanTransportInterface.async_send_packet` + :meth:`~uds.transport_interface.can.python_can_transport_interface.PyCanTransportInterface.async_send_packet` method. :return: Time in milliseconds or None if the value was never measured.