iso14229 0.11.0
ISO14229-1 (UDS) C Library
Loading...
Searching...
No Matches
iso14229.h
Go to the documentation of this file.
1/**
2 * @file iso14229.h
3 * SPDX-License-Identifier: MIT
4 * @brief ISO 14229 (UDS) library
5 * @copyright Copyright (c) Nick Kirkby
6 * @see documentation at https://github.com/driftregion/iso14229
7 */
8
9#ifndef ISO14229_H
10#define ISO14229_H
11
12#ifdef __cplusplus
13extern "C" {
14#endif // #ifdef __cplusplus
15
16
17#ifdef UDS_LINES
18#line 1 "src/version.h"
19#endif // #ifdef UDS_LINES
20#define UDS_LIB_VERSION "0.11.0"
21
22
23#ifdef UDS_LINES
24#line 1 "src/include.h"
25#endif // #ifdef UDS_LINES
26
27#include <assert.h> // early includes for static_assert
28
29#if !defined(__cplusplus) && ((!defined(__STDC_VERSION__)) || (__STDC_VERSION__ < 201112L))
30#ifndef static_assert
31/* cppcheck-suppress [misra-c2012-19.2,misra-c2012-20.4] Patch static_assert for pre-C11 toolchains
32 */
33#define static_assert(expr, msg)
34#else // #ifndef static_assert
35#warning "using static_assert of unknown provenance; Please check that the signature is correct"
36#endif // #ifndef static_assert
37#endif
38
39#include <inttypes.h>
40#include <stdbool.h>
41#include <stddef.h>
42#include <stdint.h>
43#include <stdio.h>
44#include <string.h>
45
46
47#ifdef UDS_LINES
48#line 1 "src/sys.h"
49#endif // #ifdef UDS_LINES
50
51/**
52 * @defgroup uds_sys_ valid values of UDS_SYS
53 * @brief iso14229 host system selection
54 * @see UDS_SYS
55 * @{
56 */
57#define UDS_SYS_CUSTOM 0 /**< bare metal or unsupported targets */
58#define UDS_SYS_UNIX 1
59#define UDS_SYS_WINDOWS 2
60#define UDS_SYS_ARDUINO 3
61#define UDS_SYS_ESP32 4
62#define UDS_SYS_ZEPHYR 5
63/** @} */
64
65#ifndef UDS_SYS // system auto-detection
66#ifdef __ZEPHYR__ // native_sim links w/host libc which also defines __unix__
67#define UDS_SYS UDS_SYS_ZEPHYR
68#elif defined(__unix__) || defined(__APPLE__)
69#define UDS_SYS UDS_SYS_UNIX
70#elif defined(_WIN32)
71#define UDS_SYS UDS_SYS_WINDOWS
72#elif defined(ARDUINO)
73#define UDS_SYS UDS_SYS_ARDUINO
74#elif defined(ESP_PLATFORM)
75#define UDS_SYS UDS_SYS_ESP32
76#else
77#warning \
78 "UDS_SYS was not detected, defaulting to UDS_SYS_CUSTOM. Remove this warning by defining UDS_SYS=UDS_SYS_CUSTOM in your build configuration"
79#define UDS_SYS UDS_SYS_CUSTOM
80#endif // defined(__ZEPHYR__)
81#endif // #ifndef(UDS_SYS) // system auto-detection
82
83
84#ifdef UDS_LINES
85#line 1 "src/config.h"
86#endif // #ifdef UDS_LINES
87
88/**
89 * @def UDS_SYS
90 * @brief Selects the host system iso14229 is compiled for.
91 * @see uds_sys_ for the list of valid values
92 */
93
94/**
95 * @def UDS_CUSTOM_MILLIS
96 * @brief bring your own UDSMillis implementation
97 * @details Bring your own UDSMillis implementation. Valid values:
98 * - `0` (default): iso14229 provides UDSMillis() for the detected @ref UDS_SYS platform
99 * - `1`: the user must provide their own UDSMillis() implementation
100 *
101 * @see UDSMillis
102 */
103
104/**
105 * @def UDS_LOG_LEVEL
106 * @brief sets the logging level
107 * @details set UDS_LOG_LEVEL to 0U (UDS_LOG_NONE) to remove logging entirely.
108 * @see uds_log_level_ for valid values
109 */
110#ifndef UDS_LOG_LEVEL
111#define UDS_LOG_LEVEL 0U
112#endif
113
114#define UDS_ISOTP_MTU (4095U) ///< ISO-TP Maximum Transmission Unit (ISO-15764-2-2004 section 5.3.3)
115
116#ifndef UDS_TP_MTU
117/// ISOTP is the only supported tp type, so UDS inherits its MTU
118#define UDS_TP_MTU UDS_ISOTP_MTU
119#endif
120
121/**
122 * @def UDS_SERVER_SEND_BUF_SIZE
123 * @brief reduce this at your own risk to save RAM. Fuzz testing is done with the default of @ref
124 * UDS_TP_MTU.
125 */
126#ifndef UDS_SERVER_SEND_BUF_SIZE
127#define UDS_SERVER_SEND_BUF_SIZE (UDS_TP_MTU)
128#endif
129
130/** @copydoc UDS_SERVER_SEND_BUF_SIZE */
131#ifndef UDS_SERVER_RECV_BUF_SIZE
132#define UDS_SERVER_RECV_BUF_SIZE (UDS_TP_MTU)
133#endif
134
135/** @copydoc UDS_SERVER_SEND_BUF_SIZE */
136#ifndef UDS_CLIENT_SEND_BUF_SIZE
137#define UDS_CLIENT_SEND_BUF_SIZE (UDS_TP_MTU)
138#endif
139
140/** @copydoc UDS_SERVER_SEND_BUF_SIZE */
141#ifndef UDS_CLIENT_RECV_BUF_SIZE
142#define UDS_CLIENT_RECV_BUF_SIZE (UDS_TP_MTU)
143#endif
144
145#ifndef UDS_CLIENT_DEFAULT_P2_MS
146#define UDS_CLIENT_DEFAULT_P2_MS (150U) ///< default P2 timeout
147#endif
148
149#ifndef UDS_CLIENT_DEFAULT_P2_STAR_MS
150#define UDS_CLIENT_DEFAULT_P2_STAR_MS (1500U) ///< default P2* timeout
151#endif
152
154
155#ifndef UDS_SERVER_DEFAULT_P2_MS
156#define UDS_SERVER_DEFAULT_P2_MS (50) ///< default P2 duration
157#endif
158
159#ifndef UDS_SERVER_DEFAULT_P2_STAR_MS
160#define UDS_SERVER_DEFAULT_P2_STAR_MS (5000) ///< default P2* duration
161#endif
162
163#ifndef UDS_SERVER_DEFAULT_S3_MS
164#define UDS_SERVER_DEFAULT_S3_MS \
165 (5100) ///< default S3 duration (ISO14229-2 2013 Table 5: 5000 -0/+200 ms)
166#endif
167
168static_assert((bool)((0 < UDS_SERVER_DEFAULT_P2_MS) &&
171 "");
172
173/// Duration between the server sending a positive response to an ECU reset request and the emission
174/// of a UDS_EVT_DoScheduledReset event. This should be set to a duration adequate for the server
175/// transport layer to finish responding to the ECU reset request.
176#ifndef UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS
177#define UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS (60)
178#endif
179
180#if (UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS < UDS_SERVER_DEFAULT_P2_MS)
181#error "The server shall have adequate time to respond before reset"
182#endif
183
184/// Amount of time to wait after boot before accepting 0x27 requests.
185#ifndef UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_BOOT_DELAY_MS
186#define UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_BOOT_DELAY_MS (1000U)
187#endif
188
189/// Amount of time to wait after an authentication failure before accepting another 0x27 request.
190#ifndef UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_AUTH_FAIL_DELAY_MS
191#define UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_AUTH_FAIL_DELAY_MS (1000U)
192#endif
193
194#ifndef UDS_SERVER_DEFAULT_XFER_DATA_MAX_BLOCKLENGTH
195/*! ISO14229-1:2013 Table 396. This parameter is used by the requestDownload positive response
196message to inform the client how many data bytes (maxNumberOfBlockLength) to include in each
197TransferData request message from the client. */
198#define UDS_SERVER_DEFAULT_XFER_DATA_MAX_BLOCKLENGTH (UDS_TP_MTU)
199#endif
200
201#ifndef UDS_AUTOSELECT_TP // transport auto-selection. Set -DUDS_AUTOSELECT_TP=0 to turn off
202 // auto-selection
203#define UDS_AUTOSELECT_TP 1
204
205#if ((UDS_SYS == UDS_SYS_CUSTOM) || (UDS_SYS == UDS_SYS_ARDUINO) || (UDS_SYS == UDS_SYS_ESP32) || \
206 (UDS_SYS == UDS_SYS_ZEPHYR))
207#ifndef UDS_TP_ISOTP_C
208#define UDS_TP_ISOTP_C
209#endif // #ifndef UDS_TP_ISOTP_C
210#elif (UDS_SYS == UDS_SYS_UNIX)
211#ifndef UDS_TP_ISOTP_SOCK
212#define UDS_TP_ISOTP_SOCK
213#endif // #ifndef UDS_TP_ISOTP_SOCK
214#else
215// no default tp
216#endif // ((UDS_SYS == UDS_SYS_CUSTOM) || ... )
217
218#endif // #ifndef UDS_AUTOSELECT_TP
219
220
221#ifdef UDS_LINES
222#line 1 "src/config_internal.h"
223#endif // #ifdef UDS_LINES
224// non user-facing config
225
226#if UDS_SYS == UDS_SYS_CUSTOM
227#ifndef UDS_CUSTOM_MILLIS
228#define UDS_CUSTOM_MILLIS
229#endif // #ifndef UDS_CUSTOM_MILLIS
230#endif // UDS_SYS == UDS_SYS_CUSTOM
231
232#if UDS_SYS == UDS_SYS_WINDOWS
233#ifdef _MSC_VER
234#define strncasecmp _strnicmp
235#define strcasecmp _stricmp
236#endif // ifdef _MSC_VER
237#endif // if UDS_SYS == UDS_SYS_WINDOWS
238
239#ifdef UDS_TP_ISOTP_C_SOCKETCAN
240#ifndef UDS_TP_ISOTP_C
241#define UDS_TP_ISOTP_C
242#endif // #ifndef (UDS_TP_ISOTP_C)
243#endif // #defined(UDS_TP_ISOTP_C_SOCKETCAN)
244
245#ifdef UDS_TP_ISOTP_C_SOCKETCAN
246#ifndef UDS_TP_ISOTP_C
247#error "UDS_TP_ISOTP_C must be defined to use UDS_TP_ISOTP_C_SOCKETCAN"
248#endif // #ifndef UDS_TP_ISOTP_C
249#endif // defined(UDS_TP_ISOTP_C_SOCKETCAN)
250
251#ifdef UDS_TP_ISOTP_C
252#ifdef ISO_TP_USER_SEND_CAN_ARG
253#error "this flag is set by iso14229"
254#endif // #ifdef ISO_TP_USER_SEND_CAN_ARG
255#define ISO_TP_USER_SEND_CAN_ARG 1
256
257#ifdef ISO_TP_NO_FORMATTED_ERRORS
258#error "this flag is set by iso14229"
259#endif
260#define ISO_TP_NO_FORMATTED_ERRORS 1
261#endif // defined(UDS_TP_ISOTP_C)
262
263
264#ifdef UDS_LINES
265#line 1 "src/uds.h"
266#endif // #ifdef UDS_LINES
267
268/** @file */
269
270/**
271 * @enum UDSEvent_t
272 * @brief UDS events
273 *
274 * Events are passed to the server or client callback function along with
275 * a pointer to the associated argument structure.
276 */
277typedef enum UDSEvent {
278 UDS_EVT_Err, /**< Common event. Argument type: UDSErr_t * */
279
280 UDS_EVT_DiagSessCtrl, /**< Server evt 0x10, argtype: UDSDiagSessCtrlArgs_t * */
281 UDS_EVT_EcuReset, /**< Server evt 0x11, argtype: UDSECUResetArgs_t * */
282 UDS_EVT_ClearDiagnosticInfo, /**< Server evt 0x14, argtype: UDSCDIArgs_t * */
283 UDS_EVT_ReadDTCInformation, /**< Server evt 0x19, argtype: UDSRDTCIArgs_t * */
284 UDS_EVT_ReadDataByIdent, /**< Server evt 0x22, argtype: UDSRDBIArgs_t * */
285 UDS_EVT_ReadMemByAddr, /**< Server evt 0x23, argtype: UDSReadMemByAddrArgs_t * */
286 UDS_EVT_CommCtrl, /**< Server evt 0x28, argtype: UDSCommCtrlArgs_t * */
287 UDS_EVT_SecAccessRequestSeed, /**< Server evt 0x27, argtype: UDSSecAccessRequestSeedArgs_t * */
288 UDS_EVT_SecAccessValidateKey, /**< Server evt 0x27, argtype: UDSSecAccessValidateKeyArgs_t * */
289 UDS_EVT_WriteDataByIdent, /**< Server evt 0x2E, argtype: UDSWDBIArgs_t * */
290 UDS_EVT_WriteMemByAddr, /**< Server evt 0x3D, argtype: UDSWriteMemByAddrArgs_t * */
291 UDS_EVT_DynamicDefineDataId, /**< Server evt 0x2C, argtype: UDSDDDIArgs_t * */
292 UDS_EVT_IOControl, /**< Server evt 0x2F, argtype: UDSIOCtrlArgs_t * */
293 UDS_EVT_RoutineCtrl, /**< Server evt 0x31, argtype: UDSRoutineCtrlArgs_t * */
294 UDS_EVT_RequestDownload, /**< Server evt 0x34, argtype: UDSRequestDownloadArgs_t * */
295 UDS_EVT_RequestUpload, /**< Server evt 0x35, argtype: UDSRequestUploadArgs_t * */
296 UDS_EVT_TransferData, /**< Server evt 0x36, argtype: UDSTransferDataArgs_t * */
297 UDS_EVT_RequestTransferExit, /**< Server evt 0x37, argtype: UDSRequestTransferExitArgs_t * */
298 UDS_EVT_SessionTimeout, /**< Server evt 0x38, argtype: NULL */
299 UDS_EVT_DoScheduledReset, /**< Server evt 0x39, argtype: uint8_t * */
300 UDS_EVT_RequestFileTransfer, /**< Server evt 0x38, argtype: UDSRequestFileTransferArgs_t * */
301 UDS_EVT_ControlDTCSetting, /**< Server evt 0x85, argtype: UDSControlDTCSettingArgs_t * */
302 UDS_EVT_LinkControl, /**< Server evt 0x87, argtype: UDSLinkCtrlArgs_t * */
303 UDS_EVT_Custom, /**< Server evt other, argtype: UDSCustomArgs_t * */
304
305 UDS_EVT_Poll, /**< Client evt: Poll. Argument type: NULL */
306 UDS_EVT_SendComplete, /**< Client evt: Send complete. Argument type: NULL */
307 UDS_EVT_ResponseReceived, /**< Client evt: Response received. Argument type: NULL */
308 UDS_EVT_Idle, /**< Client evt: Idle. Argument type: NULL */
309
310 UDS_EVT_MAX, /**< Unused sentinel value */
311} UDSEvent_t;
312
313/**
314 * @brief Error Codes, including NRCs defined by the standard.
315 * @see UDSErrToStr
316 */
317typedef enum {
318 UDS_FAIL = -1, // General error
319 UDS_OK = 0, // Success
320
321 // Negative Response Codes (NRCs) as defined in ISO14229-1:2020 Table A.1 - Negative Response
322 // Code (NRC) definition and values
323 UDS_PositiveResponse = 0,
324 // 0x01 to 0x0F are reserved by ISO14229-1:2020
325 UDS_NRC_GeneralReject = 0x10,
326 UDS_NRC_ServiceNotSupported = 0x11,
327 UDS_NRC_SubFunctionNotSupported = 0x12,
328 UDS_NRC_IncorrectMessageLengthOrInvalidFormat = 0x13,
329 UDS_NRC_ResponseTooLong = 0x14,
330 // 0x15 to 0x20 are reserved by ISO14229-1:2020
331 UDS_NRC_BusyRepeatRequest = 0x21,
332 UDS_NRC_ConditionsNotCorrect = 0x22,
333 UDS_NRC_RequestSequenceError = 0x24,
334 UDS_NRC_NoResponseFromSubnetComponent = 0x25,
335 UDS_NRC_FailurePreventsExecutionOfRequestedAction = 0x26,
336 // 0x27 to 0x30 are reserved by ISO14229-1:2020
337 UDS_NRC_RequestOutOfRange = 0x31,
338 // 0x32 is reserved by ISO14229-1:2020
339 UDS_NRC_SecurityAccessDenied = 0x33,
340 UDS_NRC_AuthenticationRequired = 0x34,
341 UDS_NRC_InvalidKey = 0x35,
342 UDS_NRC_ExceedNumberOfAttempts = 0x36,
343 UDS_NRC_RequiredTimeDelayNotExpired = 0x37,
344 UDS_NRC_SecureDataTransmissionRequired = 0x38,
345 UDS_NRC_SecureDataTransmissionNotAllowed = 0x39,
346 UDS_NRC_SecureDataVerificationFailed = 0x3A,
347 // 0x3B to 0x4F are reserved by ISO14229-1:2020
348 UDS_NRC_CertficateVerificationFailedInvalidTimePeriod = 0x50,
349 UDS_NRC_CertficateVerificationFailedInvalidSignature = 0x51,
350 UDS_NRC_CertficateVerificationFailedInvalidChainOfTrust = 0x52,
351 UDS_NRC_CertficateVerificationFailedInvalidType = 0x53,
352 UDS_NRC_CertficateVerificationFailedInvalidFormat = 0x54,
353 UDS_NRC_CertficateVerificationFailedInvalidContent = 0x55,
354 UDS_NRC_CertficateVerificationFailedInvalidScope = 0x56,
355 UDS_NRC_CertficateVerificationFailedInvalidCertificate = 0x57,
356 UDS_NRC_OwnershipVerificationFailed = 0x58,
357 UDS_NRC_ChallengeCalculationFailed = 0x59,
358 UDS_NRC_SettingAccessRightsFailed = 0x5A,
359 UDS_NRC_SessionKeyCreationOrDerivationFailed = 0x5B,
360 UDS_NRC_ConfigurationDataUsageFailed = 0x5C,
361 UDS_NRC_DeAuthenticationFailed = 0x5D,
362 // 0x5E to 0x6F are reserved by ISO14229-1:2020
363 UDS_NRC_UploadDownloadNotAccepted = 0x70,
364 UDS_NRC_TransferDataSuspended = 0x71,
365 UDS_NRC_GeneralProgrammingFailure = 0x72,
366 UDS_NRC_WrongBlockSequenceCounter = 0x73,
367 // 0x74 to 0x77 are reserved by ISO14229-1:2020
368 UDS_NRC_RequestCorrectlyReceived_ResponsePending = 0x78,
369 // 0x79 to 0x7D are reserved by ISO14229-1:2020
370 UDS_NRC_SubFunctionNotSupportedInActiveSession = 0x7E,
371 UDS_NRC_ServiceNotSupportedInActiveSession = 0x7F,
372 // 0x80 is reserved by ISO14229-1:2020
373 UDS_NRC_RpmTooHigh = 0x81,
374 UDS_NRC_RpmTooLow = 0x82,
375 UDS_NRC_EngineIsRunning = 0x83,
376 UDS_NRC_EngineIsNotRunning = 0x84,
377 UDS_NRC_EngineRunTimeTooLow = 0x85,
378 UDS_NRC_TemperatureTooHigh = 0x86,
379 UDS_NRC_TemperatureTooLow = 0x87,
380 UDS_NRC_VehicleSpeedTooHigh = 0x88,
381 UDS_NRC_VehicleSpeedTooLow = 0x89,
382 UDS_NRC_ThrottlePedalTooHigh = 0x8A,
383 UDS_NRC_ThrottlePedalTooLow = 0x8B,
384 UDS_NRC_TransmissionRangeNotInNeutral = 0x8C,
385 UDS_NRC_TransmissionRangeNotInGear = 0x8D,
386 // 0x8E is reserved by ISO14229-1:2020
387 UDS_NRC_BrakeSwitchNotClosed = 0x8F,
388 UDS_NRC_ShifterLeverNotInPark = 0x90,
389 UDS_NRC_TorqueConverterClutchLocked = 0x91,
390 UDS_NRC_VoltageTooHigh = 0x92,
391 UDS_NRC_VoltageTooLow = 0x93,
392 UDS_NRC_ResourceTemporarilyNotAvailable = 0x94,
393
394 /* 0x95 to 0xEF are reservedForSpecificConditionsNotCorrect */
395 /* 0xF0 to 0xFE are vehicleManufacturerSpecificConditionsNotCorrect */
396 /* 0xFF is ISOSAEReserved */
397 UDS_NRC_UNUSED_ISOSAEReserved = 0xFF,
398
399 // The following values are not defined in ISO14229-1:2020
400 UDS_ERR_TIMEOUT = 0x100, // A request has timed out
401 UDS_ERR_DID_MISMATCH = 0x101, // The response DID does not match the request DID
402 UDS_ERR_SID_MISMATCH = 0x102, // The response SID does not match the request SID
403 UDS_ERR_SUBFUNCTION_MISMATCH =
404 0x103, // The response SubFunction does not match the request SubFunction
405 UDS_ERR_RESP_TOO_SHORT = 0x104, // The response is too short
406 UDS_ERR_BUFSIZ = 0x105, // The buffer is not large enough
407 UDS_ERR_INVALID_ARG = 0x106, // The function has been called with invalid arguments
408 UDS_ERR_BUSY = 0x107, // The client is busy and cannot process the request
409 UDS_ERR_MISUSE = 0x108, // The library is used incorrectly
410
411 UDS_ERR_TPORT = 0x200, // Transport error
412} UDSErr_t;
413
414/**
415 * @defgroup uds_lev_ds_ Diagnostic Session Levels
416 * @brief ISO14229-1:2020 Table 25
417 * @see UDSSendDiagSessCtrl UDS_EVT_DiagSessCtrl
418 * @{
419 */
420#define UDS_LEV_DS_DS 1U ///< Default Session
421#define UDS_LEV_DS_PRGS 2U ///< Programming Session
422#define UDS_LEV_DS_EXTDS 3U ///< Extended Diagnostic Session
423#define UDS_LEV_DS_SSDS 4U ///< Safety System Diagnostic Session
424/** @} */
425
426/**
427 * @defgroup uds_lev_rt_ Reset Types
428 * @brief ISO14229-1:2020 Table 34
429 * @see UDSSendECUReset UDS_EVT_ECUReset
430 * @{
431 */
432#define UDS_LEV_RT_HR 1U ///< Hard Reset
433#define UDS_LEV_RT_KOFFONR 2U ///< Key Off On Reset
434#define UDS_LEV_RT_SR 3U ///< Soft Reset
435#define UDS_LEV_RT_ERPSD 4U ///< Enable Rapid Power Shut Down
436#define UDS_LEV_RT_DRPSD 5U ///< Disable Rapid Power Shut Down
437/** @} */
438
439/**
440 * @defgroup uds_lev_ctrlp_ Communication Control Levels
441 * @brief ISO14229-1:2020 Table 54
442 * @see UDSSendCommCtrl UDS_EVT_CommCtrl
443 * @{
444 */
445#define UDS_LEV_CTRLTP_ERXTX 0U ///< EnableRxAndTx
446#define UDS_LEV_CTRLTP_ERXDTX 1U ///< EnableRxAndDisableTx
447#define UDS_LEV_CTRLTP_DRXETX 2U ///< DisableRxAndEnableTx
448#define UDS_LEV_CTRLTP_DRXTX 3U ///< DisableRxAndTx
449/** @} */
450
451/**
452 * @defgroup uds_ctp_ Communication Types
453 * @brief ISO14229-1:2020 Table B.1
454 * @see UDSSendCommCtrl UDS_EVT_CommCtrl
455 * @{
456 */
457#define UDS_CTP_NCM 1U ///< NormalCommunicationMessages
458#define UDS_CTP_NWMCM 2U ///< NetworkManagementCommunicationMessages
459#define UDS_CTP_NWMCM_NCM \
460 3U ///< NetworkManagementCommunicationMessagesAndNormalCommunicationMessages
461/** @} */
462
463/**
464 * @defgroup uds_lev_rctp_ Routine Control Levels
465 * @brief ISO14229-1:2020 Table 426
466 * @see UDSSendRoutineCtrl UDS_EVT_RoutineCtrl
467 * @{
468 */
469#define UDS_LEV_RCTP_STR 1U ///< StartRoutine
470#define UDS_LEV_RCTP_STPR 2U ///< StopRoutine
471#define UDS_LEV_RCTP_RRR 3U ///< RequestRoutineResults
472/** @} */
473
474/**
475 * @defgroup uds_moop_ Mode of Operation for RequestFileTransfer
476 * @brief ISO14229-1:2020 Table G.1
477 * @see UDSSendRequestFileTransfer UDS_EVT_RequestFileTransfer
478 * @{
479 */
480#define UDS_MOOP_ADDFILE 1U ///< AddFile
481#define UDS_MOOP_DELFILE 2U ///< DeleteFile
482#define UDS_MOOP_REPLFILE 3U ///< ReplaceFile
483#define UDS_MOOP_RDFILE 4U ///< ReadFile
484#define UDS_MOOP_RDDIR 5U ///< ReadDirectory
485#define UDS_MOOP_RSFILE 6U ///< ResumeFile
486/** @} */
487
488/**
489 * @defgroup uds_lev_dtcstp_ Diagnostic Trouble Code Control Level
490 * @brief ISO14229-1:2020 Table 128
491 * @see UDSSendControlDTCSetting UDS_EVT_ControlDTCSetting
492 * @{
493 */
494#define UDS_LEV_DTCSTP_ON 1U ///< Resume updating DTCs
495#define UDS_LEV_DTCSTP_OFF 2U ///< Stop updating DTCs
496/** @} */
497
498/**
499 * @defgroup uds_lev_lctp_ Link Control Level
500 * @brief ISO14229-1:2020 Table 171
501 * @see UDSSendLinkControl UDS_EVT_LinkControl
502 * @{
503 */
504#define UDS_LEV_LCTP_VMTWFP 1U ///< VerifyModeTransitionWithFixedParameter
505#define UDS_LEV_LCTP_VMTWSP 2U ///< VerifyModeTransitionWithSpecificParameter
506#define UDS_LEV_LCTP_TM 3U ///< TransitionMode
507/** @} */
508
509
510#ifdef UDS_LINES
511#line 1 "src/tp.h"
512#endif // #ifdef UDS_LINES
513
514
515
516
517#ifdef UDS_TP_ISOTP_C_SOCKETCAN
518#ifndef UDS_TP_ISOTP_C
519#define UDS_TP_ISOTP_C
520#endif
521#endif
522
523/** private: transport message type
524 * @defgroup uds_a_mtype
525 */
526#define UDS_A_MTYPE_DIAG 0U
527#define UDS_A_MTYPE_REMOTE_DIAG 1U
528#define UDS_A_MTYPE_SECURE_DIAG 2U
529#define UDS_A_MTYPE_SECURE_REMOTE_DIAG 3U
530
531typedef uint8_t UDS_A_Mtype_t; ///< private: oneof @ref uds_a_mtype
532
533/** private: transport transmission type
534 * @defgroup uds_a_ta_type
535 */
536#define UDS_A_TA_TYPE_PHYSICAL 0U // unicast (1:1)
537#define UDS_A_TA_TYPE_FUNCTIONAL 1U // multicast
538
539typedef uint8_t UDS_A_TA_Type_t; ///< private: oneof @ref uds_a_ta_type
540
541/**
542 * @brief Service data unit (SDU)
543 * @details Service data unit (SDU): data interface between the application layer and the
544 * transport layer
545 */
546typedef struct {
547 UDS_A_Mtype_t A_Mtype; /**< message type (diagnostic, remote diagnostic, secure diagnostic,
548 secure remote diagnostic) */
549 uint32_t A_SA; /**< application source address */
550 uint32_t A_TA; /**< application target address */
551 UDS_A_TA_Type_t A_TA_Type; /**< application target address type (physical or functional) */
552 uint32_t A_AE; /**< application layer remote address */
553} UDSSDU_t;
554
555#define UDS_TP_NOOP_ADDR (0xFFFFFFFFU) ///< flags A_SA / A_TA as unused
556
557/**
558 * @brief UDS Transport layer
559 * @note implementers should embed this struct at offset zero in their own transport layer handle
560 */
561typedef struct UDSTp {
562 /**
563 * @brief Send data to the transport
564 * @param hdl: pointer to transport handle
565 * @param buf: a pointer to the data to send
566 * @param len: length of data to send
567 * @param info: pointer to SDU info (may be NULL). If NULL, implementation should send with
568 * physical addressing
569 * @return UDS_OK if successful
570 */
571 UDSErr_t (*send)(struct UDSTp *hdl, const uint8_t *buf, const size_t len, const UDSSDU_t *info);
572
573 /**
574 * @brief Receive data from the transport
575 * @param hdl: transport handle
576 * @param buf: receive buffer
577 * @param bufsiz: size of receive buffer
578 * @param recvlen: number of bytes actually received
579 * @param info: pointer to SDU info to be updated by transport implementation. May be NULL. If
580 * non-NULL, the transport implementation must populate it with valid values.
581 * @return UDS_OK if successful
582 */
583 UDSErr_t (*recv)(struct UDSTp *hdl, uint8_t *buf, size_t bufsiz, size_t *recvlen,
584 UDSSDU_t *info);
585
586 /**
587 * @brief Poll the transport layer.
588 * @param hdl: pointer to transport handle
589 * @note
590 */
591 UDSErr_t (*poll)(struct UDSTp *hdl);
592
593 /**
594 * @brief status flag (read-only)
595 */
596 struct {
597 unsigned is_sending : 1; // set when data transmission starts in send(); cleared when done.
598 } status;
599} UDSTp_t;
600
601UDSErr_t UDSTpSend(UDSTp_t *hdl, const uint8_t *buf, size_t len,
602 const UDSSDU_t *info); ///< Send to transport
603UDSErr_t UDSTpRecv(UDSTp_t *hdl, uint8_t *buf, size_t bufsiz, size_t *recvlen,
604 UDSSDU_t *info); ///< Receive from transport
605UDSErr_t UDSTpPoll(UDSTp_t *hdl); ///< call this at <5ms intervals
606
607
608#ifdef UDS_LINES
609#line 1 "src/util.h"
610#endif // #ifdef UDS_LINES
611
612
613
614
615
616
617/**
618 * @def UDS_ASSERT(x)
619 * @brief used to enforce runtime invariants within iso14229
620 */
621#ifndef UDS_ASSERT
622#define UDS_ASSERT(x) assert(x)
623#endif
624
625/**
626 * @brief Get time in milliseconds
627 * @return current time in milliseconds
628 * @note implementers must ensure the return value is monotonically increasing between
629 * calls. The value must never go backwards.
630 * Wrap-around (overflow back to 0) is expected; this is handled by UDSTimeAfter.
631 */
632uint32_t UDSMillis(void);
633
634const char *UDSErrToStr(UDSErr_t err);
635const char *UDSEventToStr(UDSEvent_t evt);
636
637
638#ifdef UDS_LINES
639#line 1 "src/log.h"
640#endif // #ifdef UDS_LINES
641
642/**
643 * @brief logging for bring-up and unit tests.
644 * Attribution: the initial version of this API was copied from ESP-IDF.
645 */
646
647
648
649
650
651/**
652 * @defgroup uds_log_level_ valid values for UDS_LOG_LEVEL
653 * @brief configures logging verbosity
654 * @{
655 */
656#define UDS_LOG_NONE 0U /**< No log output */
657#define UDS_LOG_ERROR 1U /**< Log errors only */
658#define UDS_LOG_WARN 2U /**< Log warnings and errors */
659#define UDS_LOG_INFO 3U /**< Log info, warnings, and errors */
660#define UDS_LOG_DEBUG 4U /**< Log debug, info, warnings, and errors */
661#define UDS_LOG_VERBOSE 5U /**< Log verbose, debug, info, warnings, and errors */
662/** @} */
663
664typedef unsigned int UDS_LogLevel_t; ///< one of @ref uds_log_level_
665
666static_assert((bool)((UDS_LOG_LEVEL == UDS_LOG_NONE) || (UDS_LOG_LEVEL == UDS_LOG_ERROR) ||
669 "unknown log level");
670
671#if UDS_LOG_LEVEL >= UDS_LOG_ERROR && UDS_LOG_LEVEL != UDS_LOG_NONE
672#define UDS_LOGE(tag, format, ...) \
673 UDS_LogWrite(UDS_LOG_ERROR, tag, UDS_LOG_FORMAT(E, format), UDSMillis(), tag, ##__VA_ARGS__)
674#else
675#define UDS_LOGE(tag, format, ...) UDS_LogDummy(UDS_LOG_NONE, tag, format, ##__VA_ARGS__)
676#endif
677
678#if UDS_LOG_LEVEL >= UDS_LOG_WARN && UDS_LOG_LEVEL != UDS_LOG_NONE
679#define UDS_LOGW(tag, format, ...) \
680 UDS_LogWrite(UDS_LOG_WARN, tag, UDS_LOG_FORMAT(W, format), UDSMillis(), tag, ##__VA_ARGS__)
681#else
682#define UDS_LOGW(tag, format, ...) UDS_LogDummy(UDS_LOG_NONE, tag, format, ##__VA_ARGS__)
683#endif
684
685#if UDS_LOG_LEVEL >= UDS_LOG_INFO && UDS_LOG_LEVEL != UDS_LOG_NONE
686#define UDS_LOGI(tag, format, ...) \
687 UDS_LogWrite(UDS_LOG_INFO, tag, UDS_LOG_FORMAT(I, format), UDSMillis(), tag, ##__VA_ARGS__)
688#else
689#define UDS_LOGI(tag, format, ...) UDS_LogDummy(UDS_LOG_NONE, tag, format, ##__VA_ARGS__)
690#endif
691
692#if UDS_LOG_LEVEL >= UDS_LOG_DEBUG && UDS_LOG_LEVEL != UDS_LOG_NONE
693#define UDS_LOGD(tag, format, ...) \
694 UDS_LogWrite(UDS_LOG_DEBUG, tag, UDS_LOG_FORMAT(D, format), UDSMillis(), tag, ##__VA_ARGS__)
695#else
696#define UDS_LOGD(tag, format, ...) UDS_LogDummy(UDS_LOG_NONE, tag, format, ##__VA_ARGS__)
697#endif
698
699#if UDS_LOG_LEVEL >= UDS_LOG_VERBOSE
700#define UDS_LOGV(tag, format, ...) \
701 UDS_LogWrite(UDS_LOG_VERBOSE, tag, UDS_LOG_FORMAT(V, format), UDSMillis(), tag, ##__VA_ARGS__)
702#define UDS_LOG_SDU(tag, buffer, buff_len, info) \
703 UDS_LogSDUInternal(UDS_LOG_DEBUG, tag, buffer, buff_len, info)
704#else
705#define UDS_LOGV(tag, format, ...) UDS_LogDummy(UDS_LOG_NONE, tag, format, ##__VA_ARGS__)
706#define UDS_LOG_SDU(tag, buffer, buff_len, info) \
707 UDS_LogSDUDummy(UDS_LOG_NONE, tag, buffer, buff_len, info)
708#endif
709
710#if defined(__GNUC__) || defined(__clang__)
711#define UDS_PRINTF_FORMAT(fmt_index, first_arg) \
712 __attribute__((format(printf, fmt_index, first_arg)))
713#else
714#define UDS_PRINTF_FORMAT(fmt_index, first_arg)
715#endif
716
717#if UDS_LOG_LEVEL > UDS_LOG_NONE
718/* cppcheck-suppress [misra-c2012-20.10] string logging is not subject to MISRA */
719#define UDS_LOG_FORMAT(letter, format) #letter " (%" PRIu32 ") %s: " format "\n"
720void UDS_LogWrite(UDS_LogLevel_t level, const char *tag, const char *format, ...)
721 UDS_PRINTF_FORMAT(3, 4);
722void UDS_LogSDUInternal(UDS_LogLevel_t level, const char *tag, const uint8_t *buffer, size_t buflen,
723 const UDSSDU_t *info);
724#endif // UDS_LOG_LEVEL > UDS_LOG_NONE
725
726static inline void UDS_LogDummy(UDS_LogLevel_t level, const char *tag, const char *format, ...) {
727 (void)level;
728 (void)tag;
729 (void)format;
730}
731static inline void UDS_LogSDUDummy(UDS_LogLevel_t level, const char *tag, const uint8_t *buffer,
732 size_t buflen, const UDSSDU_t *info) {
733 (void)level;
734 (void)tag;
735 (void)buffer;
736 (void)buflen;
737 (void)info;
738}
739/// \endcond
740
741
742#ifdef UDS_LINES
743#line 1 "src/client.h"
744#endif // #ifdef UDS_LINES
745
746
747
748
749
750/**
751 * @brief UDS client structure
752 */
753typedef struct UDSClient {
754 // User-facing configuration options
755 UDSTp_t *tp; /**< transport layer handle */
756 int (*fn)(struct UDSClient *client, UDSEvent_t evt, void *ev_data); /**< callback function */
757 void *fn_data; /**< user-specified function data */
758 unsigned cfg_suppress_pos_resp : 1; /**< suppress positive responses from the server */
759 unsigned cfg_send_functional : 1; /**< send functional (broadcast) requests */
761 : 1; /**< do not heed the P2 and P2* timings sent by the server */
762 uint8_t cfg_data_format_identifier; /**< 0x38 RequestFileTransfer dataFormatIdentifier */
763 uint8_t cfg_file_size_parameter_length; /**< 0x38 RequestFileTransfer fileSizeParameterLength */
764
765 // private members
766 uint16_t p2_ms; /**< p2 timeout in milliseconds */
767 uint32_t p2_star_ms; /**< p2* timeout in milliseconds (for 0x78 response) */
768 uint32_t p2_timer; /**< p2 timer value */
769 uint8_t state; /**< client request state, @see client_request_states */
770
771 size_t recv_size; /**< size of received data */
772 size_t send_size; /**< size of data to send */
773 uint8_t recv_buf[UDS_CLIENT_RECV_BUF_SIZE]; /**< receive buffer */
774 uint8_t send_buf[UDS_CLIENT_SEND_BUF_SIZE]; /**< send buffer */
776
777/**
778 * @brief Security access response structure
779 */
781 uint8_t securityAccessType; /**< security access type (subfunction) */
782 const uint8_t *securitySeed; /**< pointer to security seed data */
783 size_t securitySeedLength; /**< length of security seed */
784};
785
786/**
787 * @brief Request download response structure
788 */
790 uint32_t maxBlockLength; /**< server's maximum block length for TransferData requests */
791};
792
793/**
794 * @brief Routine control response structure
795 */
797 uint8_t routineControlType; /**< routine control type (subfunction) */
798 uint16_t routineIdentifier; /**< routine identifier */
799 const uint8_t *routineStatusRecord; /**< pointer to routine status record */
800 size_t routineStatusRecordLength; /**< length of routine status record */
801};
802
803/**
804 * @brief Read data by identifier variable structure
805 */
806typedef struct {
807 uint16_t did; /**< data identifier */
808 uint16_t len; /**< data length */
809 void *data; /**< pointer to data buffer */
810 void *(*UnpackFn)(void *dst, const void *src, size_t n); /**< optional unpack function */
812
813UDSErr_t UDSClientInit(UDSClient_t *client); ///< Call this once
814UDSErr_t UDSClientPoll(UDSClient_t *client); ///< Call at <5ms intervals
815UDSErr_t UDSSendBytes(UDSClient_t *client, const uint8_t *data,
816 uint16_t size); ///< Send user-defined bytes to a UDS server
817UDSErr_t UDSSendECUReset(UDSClient_t *client, uint8_t type); ///< Request ECUReset
818UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, uint8_t mode); ///< Change the diagnostic session
819UDSErr_t UDSSendSecurityAccess(UDSClient_t *client, uint8_t level, const uint8_t *data,
820 uint16_t size); ///< Get Security Access
821UDSErr_t UDSSendCommCtrl(UDSClient_t *client, uint8_t ctrl,
822 uint8_t comm); ///< Change communication settings
823UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList,
824 uint16_t numDataIdentifiers); ///< Read Data By Identifier
825UDSErr_t UDSSendWDBI(UDSClient_t *client, uint16_t dataIdentifier, const uint8_t *data,
826 uint16_t size); ///< Write Data By Identifier
827UDSErr_t UDSSendTesterPresent(UDSClient_t *client); ///< What's up?
828UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, uint8_t type, uint16_t routineIdentifier,
829 const uint8_t *data, uint16_t size); ///< Request to Twiddle Routines
830
831UDSErr_t UDSSendRequestDownload(UDSClient_t *client, uint8_t dataFormatIdentifier,
832 uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress,
833 size_t memorySize); ///< Request to Download via TransferData
834
835UDSErr_t UDSSendRequestUpload(UDSClient_t *client, uint8_t dataFormatIdentifier,
836 uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress,
837 size_t memorySize); ///< Request to Upload via TransferData
838UDSErr_t UDSSendTransferData(UDSClient_t *client, uint8_t blockSequenceCounter,
839 uint16_t blockLength, const uint8_t *data,
840 uint16_t size); ///< Transfer Data to/from a buffer
842UDSSendRequestTransferExit(UDSClient_t *client); ///< Call this when finished with TransferData
843
845 UDSClient_t *client, uint8_t mode, const char *filePath, size_t filePathLen,
846 size_t fileSizeUncompressed,
847 size_t fileSizeCompressed); ///< filesystem-based frontend to TransferData
848UDSErr_t UDSCtrlDTCSetting(UDSClient_t *client, uint8_t dtcSettingType,
849 const uint8_t *dtcSettingControlOptionRecord,
850 uint16_t len); ///< control DTC setting
852 uint16_t numVars); ///< Parse server's response to RDBI
854 const UDSClient_t *client,
855 struct SecurityAccessResponse *resp); ///< Parse server's response to SecurityAccess
857 const UDSClient_t *client,
858 struct RequestDownloadResponse *resp); ///< Parse server's response to RequestDownload
860 const UDSClient_t *client,
861 struct RoutineControlResponse *resp); ///< Parse server's response to RoutineControl
862
863
864#ifdef UDS_LINES
865#line 1 "src/server.h"
866#endif // #ifdef UDS_LINES
867
868
869
870
871
872/**
873 * @brief Server request context
874 */
875typedef struct {
876 uint8_t recv_buf[UDS_SERVER_RECV_BUF_SIZE]; /**< receive buffer */
877 uint8_t send_buf[UDS_SERVER_SEND_BUF_SIZE]; /**< send buffer */
878 size_t recv_len; /**< received data length */
879 size_t send_len; /**< send data length */
880 size_t send_buf_size; /**< send buffer size */
881 UDSSDU_t info; /**< service data unit information */
882} UDSReq_t;
883
884/**
885 * @brief UDS server structure
886 */
887typedef struct UDSServer {
888 UDSTp_t *tp; /**< transport layer handle */
889 UDSErr_t (*fn)(struct UDSServer *srv, UDSEvent_t event, void *arg); /**< callback function */
890 void *fn_data; /**< user-specified function data */
891
892 /**
893 * @brief Server time constants (milliseconds)
894 */
895 uint16_t p2_ms; /**< Default P2_server_max timing supported by the server */
896 uint32_t p2_star_ms; /**< Enhanced (NRC 0x78) P2_server_max supported by the server */
897 uint16_t s3_ms; /**< Session timeout */
898
899 uint8_t ecuResetScheduled; /**< nonzero indicates that an ECUReset has been scheduled */
900 uint32_t ecuResetTimer; /**< for delaying resetting until a response has been sent */
901 uint32_t p2_timer; /**< for rate limiting server responses */
902 uint32_t s3_session_timeout_timer; /**< indicates that diagnostic session has timed out */
903 uint32_t sec_access_auth_fail_timer; /**< brute-force hardening: rate limit security access */
904 uint32_t sec_access_boot_delay_timer; /**< brute-force hardening: restrict security access until
905 timer expires */
906
907 /**
908 * @brief UDS-1-2013: Table 407 - 0x36 TransferData Supported negative
909 * response codes requires that the server keep track of whether the
910 * transfer is active
911 */
912 bool xferIsActive; /**< transfer is active */
913 uint8_t xferBlockSequenceCounter; /**< UDS-1-2013: 14.4.2.3, Table 404: block sequence counter
914 starts at 0x01 */
915 size_t xferTotalBytes; /**< total transfer size in bytes requested by the client */
916 size_t xferByteCounter; /**< total number of bytes transferred */
917 size_t xferBlockLength; /**< block length (convenience for the TransferData API) */
918
919 uint8_t sessionType; /**< diagnostic session type (0x10) */
920 uint8_t securityLevel; /**< SecurityAccess (0x27) level */
921
922 bool RCRRP; /**< set to true when user fn returns 0x78 and false otherwise */
923 bool requestInProgress; /**< set to true when a request has been processed but the response has
924 not yet been sent */
925
926 /**
927 * @brief UDS-1 2013 defines the following conditions under which the server does not
928 * process incoming requests:
929 * - not ready to receive (Table A.1 0x78)
930 * - not accepting request messages and not sending responses (9.3.1)
931 *
932 * when this variable is set to true, incoming ISO-TP data will not be processed.
933 */
934 bool notReadyToReceive; /**< incoming ISO-TP data will not be processed */
935
936 UDSReq_t r; /**< request context */
938
939/**
940 * @brief Diagnostic session control arguments
941 */
942typedef struct {
943 const uint8_t type; /**< oneof @ref uds_lev_ds_ */
944 uint16_t p2_ms; /**< optional: p2 timing override */
945 uint32_t p2_star_ms; /**< optional: p2* timing override */
947
948/**
949 * @brief ECU reset arguments
950 */
951typedef struct {
952 const uint8_t type; /**< reset type requested by client */
953 uint32_t powerDownTimeMillis; /**< when this much time has elapsed after a UDS_PositiveResponse,
954 a UDS_EVT_DoScheduledReset will be issued */
956
957/**
958 * @brief Clear diagnostic information arguments
959 */
960typedef struct {
961 const uint32_t groupOfDTC; /**< lower 3 bytes describe the groupOfDTC */
962 const bool hasMemorySelection; /**< `true` when a memory selection byte is present */
963 const uint8_t memorySelection; /**< memorySelection byte (optional) */
965
966/**
967 * @brief Read DTC information arguments
968 */
969typedef struct {
970 const uint8_t type; /**< invoked subfunction */
971 uint8_t (*copy)(UDSServer_t *srv, const void *src,
972 uint16_t count); /**< function for copying data */
973
974 /* cppcheck-suppress [misra-c2012-19.2] */
975 union {
976 struct {
977 uint8_t mask; /**< DTC status mask */
978 } numOfDTCByStatusMaskArgs; /**< args for number of DTCs by status mask */
979 struct {
980 uint8_t mask; /**< DTC status mask */
981 } dtcStatusByMaskArgs; /**< args for DTCs by status mask */
982 struct {
983 uint32_t dtc; /**< DTC Mask Record */
984 uint8_t snapshotNum; /**< DTC Snaphot Record Number */
985 } dtcSnapshotRecordbyDTCNumArgs; /**< args for DTC snapshot record by DTC number */
986 struct {
987 uint32_t dtc; /**< DTC Mask Record */
988 uint8_t snapshotNum; /**< DTC Snaphot Record Number */
989 uint8_t memory; /**< Memory Selection */
990 } userDefMemDTCSnapshotRecordByDTCNumArgs; /**< args for user-defined-memory DTC snapshot
991 record by DTC number */
992 struct {
993 uint8_t recordNum; /**< DTC Data Record Number */
994 } dtcStoredDataByRecordNumArgs; /**< args for DTC stored data by record number */
995 struct {
996 uint8_t recordNum; /**< DTC Data Record Number */
997 } dtcExtDataRecordByRecordNumArgs; /**< args for DTC extended data record by record number
998 */
999 struct {
1000 uint8_t recordNum; /**< DTC Data Record Number */
1001 } dtcExtDataRecordIdArgs; /**< args for supported DTC extended data record ID */
1002 struct {
1003 uint32_t dtc; /**< DTC Mask Record */
1004 uint8_t extDataRecNum; /**< DTC Extended Data Record Number */
1005 } dtcExtDtaRecordByDTCNumArgs; /**< args for DTC extended data record by DTC number */
1006 struct {
1007 uint32_t dtc; /**< DTC Mask Record */
1008 uint8_t extDataRecNum; /**< DTC Extended Data Record Number */
1009 uint8_t memory; /**< Memory Selection */
1010 } userDefMemDTCExtDataRecordByDTCNumArgs; /**< args for user-defined-memory DTC extended
1011 data record by DTC number */
1012 struct {
1013 uint8_t severityMask; /**< DTC Severity Mask */
1014 uint8_t statusMask; /**< DTC Status Mask */
1015 } numOfDTCBySeverityMaskArgs; /**< args for number of DTCs by severity mask */
1016 struct {
1017 uint8_t functionalGroup; /**< Functional Group Identifier */
1018 uint8_t severityMask; /**< DTC Severity Mask */
1019 uint8_t statusMask; /**< DTC Status Mask */
1020 } wwhobdDTCByMaskArgs; /**< args for WWH-OBD DTCs by mask */
1021 struct {
1022 uint32_t dtc; /**< DTC Mask Record */
1023 } severityInfoOfDTCArgs; /**< args for severity information of a DTC */
1024 struct {
1025 uint8_t mask; /**< DTC status mask */
1026 uint8_t memory; /**< Memory Selection */
1027 } userDefMemoryDTCByStatusMaskArgs; /**< args for user-defined-memory DTCs by status mask */
1028 struct {
1029 uint8_t functionalGroup; /**< Functional Group Identifier */
1030 } wwhobdDTCWithPermStatusArgs; /**< args for WWH-OBD DTCs with permanent status */
1031 struct {
1032 uint8_t functionalGroup; /**< Functional Group Identifier */
1033 uint8_t readinessGroup; /**< DTC Readiness Group Identifier */
1034 } dtcInfoByDTCReadinessGroupIdArgs; /**< args for DTCs by readiness group */
1035 /* cppcheck-suppress [misra-c2012-19.2] */
1036 } subFuncArgs; /**< subfunction-specific arguments, selected by \ref type */
1038
1039/**
1040 * @brief Read data by identifier arguments
1041 */
1042typedef struct {
1043 const uint16_t dataId; /**< RDBI Data Identifier */
1044 uint8_t (*copy)(UDSServer_t *srv, const void *src,
1045 uint16_t count); /**< function for copying data */
1047
1048/**
1049 * @brief Read memory by address arguments
1050 */
1051typedef struct {
1052 const uintptr_t memAddr; /**< requested server memory address */
1053 const size_t memSize; /**< requested size */
1054 uint8_t (*copy)(UDSServer_t *srv, const void *src,
1055 uint16_t count); /**< function for copying data to response */
1057
1058/**
1059 * @brief Communication control arguments
1060 */
1061typedef struct {
1062 uint8_t ctrlType; /**< ControlType */
1063 uint8_t commType; /**< CommunicationType */
1064 uint16_t nodeId; /**< NodeIdentificationNumber (only used when ctrlType is 0x04 or 0x05) */
1066
1067/**
1068 * @brief Security access request seed arguments
1069 */
1070typedef struct {
1071 const uint8_t level; /**< requested security level */
1072 const uint8_t *const dataRecord; /**< pointer to request data */
1073 const uint16_t len; /**< size of request data */
1074 uint8_t (*copySeed)(UDSServer_t *srv, const void *src,
1075 uint16_t len); /**< function for copying data */
1077
1078/**
1079 * @brief Security access validate key arguments
1080 */
1081typedef struct {
1082 const uint8_t level; /**< security level to be validated */
1083 const uint8_t *const key; /**< key sent by client */
1084 const uint16_t len; /**< length of key */
1086
1087/**
1088 * @brief Write data by identifier arguments
1089 */
1090typedef struct {
1091 const uint16_t dataId; /**< WDBI Data Identifier */
1092 const uint8_t *const data; /**< pointer to data */
1093 const uint16_t len; /**< length of data */
1095
1096/**
1097 * @brief Write memory by address arguments
1098 */
1099typedef struct {
1100 const uintptr_t memAddr; /**< pointer to memory address */
1101 const size_t memSize; /**< size of memory */
1102 const uint8_t *const data; /**< pointer to data */
1104
1105/**
1106 * @brief Dynamically define data identifier arguments
1107 */
1108typedef struct {
1109 const uint8_t type; /**< invoked subfunction */
1110 bool allDataIds; /**< is true when request is for all data identifiers (only relevant for
1111 subFunc 0x03) */
1112 uint16_t dynamicDataId; /**< dynamicallyDefinedDataIdentifier */
1113
1114 /* cppcheck-suppress [misra-c2012-19.2] */
1115 union {
1116 struct {
1117 uint16_t sourceDataId; /**< source DataIdentifier */
1118 uint8_t position; /**< position in source data record */
1119 uint8_t size; /**< number of bytes to be copied */
1120 } defineById; /**< args when defining from an existing source data identifier */
1121 struct {
1122 uintptr_t memAddr; /**< memory address to read from */
1123 size_t memSize; /**< number of bytes to read */
1124 } defineByMemAddress; /**< args when defining from a memory address */
1125 /* cppcheck-suppress [misra-c2012-19.2] */
1126 } subFuncArgs; /**< subfunction-specific arguments, selected by \ref type */
1128
1129/**
1130 * @brief Input/output control by identifier arguments
1131 */
1132typedef struct {
1133 const uint16_t dataId; /**< Data Identifier */
1134 const uint8_t ioCtrlParam; /**< inputOutputControlParameter */
1135 const void *const ctrlStateAndMask; /**< controlState bytes and controlMask (optional) */
1136 const size_t ctrlStateAndMaskLen; /**< number of bytes in `ctrlStateAndMask` */
1137 uint8_t (*copy)(UDSServer_t *srv, const void *src,
1138 uint16_t count); /**< function for copying data */
1140
1141/**
1142 * @brief Routine control arguments
1143 */
1144typedef struct {
1145 const uint8_t ctrlType; /**< routineControlType */
1146 const uint16_t id; /**< routineIdentifier */
1147 const uint8_t *optionRecord; /**< optional data */
1148 const uint16_t len; /**< length of optional data */
1149 uint8_t (*copyStatusRecord)(UDSServer_t *srv, const void *src,
1150 uint16_t len); /**< function for copying response data */
1152
1153/**
1154 * @brief Request download arguments
1155 */
1156typedef struct {
1157 const uintptr_t addr; /**< requested address */
1158 const size_t size; /**< requested download size */
1159 const uint8_t dataFormatIdentifier; /**< optional specifier for format of data */
1160 uint16_t maxNumberOfBlockLength; /**< optional response: inform client how many data bytes to
1161 send in each `TransferData` request */
1163
1164/**
1165 * @brief Request upload arguments
1166 */
1167typedef struct {
1168 const uintptr_t addr; /**< requested address */
1169 const size_t size; /**< requested download size */
1170 const uint8_t dataFormatIdentifier; /**< optional specifier for format of data */
1171 uint16_t maxNumberOfBlockLength; /**< optional response: inform client how many data bytes to
1172 send in each `TransferData` request */
1174
1175/**
1176 * @brief Transfer data arguments
1177 */
1178typedef struct {
1179 const uint8_t *const data; /**< transfer data */
1180 const uint16_t len; /**< transfer data length */
1181 const uint16_t maxRespLen; /**< don't send more than this many bytes with copyResponse */
1182 uint8_t (*copyResponse)(
1183 UDSServer_t *srv, const void *src,
1184 uint16_t len); /**< function for copying transfer data response data (optional) */
1186
1187/**
1188 * @brief Request transfer exit arguments
1189 */
1190typedef struct {
1191 const uint8_t *const data; /**< request data */
1192 const uint16_t len; /**< request data length */
1193 uint8_t (*copyResponse)(UDSServer_t *srv, const void *src,
1194 uint16_t len); /**< function for copying response data (optional) */
1196
1197/**
1198 * @brief Request file transfer arguments
1199 */
1200typedef struct {
1201 /**
1202 * request:
1203 * @see @ref uds_moop_ "modeOfOperation values"
1204 */
1205 const uint8_t modeOfOperation;
1206 const uint16_t filePathLen; /**< request: data length. */
1207 const uint8_t *filePath; /**< request: file path or directory name (ReadDirectory). */
1208 const uint8_t dataFormatIdentifier; /**< request: specifier for format of data (does not apply
1209 to DeleteFile or ReadDir) */
1210
1211 // if MOOP is AddFile, ReplaceFile, or ResumeFile, these fields are **requests**.
1212 // if MOOP is ReadFile or ReadDirectory, these fields are **responses** -- the server must set
1213 // them. if MOOP is DelFile, these fields are unused.
1214 size_t fileSizeUnCompressed; /**< file size or directory info len (ReadDirectory) */
1215 size_t fileSizeCompressed; /**< compressed filesize (ReadFile), otherwise zero. */
1216
1217 uint16_t maxNumberOfBlockLength; /**< response: Defaults to UDS_TP_MTU. Informs client how many
1218 data bytes to send in each `TransferData` request. (unused
1219 by DelFile). */
1220 size_t filePosition; /**< response: byte position to resume from after suspended download
1221 (ResumeFile), otherwise zero. */
1223
1224/**
1225 * @brief Control DTC setting arguments
1226 */
1227typedef struct {
1228 uint8_t type; /**< invoked subfunction */
1229 size_t len; /**< length of data */
1230 void *data; /**< DTCSettingControlOptionRecord */
1232
1233/**
1234 * @brief Link control arguments
1235 */
1236typedef struct {
1237 const uint8_t type; /**< invoked subfunction */
1238 /* purposefully left generic to allow vehicle- and supplier specific data of different sizes */
1239 const size_t len; /**< length of data */
1240 const void *data; /**< data used in the subfunction. E.g. on SubFunction 0x01 this is the
1241 linkControlModelIdentifier, on SubFunction 0x02 this is the linkRecord */
1243
1244/**
1245 * @brief Custom service arguments
1246 */
1247typedef struct {
1248 const uint16_t sid; /**< serviceIdentifier */
1249 const uint8_t *optionRecord; /**< optional data */
1250 const uint16_t len; /**< length of optional data */
1251 uint8_t (*copyResponse)(UDSServer_t *srv, const void *src,
1252 uint16_t len); /**< function for copying response data (optional) */
1254
1255UDSErr_t UDSServerInit(UDSServer_t *srv); ///< call this once
1256void UDSServerPoll(UDSServer_t *srv); ///< Call this at <5ms intervals
1257
1258#if defined(UDS_TP_ISOTP_C)
1259/// \cond DOXYGEN_SHOULD_SKIP_THIS
1260////////////////////////////////////////////////////////////////////////
1261#ifdef UDS_LINES
1262#line 1 "src/tp/isotp-c/isotp_config.h"
1263#endif // #ifdef UDS_LINES
1264// ___ ___ ___ _____ ___ ___ //
1265// |_ _/ __|/ _ \_ _| _ \___ / __| //
1266// | |\__ \ (_) || | | _/___| (__ //
1267// |___|___/\___/ |_| |_| \___| //
1268// //
1269// ___ ___ _ _ ___ ___ ___ //
1270// / __/ _ \| \| | __|_ _/ __| //
1271// | (_| (_) | .` | _| | | (_ | //
1272// \___\___/|_|\_|_| |___\___| //
1273// //
1274////////////////////////////////////////////////////////////////////////
1275
1276#ifndef ISOTPC_CONFIG_H
1277#define ISOTPC_CONFIG_H
1278
1279/**
1280 * @file isotp_config.h
1281 * @brief Compile-time transport configuration and defaults.
1282 *
1283 * Prefer the corresponding CMake or Make settings when using a supplied build
1284 * system. Direct builds must define ABI-affecting options identically while
1285 * compiling the library and every consumer.
1286 */
1287
1288/** @defgroup isotp_config Compile-time configuration
1289 * @brief Macros controlling frame sizes, timing, optional APIs, and platform integration.
1290 * @{ */
1291
1292/** The maximum amount of data bytes a single CAN frame may carry (CAN_DL).
1293 * Classical CAN is limited to 8 bytes; CAN FD additionally allows frames of
1294 * 12, 16, 20, 24, 32, 48 and 64 bytes.
1295 *
1296 * Set this to one of the CAN FD lengths to enable CAN FD support. This
1297 * increases the size of the internal frame buffers accordingly, so leave it at
1298 * 8 on platforms without CAN FD.
1299 */
1300#ifndef ISO_TP_MAX_CAN_FRAME_SIZE
1301 #define ISO_TP_MAX_CAN_FRAME_SIZE 8
1302#endif
1303
1304/** The CAN_DL (TX_DL) used by a freshly initialised link.
1305 * This may be reduced per link at runtime using isotp_set_tx_dl(), e.g. when a
1306 * peer only supports Classical CAN frame lengths.
1307 */
1308#ifndef ISO_TP_DEFAULT_TX_DL
1309 #define ISO_TP_DEFAULT_TX_DL ISO_TP_MAX_CAN_FRAME_SIZE
1310#endif
1311
1312/** Flow Control block size advertised by the receiver.
1313 * A value of 0 asks the sender not to wait for further block acknowledgements.
1314 */
1315#ifndef ISO_TP_DEFAULT_BLOCK_SIZE
1316 #define ISO_TP_DEFAULT_BLOCK_SIZE 8
1317#endif
1318
1319/** Minimum Consecutive Frame separation requested by the receiver, in microseconds.
1320 */
1321#ifndef ISO_TP_DEFAULT_ST_MIN_US
1322 #define ISO_TP_DEFAULT_ST_MIN_US 0
1323#endif
1324
1325/** Maximum number of Flow Control Wait frames accepted during transmission.
1326 */
1327#ifndef ISO_TP_MAX_WFT_NUMBER
1328 #define ISO_TP_MAX_WFT_NUMBER 1
1329#endif
1330
1331/** Timeout for required Flow Control or Consecutive Frames, in microseconds.
1332 * Keep this below half the range of the 32-bit microsecond clock so wrapping
1333 * deadline comparisons remain unambiguous.
1334 */
1335#ifndef ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US
1336 #define ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US 100000
1337#endif
1338
1339/** @def ISO_TP_FRAME_PADDING
1340 * Pad transmitted Classical CAN frames to TX_DL. CAN FD frames larger than
1341 * eight bytes are always padded to a legal CAN FD data length.
1342 */
1343#ifdef DOXYGEN
1344 #define ISO_TP_FRAME_PADDING
1345#endif
1346
1347/** @def ISO_TP_NO_FORMATTED_ERRORS
1348 * Omit the two formatted error messages, which are the library's only
1349 * use of snprintf(). Define this on a target whose libc has no snprintf, or
1350 * where the 128-byte ISOTP_MAX_ERROR_MSG_SIZE stack buffer is unwelcome. The
1351 * errors are still reported through isotp_user_debug(), without the values.
1352 *
1353 * Measured on Cortex-M4, -Os -DNDEBUG: .text 2235 -> 2091 bytes, and the
1354 * largest stack frame 160 -> 32 bytes. With this and NDEBUG the object needs
1355 * nothing from libc but memcpy and memset.
1356 */
1357#ifdef DOXYGEN
1358 #define ISO_TP_NO_FORMATTED_ERRORS
1359#endif
1360
1361
1362/** Byte written into unused padded frame positions. */
1363#ifndef ISO_TP_FRAME_PADDING_VALUE
1364 #define ISO_TP_FRAME_PADDING_VALUE 0xAA
1365#endif
1366
1367/** @def ISO_TP_USER_SEND_CAN_ARG
1368 * Append the link's user_send_can_arg value to isotp_user_send_can(). This
1369 * changes the shim signature and the public IsoTpLink layout.
1370 */
1371#ifdef DOXYGEN
1372 #define ISO_TP_USER_SEND_CAN_ARG
1373#endif
1374
1375/** @def ISO_TP_USER_SEND_CAN_FLAGS
1376 * Add a frame-flags argument to isotp_user_send_can(), telling the driver whether a frame has to be
1377 * transmitted as a CAN FD frame. Enable this if the driver cannot derive the
1378 * frame format from the frame length. When combined with
1379 * ISO_TP_USER_SEND_CAN_ARG, the flags argument comes first.
1380 */
1381#ifdef DOXYGEN
1382 #define ISO_TP_USER_SEND_CAN_FLAGS
1383#endif
1384
1385/** @def ISO_TP_CAN_FD_USE_BRS
1386 * Add ISOTP_CAN_FRAME_FLAG_BRS to CAN FD transmissions. This has an effect only
1387 * with ISO_TP_USER_SEND_CAN_FLAGS.
1388 */
1389#ifdef DOXYGEN
1390 #define ISO_TP_CAN_FD_USE_BRS
1391#endif
1392
1393/** @def ISO_TP_TRANSMIT_COMPLETE_CALLBACK
1394 * Add the transmit callback type, registration API, and link state.
1395 */
1396#ifdef DOXYGEN
1397 #define ISO_TP_TRANSMIT_COMPLETE_CALLBACK
1398#endif
1399
1400/** @def ISO_TP_RECEIVE_COMPLETE_CALLBACK
1401 * Add the receive callback type, registration API, and link state.
1402 */
1403#ifdef DOXYGEN
1404 #define ISO_TP_RECEIVE_COMPLETE_CALLBACK
1405#endif
1406
1407/** @def ISO_TP_ENABLE_STREAMING
1408 * Add isotp_receive_streaming() and link state for receiving messages larger
1409 * than the receive buffer in application-consumable chunks.
1410 */
1411#ifdef DOXYGEN
1412 #define ISO_TP_ENABLE_STREAMING
1413#endif
1414
1415/** @} */
1416
1417#endif // ISOTPC_CONFIG_H
1418
1419#ifndef ISOTPC_USER_DEFINITIONS_H
1420#ifdef UDS_LINES
1421#line 1 "src/tp/isotp-c/isotp_defines.h"
1422#endif // #ifdef UDS_LINES
1423#define ISOTPC_USER_DEFINITIONS_H
1424
1425/**
1426 * @file isotp_defines.h
1427 * @brief Public result codes, CAN frame constants, and callback types.
1428 */
1429
1430
1431
1432
1433
1434/**************************************************************
1435 * compiler specific defines
1436 *************************************************************/
1437#ifdef __GNUC__
1438 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1439 #define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1440 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1441 #else
1442 #error "unsupported byte ordering"
1443 #endif
1444#endif
1445
1446/**************************************************************
1447 * OS specific defines
1448 *************************************************************/
1449#ifdef _MSC_VER
1450
1451 #define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1452#endif
1453
1454#if defined(_MSC_VER) && _MSC_VER < 1900
1455 #define ISOTP_SNPRINTF _snprintf
1456#else
1457 #define ISOTP_SNPRINTF snprintf
1458#endif
1459
1460#define LE32TOH(le) ((uint32_t)(((le) << 24) | (((le) & 0x0000FF00) << 8) | (((le) & 0x00FF0000) >> 8) | ((le) >> 24)))
1461
1462/**************************************************************
1463 * CAN frame length (CAN_DL) defines
1464 *************************************************************/
1465
1466/** @defgroup isotp_can CAN frame constants
1467 * @brief Values used to configure CAN and CAN FD transmission.
1468 * @{ */
1469
1470/** Number of payload bytes in a full Classical CAN frame. */
1471#define ISOTP_CAN_DL_CLASSIC 8
1472
1473#if (ISO_TP_MAX_CAN_FRAME_SIZE != 8) && (ISO_TP_MAX_CAN_FRAME_SIZE != 12) && (ISO_TP_MAX_CAN_FRAME_SIZE != 16) && (ISO_TP_MAX_CAN_FRAME_SIZE != 20) && \
1474 (ISO_TP_MAX_CAN_FRAME_SIZE != 24) && (ISO_TP_MAX_CAN_FRAME_SIZE != 32) && (ISO_TP_MAX_CAN_FRAME_SIZE != 48) && (ISO_TP_MAX_CAN_FRAME_SIZE != 64)
1475 #error "ISO_TP_MAX_CAN_FRAME_SIZE must be one of 8, 12, 16, 20, 24, 32, 48, 64"
1476#endif
1477
1478#if (ISO_TP_DEFAULT_TX_DL > ISO_TP_MAX_CAN_FRAME_SIZE) || (ISO_TP_DEFAULT_TX_DL < ISOTP_CAN_DL_CLASSIC)
1479 #error "ISO_TP_DEFAULT_TX_DL must be at least 8 and must not exceed ISO_TP_MAX_CAN_FRAME_SIZE"
1480#endif
1481
1482/** Transmit a Classical CAN frame; no optional frame properties are set. */
1483#define ISOTP_CAN_FRAME_FLAG_NONE 0x00
1484/** Transmit a CAN FD frame. */
1485#define ISOTP_CAN_FRAME_FLAG_FD 0x01
1486/** Enable CAN FD bit-rate switching for the data phase. */
1487#define ISOTP_CAN_FRAME_FLAG_BRS 0x02
1488
1489/**
1490 * Largest ISO-TP payload that fits in one frame for a given CAN_DL.
1491 *
1492 * CAN FD data lengths use the two-byte SF_DL escape header; Classical CAN uses
1493 * a one-byte header.
1494 */
1495#define ISOTP_SF_MAX_PAYLOAD(can_dl) ((can_dl) > ISOTP_CAN_DL_CLASSIC ? (uint32_t)((can_dl) - 2u) : (uint32_t)((can_dl) - 1u))
1496
1497/** @} */
1498
1499/**************************************************************
1500 * Result codes
1501 *************************************************************/
1502/** @defgroup isotp_results Return values
1503 * @brief Status values returned by the transport API and platform send shim.
1504 * @{ */
1505
1506/** Operation succeeded or a frame was accepted by the CAN driver. */
1507#define ISOTP_RET_OK 0
1508/** Invalid argument, incompatible receive mode, or permanent driver failure. */
1509#define ISOTP_RET_ERROR -1
1510/** A segmented transmission is already active. */
1511#define ISOTP_RET_INPROGRESS -2
1512/** A payload exceeds the configured link buffer. */
1513#define ISOTP_RET_OVERFLOW -3
1514/** A Consecutive Frame used an unexpected sequence number. */
1515#define ISOTP_RET_WRONG_SN -4
1516/** No completed message or streaming chunk is available. */
1517#define ISOTP_RET_NO_DATA -5
1518/** A protocol response was not received before its deadline. */
1519#define ISOTP_RET_TIMEOUT -6
1520/** A CAN frame or declared ISO-TP payload length is invalid. */
1521#define ISOTP_RET_LENGTH -7
1522/** Temporary CAN-driver backpressure, or a streaming destination that is too small. */
1523#define ISOTP_RET_NOSPACE -8
1524
1525/** @} */
1526
1527/** @cond ISOTP_INTERNAL */
1528
1529/* return logic true if 'a' is after 'b' */
1530#define IsoTpTimeAfter(a, b) ((int32_t)((int32_t)(b) - (int32_t)(a)) < 0)
1531
1532/* invalid bs */
1533#define ISOTP_INVALID_BS 0xFFFF
1534
1535/* Define the maximum amount of characters allowed in an error message. This fixes code which would otherwise break on Microsoft's dumb platform. */
1536#define ISOTP_MAX_ERROR_MSG_SIZE 128
1537
1538/** @endcond */
1539
1540/** @defgroup isotp_status Link status and protocol results
1541 * @brief Observable state for asynchronous send and receive operations.
1542 * @{ */
1543
1544/** Current segmented-transmission state stored in IsoTpLink::send_status. */
1545typedef enum {
1546 ISOTP_SEND_STATUS_IDLE, /**< No segmented transmission is active. */
1547 ISOTP_SEND_STATUS_INPROGRESS, /**< Consecutive Frames or Flow Control are pending. */
1548 ISOTP_SEND_STATUS_ERROR, /**< Transmission stopped; inspect IsoTpLink::send_protocol_result. */
1549} IsoTpSendStatusTypes;
1550
1551/** Current reassembly state stored in IsoTpLink::receive_status. */
1552typedef enum {
1553 ISOTP_RECEIVE_STATUS_IDLE, /**< No message is being reassembled. */
1554 ISOTP_RECEIVE_STATUS_INPROGRESS, /**< Consecutive Frames are expected. */
1555 ISOTP_RECEIVE_STATUS_FULL, /**< A complete message or streaming chunk is available. */
1556} IsoTpReceiveStatusTypes;
1557
1558/** @} */
1559
1560/** @cond ISOTP_INTERNAL */
1561
1562/* can fram defination */
1563#if defined(ISOTP_BYTE_ORDER_LITTLE_ENDIAN)
1564typedef struct {
1565 uint8_t reserve_1 : 4;
1566 uint8_t type : 4;
1567 uint8_t reserve_2[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1568} IsoTpPciType;
1569
1570typedef struct {
1571 uint8_t SF_DL : 4;
1572 uint8_t type : 4;
1573 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1574} IsoTpSingleFrame;
1575
1576typedef struct {
1577 uint8_t set_to_zero : 4;
1578 uint8_t type : 4;
1579 uint8_t SF_DL;
1580 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 2];
1581} IsoTpSingleFrameEscape;
1582
1583typedef struct {
1584 uint8_t FF_DL_high : 4;
1585 uint8_t type : 4;
1586 uint8_t FF_DL_low;
1587 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 2];
1588} IsoTpFirstFrameShort;
1589
1590#pragma pack(push, 1)
1591typedef struct {
1592 uint8_t set_to_zero_high : 4;
1593 uint8_t type : 4;
1594 uint8_t set_to_zero_low;
1595 uint32_t FF_DL;
1596 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 6];
1597} IsoTpFirstFrameLong;
1598#pragma pack(pop)
1599
1600typedef struct {
1601 uint8_t SN : 4;
1602 uint8_t type : 4;
1603 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1604} IsoTpConsecutiveFrame;
1605
1606typedef struct {
1607 uint8_t FS : 4;
1608 uint8_t type : 4;
1609 uint8_t BS;
1610 uint8_t STmin;
1611 uint8_t reserve[ISO_TP_MAX_CAN_FRAME_SIZE - 3];
1612} IsoTpFlowControl;
1613
1614#else
1615
1616typedef struct {
1617 uint8_t type : 4;
1618 uint8_t reserve_1 : 4;
1619 uint8_t reserve_2[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1620} IsoTpPciType;
1621
1622/*
1623 * single frame
1624 * +-------------------------+-----+
1625 * | byte #0 | ... |
1626 * +-------------------------+-----+
1627 * | nibble #0 | nibble #1 | ... |
1628 * +-------------+-----------+ ... +
1629 * | PCIType = 0 | SF_DL | ... |
1630 * +-------------+-----------+-----+
1631 */
1632typedef struct {
1633 uint8_t type : 4;
1634 uint8_t SF_DL : 4;
1635 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1636} IsoTpSingleFrame;
1637
1638/*
1639 * single frame using the SF_DL escape sequence (CAN FD only, CAN_DL > 8)
1640 * +-------------------------+-----------------------+-----+
1641 * | byte #0 | byte #1 | ... |
1642 * +-------------------------+-----------+-----------+-----+
1643 * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... |
1644 * +-------------+-----------+-----------+-----------+-----+
1645 * | PCIType = 0 | unused=0 | SF_DL | ... |
1646 * +-------------+-----------+-----------------------+-----+
1647 */
1648typedef struct {
1649 uint8_t type : 4;
1650 uint8_t set_to_zero : 4;
1651 uint8_t SF_DL;
1652 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 2];
1653} IsoTpSingleFrameEscape;
1654
1655/*
1656 * first frame short
1657 * +-------------------------+-----------------------+-----+
1658 * | byte #0 | byte #1 | ... |
1659 * +-------------------------+-----------+-----------+-----+
1660 * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... |
1661 * +-------------+-----------+-----------+-----------+-----+
1662 * | PCIType = 1 | FF_DL | ... |
1663 * +-------------+-----------+-----------------------+-----+
1664 */
1665typedef struct {
1666 uint8_t type : 4;
1667 uint8_t FF_DL_high : 4;
1668 uint8_t FF_DL_low;
1669 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 2];
1670} IsoTpFirstFrameShort;
1671
1672/*
1673 * first frame long
1674 * +-------------------------+-----------------------+---------+---------+---------+---------+
1675 * | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 |
1676 * +-------------------------+-----------+-----------+---------+---------+---------+---------+
1677 * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... |
1678 * +-------------+-----------+-----------+-----------+---------------------------------------+
1679 * | PCIType = 1 | unused=0 | escape sequence = 0 | FF_DL |
1680 * +-------------+-----------+-----------------------+---------------------------------------+
1681 */
1682#pragma pack(push, 1)
1683typedef struct {
1684 uint8_t type : 4;
1685 uint8_t set_to_zero_high : 4;
1686 uint8_t set_to_zero_low;
1687 uint32_t FF_DL;
1688 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 6];
1689} IsoTpFirstFrameLong;
1690#pragma pack(pop)
1691
1692/*
1693 * consecutive frame
1694 * +-------------------------+-----+
1695 * | byte #0 | ... |
1696 * +-------------------------+-----+
1697 * | nibble #0 | nibble #1 | ... |
1698 * +-------------+-----------+ ... +
1699 * | PCIType = 0 | SN | ... |
1700 * +-------------+-----------+-----+
1701 */
1702typedef struct {
1703 uint8_t type : 4;
1704 uint8_t SN : 4;
1705 uint8_t data[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
1706} IsoTpConsecutiveFrame;
1707
1708/*
1709 * flow control frame
1710 * +-------------------------+-----------------------+-----------------------+-----+
1711 * | byte #0 | byte #1 | byte #2 | ... |
1712 * +-------------------------+-----------+-----------+-----------+-----------+-----+
1713 * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | nibble #4 | nibble #5 | ... |
1714 * +-------------+-----------+-----------+-----------+-----------+-----------+-----+
1715 * | PCIType = 1 | FS | BS | STmin | ... |
1716 * +-------------+-----------+-----------------------+-----------------------+-----+
1717 */
1718typedef struct {
1719 uint8_t type : 4;
1720 uint8_t FS : 4;
1721 uint8_t BS;
1722 uint8_t STmin;
1723 uint8_t reserve[ISO_TP_MAX_CAN_FRAME_SIZE - 3];
1724} IsoTpFlowControl;
1725
1726#endif
1727
1728typedef struct {
1729 uint8_t ptr[ISO_TP_MAX_CAN_FRAME_SIZE];
1730} IsoTpDataArray;
1731
1732typedef struct {
1733 union {
1734 IsoTpPciType common;
1735 IsoTpSingleFrame single_frame;
1736 IsoTpSingleFrameEscape single_frame_escape;
1737 IsoTpFirstFrameShort first_frame_short;
1738 IsoTpFirstFrameLong first_frame_long;
1739 IsoTpConsecutiveFrame consecutive_frame;
1740 IsoTpFlowControl flow_control;
1741 IsoTpDataArray data_array;
1742 } as;
1743} IsoTpCanMessage;
1744
1745/** @endcond */
1746
1747/**************************************************************
1748 * Callback types
1749 *************************************************************/
1750
1751#ifdef ISO_TP_TRANSMIT_COMPLETE_CALLBACK
1752/**
1753 * @brief Called after a complete payload has been transmitted successfully.
1754 *
1755 * @param link Link that completed transmission. Cast to IsoTpLink* when needed.
1756 * @param tx_size Size of the completed ISO-TP payload in bytes.
1757 * @param user_arg Value registered with isotp_set_tx_done_cb().
1758 */
1759typedef void (*isotp_tx_done_cb)(void* link, uint32_t tx_size, void* user_arg);
1760#endif
1761
1762#ifdef ISO_TP_RECEIVE_COMPLETE_CALLBACK
1763/**
1764 * @brief Called after a complete payload has been received successfully.
1765 *
1766 * @param link Link that received the payload. Cast to IsoTpLink* when needed.
1767 * @param data Link-owned payload, valid only for the duration of the callback.
1768 * @param size Payload size in bytes.
1769 * @param user_arg Value registered with isotp_set_rx_done_cb().
1770 */
1771typedef void (*isotp_rx_done_cb)(void* link, const uint8_t* data, uint32_t size, void* user_arg);
1772#endif
1773
1774/** @cond ISOTP_INTERNAL */
1775/* Protocol Control Information (PCI) types. */
1776typedef enum {
1777 ISOTP_PCI_TYPE_SINGLE = 0x0,
1778 ISOTP_PCI_TYPE_FIRST_FRAME = 0x1,
1779 TSOTP_PCI_TYPE_CONSECUTIVE_FRAME = 0x2,
1780 ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME = 0x3,
1781
1782 ISOTP_PCI_TYPE_CONSECUTIVE_FRAME = 0x2, // Typo fix; but keep broken value for backwards-compat.
1783} IsoTpProtocolControlInformation;
1784
1785/* Private: Protocol Control Information (PCI) flow control identifiers.
1786 */
1787typedef enum { PCI_FLOW_STATUS_CONTINUE = 0x0, PCI_FLOW_STATUS_WAIT = 0x1, PCI_FLOW_STATUS_OVERFLOW = 0x2 } IsoTpFlowStatus;
1788
1789/** @endcond */
1790
1791/** @addtogroup isotp_status
1792 * @{ */
1793/** Protocol operation completed without an error. */
1794#define ISOTP_PROTOCOL_RESULT_OK 0
1795/** Reserved result for an N_As transmission timeout; not currently produced. */
1796#define ISOTP_PROTOCOL_RESULT_TIMEOUT_A -1
1797/** Timeout waiting for a Flow Control frame. */
1798#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS -2
1799/** Timeout waiting for a Consecutive Frame. */
1800#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR -3
1801/** An incoming Consecutive Frame had the wrong sequence number. */
1802#define ISOTP_PROTOCOL_RESULT_WRONG_SN -4
1803/** Reserved result for invalid Flow Control status; not currently produced. */
1804#define ISOTP_PROTOCOL_RESULT_INVALID_FS -5
1805/** A protocol data unit arrived in an incompatible link state. */
1806#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU -6
1807/** The peer sent more Flow Control Wait frames than ISO_TP_MAX_WFT_NUMBER. */
1808#define ISOTP_PROTOCOL_RESULT_WFT_OVRN -7
1809/** The sender reported overflow, or an incoming message exceeded the receive buffer. */
1810#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW -8
1811/** Reserved generic protocol error; not currently produced. */
1812#define ISOTP_PROTOCOL_RESULT_ERROR -9
1813
1814/** @} */
1815
1816#endif // ISOTPC_USER_DEFINITIONS_H
1817
1818////////////////////////////////////////////////////////////////////////
1819#ifdef UDS_LINES
1820#line 1 "src/tp/isotp-c/isotp_user.h"
1821#endif // #ifdef UDS_LINES
1822// ___ ___ ___ _____ ___ ___ //
1823// |_ _/ __|/ _ \_ _| _ \___ / __| //
1824// | |\__ \ (_) || | | _/___| (__ //
1825// |___|___/\___/ |_| |_| \___| //
1826// //
1827////////////////////////////////////////////////////////////////////////
1828
1829#ifndef ISOTPC_USER_H
1830#define ISOTPC_USER_H
1831
1832
1833
1834#ifdef __cplusplus
1835extern "C" {
1836#endif
1837
1838/**
1839 * @file isotp_user.h
1840 * @brief Application-provided platform hooks.
1841 */
1842
1843/** @defgroup isotp_platform Platform integration
1844 * @brief Functions that every application supplies to connect ISO-TP to its driver and clock.
1845 * @{ */
1846
1847/**
1848 * @brief Receive a diagnostic message from the library.
1849 *
1850 * The application may implement this as a no-op. Calls can occur from any
1851 * transport API that detects an error. The library does not require the
1852 * message to be retained after this function returns.
1853 *
1854 * @param[in] message Diagnostic string or printf-style format.
1855 * @param[in] ... Optional format arguments.
1856 */
1857void isotp_user_debug(const char* message, ...);
1858
1859/**
1860 * @brief Submit one CAN or CAN FD frame to the application's driver.
1861 *
1862 * The implementation must consume or copy @p data before returning. It may be
1863 * called synchronously from isotp_send(), isotp_on_can_message(),
1864 * isotp_receive_streaming(), or isotp_poll().
1865 *
1866 * @param[in] arbitration_id CAN identifier to transmit.
1867 * @param[in] data Frame payload, valid only for the duration of this call.
1868 * @param[in] size Frame payload length. It never exceeds
1869 * ISO_TP_MAX_CAN_FRAME_SIZE. Lengths above 8 require CAN FD.
1870 * @param[in] flags Present only with ISO_TP_USER_SEND_CAN_FLAGS. A bitwise OR
1871 * of ISOTP_CAN_FRAME_FLAG_FD and ISOTP_CAN_FRAME_FLAG_BRS;
1872 * short frames on a link with TX_DL above 8 still carry the
1873 * FD flag.
1874 * @param[in] arg Present only with ISO_TP_USER_SEND_CAN_ARG. This is the link's
1875 * user_send_can_arg value.
1876 * @retval ISOTP_RET_OK The driver accepted the frame.
1877 * @retval ISOTP_RET_NOSPACE The driver is temporarily full and a polled
1878 * Consecutive Frame should be retried.
1879 * @retval ISOTP_RET_ERROR The frame could not be submitted.
1880 */
1881int isotp_user_send_can(const uint32_t arbitration_id, const uint8_t* data, const uint8_t size
1882#ifdef ISO_TP_USER_SEND_CAN_FLAGS
1883 , const uint8_t flags
1884#endif
1885#ifdef ISO_TP_USER_SEND_CAN_ARG
1886 , void* arg
1887#endif
1888);
1889
1890/**
1891 * @brief Return the current 32-bit monotonic time in microseconds.
1892 *
1893 * The value must advance independently of call frequency. Natural wraparound
1894 * at UINT32_MAX is supported.
1895 *
1896 * @return Current platform tick in microseconds.
1897 */
1898uint32_t isotp_user_get_us(void);
1899
1900/** @} */
1901
1902#ifdef __cplusplus
1903}
1904#endif
1905
1906#endif // ISOTPC_USER_H
1907
1908////////////////////////////////////////////////////////////////////////
1909#ifdef UDS_LINES
1910#line 1 "src/tp/isotp-c/isotp.h"
1911#endif // #ifdef UDS_LINES
1912// ___ ___ ___ _____ ___ ___ //
1913// |_ _/ __|/ _ \_ _| _ \___ / __| //
1914// | |\__ \ (_) || | | _/___| (__ //
1915// |___|___/\___/ |_| |_| \___| //
1916// //
1917////////////////////////////////////////////////////////////////////////
1918
1919#ifndef ISOTPC_H
1920#define ISOTPC_H
1921
1922
1923
1924
1925
1926#ifdef __cplusplus
1927
1928
1929extern "C" {
1930#endif
1931
1932
1933
1934
1935
1936/**
1937 * @file isotp.h
1938 * @brief Public ISO-TP link and transport API.
1939 */
1940
1941/**
1942 * @defgroup isotp_api Transport API
1943 * @brief Functions for creating, driving, sending through, and receiving from an ISO-TP link.
1944 * @{
1945 */
1946
1947/**
1948 * @brief State for one independent, full-duplex ISO-TP conversation.
1949 *
1950 * Allocate one link for each conversation that can have independent send or
1951 * receive state. Initialise it with isotp_init_link() before use and keep the
1952 * object and its buffers alive for the complete lifetime of the link.
1953 *
1954 * Calls that access the same link must be serialised. Applications may observe
1955 * the documented status/result members and set user_send_can_arg when enabled;
1956 * all other members are implementation state.
1957 */
1958typedef struct IsoTpLink {
1959 /** @cond ISOTP_INTERNAL */
1960 /* sender parameters */
1961 uint32_t send_arbitration_id;
1962 uint8_t tx_dl;
1963
1964 uint8_t* send_buffer;
1965 uint32_t send_buf_size;
1966 uint32_t send_size;
1967 uint32_t send_offset;
1968
1969 uint8_t send_sn;
1970 uint32_t send_bs_remain;
1971 uint32_t send_st_min_us;
1972 uint8_t send_wtf_count;
1973 uint32_t send_timer_st;
1974 uint32_t send_timer_bs;
1975 /** @endcond */
1976 /** Result of the current or most recent segmented transmission. */
1977 int32_t send_protocol_result;
1978 /** Current IsoTpSendStatusTypes value. */
1979 uint8_t send_status;
1980 /** @cond ISOTP_INTERNAL */
1981
1982 /* receiver parameters */
1983 uint32_t receive_arbitration_id;
1984 uint8_t rx_dl;
1985
1986 uint8_t* receive_buffer;
1987 uint32_t receive_buf_size;
1988 uint32_t receive_size;
1989 uint32_t receive_offset;
1990
1991 uint8_t receive_sn;
1992 uint8_t receive_bs_count;
1993 uint32_t receive_timer_cr;
1994 /** @endcond */
1995 /** Result of the current or most recent receive operation. */
1996 int receive_protocol_result;
1997 /** Current IsoTpReceiveStatusTypes value. Prefer isotp_receive() to consume completed data. */
1998 uint8_t receive_status;
1999 /** @cond ISOTP_INTERNAL */
2000
2001#ifdef ISO_TP_ENABLE_STREAMING
2002 uint32_t receive_stream_size;
2003 uint8_t receive_streaming;
2004 uint8_t receive_stream_carry_size;
2005 uint8_t receive_stream_carry[ISO_TP_MAX_CAN_FRAME_SIZE - 1];
2006#endif
2007 /** @endcond */
2008
2009#if defined(ISO_TP_USER_SEND_CAN_ARG)
2010 /**
2011 * Application value passed to isotp_user_send_can() for this link.
2012 *
2013 * Set this after isotp_init_link(), which initially clears it to NULL.
2014 * A CAN controller or driver context pointer is a typical value.
2015 */
2016 void* user_send_can_arg;
2017#endif
2018
2019 /** @cond ISOTP_INTERNAL */
2020#ifdef ISO_TP_TRANSMIT_COMPLETE_CALLBACK
2021 isotp_tx_done_cb tx_done_cb;
2022 void* tx_done_cb_arg;
2023#endif
2024
2025#ifdef ISO_TP_RECEIVE_COMPLETE_CALLBACK
2026 isotp_rx_done_cb rx_done_cb;
2027 void* rx_done_cb_arg;
2028#endif
2029 /** @endcond */
2030} IsoTpLink;
2031
2032/**
2033 * @brief Initialise an ISO-TP link and its caller-owned buffers.
2034 *
2035 * The complete link object is cleared. Its transmit identifier is set to
2036 * @p sendid, TX_DL is set to ISO_TP_DEFAULT_TX_DL, and receive and transmit
2037 * state become idle.
2038 *
2039 * @param[out] link Link object to initialise. Must not be NULL.
2040 * @param[in] sendid CAN arbitration identifier used by isotp_send() and by
2041 * Flow Control responses.
2042 * @param[in,out] sendbuf Persistent buffer into which outgoing payloads are
2043 * copied. Must not be NULL when @p sendbufsize is nonzero.
2044 * @param[in] sendbufsize Capacity of @p sendbuf and therefore the maximum
2045 * payload accepted for transmission.
2046 * @param[in,out] recvbuf Persistent reassembly or streaming buffer. Must not be
2047 * NULL when @p recvbufsize is nonzero.
2048 * @param[in] recvbufsize Capacity of @p recvbuf. Without streaming, incoming
2049 * messages larger than this are rejected.
2050 *
2051 * @pre The link is not being used by another call.
2052 * @see isotp_set_tx_dl()
2053 */
2054void isotp_init_link(IsoTpLink* link, uint32_t sendid, uint8_t* sendbuf, uint32_t sendbufsize, uint8_t* recvbuf, uint32_t recvbufsize);
2055
2056/**
2057 * @brief Set the CAN frame data length used to transmit on a link.
2058 *
2059 * A Classical CAN link uses 8. CAN FD links may use 12, 16, 20, 24, 32, 48,
2060 * or 64, subject to the compiled ISO_TP_MAX_CAN_FRAME_SIZE.
2061 *
2062 * @param[in,out] link Initialised link, or NULL.
2063 * @param[in] tx_dl Desired transmit data length.
2064 * @retval ISOTP_RET_OK The value was applied.
2065 * @retval ISOTP_RET_ERROR The link is NULL, the value is not a legal CAN data
2066 * length, or it exceeds ISO_TP_MAX_CAN_FRAME_SIZE.
2067 * @retval ISOTP_RET_INPROGRESS A segmented transmission is active; its TX_DL
2068 * cannot be changed.
2069 *
2070 * @note RX_DL is learned independently from each incoming First Frame.
2071 * @example isotp_example_can_fd.c
2072 */
2073int isotp_set_tx_dl(IsoTpLink* link, uint8_t tx_dl);
2074
2075/**
2076 * @brief Return the effective transmit data length for a link.
2077 *
2078 * @param[in] link Initialised link, or NULL.
2079 * @return The configured TX_DL, with 8 used as a defensive fallback for a
2080 * zero-valued field; returns 0 when @p link is NULL.
2081 */
2082uint8_t isotp_get_tx_dl(const IsoTpLink* link);
2083
2084/**
2085 * @brief Clear a link's state and callback registrations.
2086 *
2087 * No memory is freed because the library owns no allocation. The caller retains
2088 * ownership of the link and both buffers. Passing NULL has no effect.
2089 *
2090 * @param[in,out] link Link to clear, or NULL.
2091 */
2092void isotp_destroy_link(IsoTpLink* link);
2093
2094/**
2095 * @brief Advance segmented transmission and protocol timeouts.
2096 *
2097 * Call this regularly even when completion callbacks are enabled. The required
2098 * frequency depends on the configured separation time and response timeout.
2099 * Single-frame transmission and incoming-frame parsing happen synchronously in
2100 * their respective API calls.
2101 *
2102 * @param[in,out] link Initialised link. Must not be NULL.
2103 * @example isotp_example_polling.c
2104 */
2105void isotp_poll(IsoTpLink* link);
2106
2107/**
2108 * @brief Process one CAN frame already routed to this link.
2109 *
2110 * The application must filter arbitration identifiers before calling this
2111 * function. Frames shorter than two bytes or longer than
2112 * ISO_TP_MAX_CAN_FRAME_SIZE are ignored. Valid frames update receive or
2113 * transmit flow-control state and may synchronously send a Flow Control frame.
2114 * A registered receive callback may run before this function returns.
2115 *
2116 * @param[in,out] link Initialised link. Must not be NULL.
2117 * @param[in] data Frame payload, valid for at least @p len bytes. Must not be NULL.
2118 * @param[in] len CAN payload length in bytes.
2119 */
2120void isotp_on_can_message(IsoTpLink* link, const uint8_t* data, uint8_t len);
2121
2122/**
2123 * @brief Start transmitting a payload with the link's configured CAN identifier.
2124 *
2125 * The payload is copied into the link's send buffer. A Single Frame is sent
2126 * synchronously. For a segmented message, only the First Frame is sent here;
2127 * isotp_poll() sends the remaining Consecutive Frames after Flow Control.
2128 *
2129 * @param[in,out] link Initialised link. Must not be NULL.
2130 * @param[in] payload Payload to copy. Must be valid for at least @p size bytes.
2131 * @param[in] size Payload size. It must not exceed the link's send-buffer capacity.
2132 * @retval ISOTP_RET_OK The Single Frame or First Frame was accepted by the driver.
2133 * @retval ISOTP_RET_OVERFLOW The payload exceeds the link's send buffer.
2134 * @retval ISOTP_RET_INPROGRESS Another segmented transmission is active.
2135 * @return Any other value returned by isotp_user_send_can().
2136 *
2137 * @warning ISOTP_RET_OK does not mean a segmented transmission is complete.
2138 * Keep polling until the completion callback runs or send_status is
2139 * no longer ISOTP_SEND_STATUS_INPROGRESS, then inspect
2140 * send_protocol_result.
2141 */
2142int isotp_send(IsoTpLink* link, const uint8_t payload[], uint32_t size);
2143
2144/**
2145 * @brief Start transmitting with a one-time CAN identifier override.
2146 *
2147 * Behaviour and return values are the same as isotp_send(), except @p id is used
2148 * instead of the identifier stored in the link. This is commonly used for a
2149 * functional-addressing request. ISO-TP functional requests must fit in a
2150 * Single Frame; the library does not enforce that addressing rule.
2151 *
2152 * @param[in,out] link Initialised link, or NULL.
2153 * @param[in] id CAN arbitration identifier for this transmission.
2154 * @param[in] payload Payload to copy. Must be valid for at least @p size bytes.
2155 * @param[in] size Payload size.
2156 * @retval ISOTP_RET_ERROR The link is NULL.
2157 * @retval ISOTP_RET_OK The Single Frame or First Frame was accepted by the driver.
2158 * @retval ISOTP_RET_OVERFLOW The payload exceeds the link's send buffer.
2159 * @retval ISOTP_RET_INPROGRESS Another segmented transmission is active.
2160 * @return Any other value returned by isotp_user_send_can().
2161 */
2162int isotp_send_with_id(IsoTpLink* link, uint32_t id, const uint8_t payload[], uint32_t size);
2163
2164/**
2165 * @brief Copy and consume one completed, non-streaming message.
2166 *
2167 * At most @p payload_size bytes are copied. The completed message is released
2168 * even when the destination is too small, so any uncopied remainder is lost.
2169 *
2170 * @param[in,out] link Initialised link. Must not be NULL.
2171 * @param[out] payload Destination buffer. Must not be NULL.
2172 * @param[in] payload_size Capacity of @p payload.
2173 * @param[out] out_size Number of bytes copied. Must not be NULL.
2174 * @retval ISOTP_RET_OK A completed message was copied and consumed.
2175 * @retval ISOTP_RET_NO_DATA No complete message is available.
2176 * @retval ISOTP_RET_ERROR Streaming reception is active, or a receive callback
2177 * is registered in a build that supports callbacks.
2178 */
2179int isotp_receive(IsoTpLink* link, uint8_t* payload, const uint32_t payload_size, uint32_t* out_size);
2180
2181#ifdef ISO_TP_ENABLE_STREAMING
2182/**
2183 * @brief Copy and consume the next available chunk of an incoming message.
2184 *
2185 * This function supports both oversized streaming messages and messages that
2186 * fit in the normal receive buffer. Consuming an intermediate chunk emits a
2187 * Continue Flow Control frame when more wire data is needed.
2188 *
2189 * @param[in,out] link Initialised link, or NULL.
2190 * @param[out] payload Destination for the complete available chunk, or NULL.
2191 * @param[in] payload_size Capacity of @p payload.
2192 * @param[out] out_size Number of bytes copied, or NULL.
2193 * @param[out] is_complete Set to true when this chunk ends the message, or NULL.
2194 * @retval ISOTP_RET_OK A chunk was copied.
2195 * @retval ISOTP_RET_NO_DATA No chunk is currently available.
2196 * @retval ISOTP_RET_NOSPACE The destination cannot hold the available chunk;
2197 * the chunk remains available.
2198 * @retval ISOTP_RET_ERROR Any required pointer is NULL.
2199 * @example isotp_example_streaming.c
2200 */
2201int isotp_receive_streaming(IsoTpLink* link, uint8_t* payload, const uint32_t payload_size, uint32_t* out_size, bool* is_complete);
2202#endif
2203
2204#ifdef ISO_TP_TRANSMIT_COMPLETE_CALLBACK
2205/**
2206 * @brief Register or clear the successful-transmission callback.
2207 *
2208 * A Single Frame invokes the callback synchronously from isotp_send() or
2209 * isotp_send_with_id(). A segmented transmission invokes it from isotp_poll()
2210 * after the final Consecutive Frame is accepted.
2211 *
2212 * @param[in,out] link Initialised link. Passing NULL has no effect.
2213 * @param[in] cb Callback to register, or NULL to disable notification.
2214 * @param[in] arg Application value passed to @p cb.
2215 */
2216void isotp_set_tx_done_cb(IsoTpLink* link, isotp_tx_done_cb cb, void* arg);
2217#endif
2218
2219#ifdef ISO_TP_RECEIVE_COMPLETE_CALLBACK
2220/**
2221 * @brief Register or clear the completed-receive callback.
2222 *
2223 * The callback runs synchronously from isotp_on_can_message(). Its payload
2224 * pointer refers to the link's receive buffer and is valid only until the
2225 * callback returns. Registering it disables delivery through isotp_receive().
2226 * Oversized streaming messages are still delivered through
2227 * isotp_receive_streaming().
2228 *
2229 * @param[in,out] link Initialised link. Passing NULL has no effect.
2230 * @param[in] cb Callback to register, or NULL to restore polling delivery.
2231 * @param[in] arg Application value passed to @p cb.
2232 * @example isotp_example_callbacks.c
2233 */
2234void isotp_set_rx_done_cb(IsoTpLink* link, isotp_rx_done_cb cb, void* arg);
2235#endif
2236
2237/** @} */
2238
2239#ifdef __cplusplus
2240}
2241#endif
2242
2243#endif // ISOTPC_H
2244
2245
2246/// \endcond
2247#endif // if defined(UDS_TP_ISOTP_C)
2248
2249#ifdef UDS_LINES
2250#line 1 "src/tp/isotp_c.h"
2251#endif // #ifdef UDS_LINES
2252#ifdef UDS_TP_ISOTP_C
2253
2254
2255
2256
2257
2258
2259
2260/**
2261 * @brief isotp-c implementation of \ref UDSTp_t
2262 */
2263typedef struct {
2264 /// \cond DOXYGEN_SHOULD_SKIP_THIS
2265 UDSTp_t hdl;
2266 IsoTpLink phys_link;
2267 IsoTpLink func_link;
2268 uint8_t send_buf[UDS_ISOTP_MTU];
2269 uint8_t recv_buf[UDS_ISOTP_MTU];
2270 uint8_t func_send_buf[8];
2271 uint8_t func_recv_buf[8];
2272 uint32_t phys_sa;
2273 uint32_t phys_ta;
2274 uint32_t func_sa;
2275 uint32_t func_ta;
2276 /// \endcond
2278
2279static_assert(offsetof(UDSTpISOTpC_t, hdl) == 0U, "hdl must be the first member");
2280
2281/**
2282 * @brief Initialize isotp-c transport for \ref UDSServer_t
2283 * @param tp \ref UDSTpISOTpC_t instance.
2284 * @param source_addr Server listens for physical transmissions on this address.
2285 * @param target_addr Server sends responses to this address.
2286 * @param source_addr_func Server listens for functional transmissions on this address.
2287 */
2288UDSErr_t UDSServerTpISOTpCInit(UDSTpISOTpC_t *tp, uint32_t source_addr, uint32_t target_addr,
2289 uint32_t source_addr_func);
2290
2291/**
2292 * @brief Initialize isotp-c transport for \ref UDSClient_t
2293 * @param tp \ref UDSTpISOTpC_t instance.
2294 * @param source_addr Client listens for responses at this address.
2295 * @param target_addr Client sends physical requests to this address.
2296 * @param target_addr_func Client sends functional transmissions to this address.
2297 */
2298UDSErr_t UDSClientTpISOTpCInit(UDSTpISOTpC_t *tp, uint32_t source_addr, uint32_t target_addr,
2299 uint32_t target_addr_func);
2300
2301// Internal API
2302UDSErr_t UDSTpISOTpCInit(UDSTpISOTpC_t *tp, uint32_t sa, uint32_t ta, uint32_t sa_func,
2303 uint32_t ta_func);
2304UDSErr_t UDSTpISOTpCPoll(UDSTp_t *tp);
2305
2306#endif
2307
2308
2309#ifdef UDS_LINES
2310#line 1 "src/tp/isotp_c_socketcan.h"
2311#endif // #ifdef UDS_LINES
2312
2313#ifdef UDS_TP_ISOTP_C_SOCKETCAN
2314
2315
2316
2317
2318/**
2319 * @brief isotp-c over SocketCAN implementation of \ref UDSTp_t
2320 */
2321typedef struct {
2322 /// \cond DOXYGEN_SHOULD_SKIP_THIS
2323 UDSTpISOTpC_t hdl2;
2324 int fd;
2325 char tag[16];
2326 /// \endcond
2328
2329static_assert(offsetof(UDSTpISOTpCSocketCAN_t, hdl2) == 0U, "hdl must be the first member");
2330
2331/**
2332 * @brief Initialize isotp-c over SocketCAN transport for \ref UDSServer_t
2333 * @param tp \ref UDSTpISOTpSocketCAN_t instance.
2334 * @param source_addr Server listens for physical transmissions on this address.
2335 * @param target_addr Server sends responses to this address.
2336 * @param source_addr_func Server listens for functional transmissions on this address.
2337 */
2339 uint32_t source_addr, uint32_t target_addr,
2340 uint32_t source_addr_func);
2341
2342/**
2343 * @brief Initialize isotp-c over SocketCAN transport for \ref UDSClient_t
2344 * @param tp \ref UDSTpISOTpC_t instance.
2345 * @param source_addr Client listens for responses at this address.
2346 * @param target_addr Client sends physical requests to this address.
2347 * @param target_addr_func Client sends functional transmissions to this address.
2348 */
2350 uint32_t source_addr, uint32_t target_addr,
2351 uint32_t target_addr_func);
2352
2353void UDSTpISOTpCSocketCANDeinit(UDSTpISOTpCSocketCAN_t *tp); ///< release socket
2354
2355#endif
2356
2357#ifdef UDS_TP_ISOTP_SOCK
2358#ifdef UDS_LINES
2359#line 1 "src/tp/isotp_sock.h"
2360#endif // #ifdef UDS_LINES
2361
2362
2363
2364
2365
2366/**
2367 * @brief linux ISO-TP socket implementation of \ref UDSTp_t
2368 */
2369typedef struct {
2370 /// \cond DOXYGEN_SHOULD_SKIP_THIS
2371 UDSTp_t hdl;
2372 uint8_t recv_buf[UDS_ISOTP_MTU];
2373 uint8_t send_buf[UDS_ISOTP_MTU];
2374 size_t recv_len;
2375 UDSSDU_t recv_info;
2376 int phys_fd;
2377 int func_fd;
2378 uint32_t phys_sa;
2379 uint32_t phys_ta;
2380 uint32_t func_sa;
2381 uint32_t func_ta;
2382 char tag[16];
2383 /// \endcond
2385
2386static_assert(offsetof(UDSTpIsoTpSock_t, hdl) == 0U, "hdl must be the first member");
2387
2388UDSErr_t UDSServerTpIsoTpSockInit(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
2389 uint32_t target_addr,
2390 uint32_t source_addr_func); ///< for UDSServer_t
2391UDSErr_t UDSClientTpIsoTpSockInit(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
2392 uint32_t target_addr,
2393 uint32_t target_addr_func); ///< for UDSClient_t
2394void UDSTpIsoTpSockDeinit(const UDSTpIsoTpSock_t *tp); ///< release sockets
2395
2396#endif
2397
2398#ifdef UDS_TP_ISOTP_MOCK
2399#ifdef UDS_LINES
2400#line 1 "src/tp/isotp_mock.h"
2401#endif // #ifdef UDS_LINES
2402
2403
2404
2405/// \cond INTERNAL_INTERFACE
2406
2407
2408
2409
2410typedef struct ISOTPMock {
2411 UDSTp_t hdl;
2412 uint8_t recv_buf[UDS_TP_MTU];
2413 uint8_t send_buf[UDS_TP_MTU];
2414 size_t recv_len;
2415 UDSSDU_t recv_info;
2416 uint32_t sa_phys; // source address - physical messages are sent from this address
2417 uint32_t ta_phys; // target address - physical messages are sent to this address
2418 uint32_t sa_func; // source address - functional messages are sent from this address
2419 uint32_t ta_func; // target address - functional messages are sent to this address
2420 uint32_t send_tx_delay_ms; // simulated delay
2421 uint32_t send_buf_size; // simulated size of the send buffer
2422 char name[32]; // name for logging
2423} ISOTPMock_t;
2424
2425static_assert(offsetof(ISOTPMock_t, hdl) == 0U, "ISOTPMock_t must not have any members before hdl");
2426
2427typedef struct {
2428 uint32_t sa_phys; // source address - physical messages are sent from this address
2429 uint32_t ta_phys; // target address - physical messages are sent to this address
2430 uint32_t sa_func; // source address - functional messages are sent from this address
2431 uint32_t ta_func; // target address - functional messages are sent to this address
2432} ISOTPMockArgs_t;
2433
2434/**
2435 * @brief Create a mock transport. It is connected by default to a broadcast network of all other
2436 * mock transports in the same process.
2437 * @param name optional name of the transport (can be NULL)
2438 * @return UDSTp_t*
2439 */
2440UDSTp_t *ISOTPMockNew(const char *name, const ISOTPMockArgs_t *args);
2441void ISOTPMockFree(UDSTp_t *tp);
2442
2443/**
2444 * @brief write all messages to a file
2445 * @note uses UDSMillis() to get the current time
2446 * @param filename log file name (will be overwritten)
2447 */
2448void ISOTPMockLogToFile(const char *filename);
2449void ISOTPMockLogToStdout(void);
2450
2451/**
2452 * @brief clear all transports and close the log file
2453 */
2454void ISOTPMockReset(void);
2455
2456/// \endcond INTERNAL_INTERFACE
2457
2458#endif
2459
2460
2461#ifdef __cplusplus
2462}
2463#endif // #ifdef __cplusplus
2464#endif // #ifndef ISO14229
#define UDS_LOG_VERBOSE
Definition iso14229.h:661
#define UDS_LOG_DEBUG
Definition iso14229.h:660
#define UDS_LOG_NONE
Definition iso14229.h:656
#define UDS_LOG_WARN
Definition iso14229.h:658
#define UDS_LOG_ERROR
Definition iso14229.h:657
#define UDS_LOG_INFO
Definition iso14229.h:659
#define UDS_CLIENT_DEFAULT_P2_MS
default P2 timeout
Definition iso14229.h:146
UDSErr_t UDSSendECUReset(UDSClient_t *client, uint8_t type)
Request ECUReset.
Definition iso14229.c:667
UDSErr_t UDSServerTpISOTpCInit(UDSTpISOTpC_t *tp, uint32_t source_addr, uint32_t target_addr, uint32_t source_addr_func)
Initialize isotp-c transport for UDSServer_t.
Definition iso14229.c:3318
void UDSServerPoll(UDSServer_t *srv)
Call this at <5ms intervals.
Definition iso14229.c:2790
#define UDS_CLIENT_SEND_BUF_SIZE
reduce this at your own risk to save RAM. Fuzz testing is done with the default of UDS_TP_MTU.
Definition iso14229.h:137
UDSErr_t UDSClientTpISOTpCSocketCANInit(UDSTpISOTpCSocketCAN_t *tp, const char *ifname, uint32_t source_addr, uint32_t target_addr, uint32_t target_addr_func)
Initialize isotp-c over SocketCAN transport for UDSClient_t.
Definition iso14229.c:3476
UDSErr_t UDSTpRecv(UDSTp_t *hdl, uint8_t *buf, size_t bufsiz, size_t *recvlen, UDSSDU_t *info)
Receive from transport.
Definition iso14229.c:2891
UDSEvent_t
UDS events.
Definition iso14229.h:277
@ UDS_EVT_Custom
Definition iso14229.h:303
@ UDS_EVT_RequestFileTransfer
Definition iso14229.h:300
@ UDS_EVT_ReadDTCInformation
Definition iso14229.h:283
@ UDS_EVT_ClearDiagnosticInfo
Definition iso14229.h:282
@ UDS_EVT_DiagSessCtrl
Definition iso14229.h:280
@ UDS_EVT_DynamicDefineDataId
Definition iso14229.h:291
@ UDS_EVT_SecAccessRequestSeed
Definition iso14229.h:287
@ UDS_EVT_SessionTimeout
Definition iso14229.h:298
@ UDS_EVT_WriteMemByAddr
Definition iso14229.h:290
@ UDS_EVT_SecAccessValidateKey
Definition iso14229.h:288
@ UDS_EVT_TransferData
Definition iso14229.h:296
@ UDS_EVT_RequestDownload
Definition iso14229.h:294
@ UDS_EVT_RoutineCtrl
Definition iso14229.h:293
@ UDS_EVT_Poll
Definition iso14229.h:305
@ UDS_EVT_WriteDataByIdent
Definition iso14229.h:289
@ UDS_EVT_RequestTransferExit
Definition iso14229.h:297
@ UDS_EVT_ReadMemByAddr
Definition iso14229.h:285
@ UDS_EVT_CommCtrl
Definition iso14229.h:286
@ UDS_EVT_ResponseReceived
Definition iso14229.h:307
@ UDS_EVT_SendComplete
Definition iso14229.h:306
@ UDS_EVT_Idle
Definition iso14229.h:308
@ UDS_EVT_RequestUpload
Definition iso14229.h:295
@ UDS_EVT_LinkControl
Definition iso14229.h:302
@ UDS_EVT_ControlDTCSetting
Definition iso14229.h:301
@ UDS_EVT_IOControl
Definition iso14229.h:292
@ UDS_EVT_EcuReset
Definition iso14229.h:281
@ UDS_EVT_DoScheduledReset
Definition iso14229.h:299
@ UDS_EVT_Err
Definition iso14229.h:278
@ UDS_EVT_MAX
Definition iso14229.h:310
@ UDS_EVT_ReadDataByIdent
Definition iso14229.h:284
UDSErr_t UDSSendTesterPresent(UDSClient_t *client)
What's up?
Definition iso14229.c:701
#define UDS_SERVER_DEFAULT_P2_MS
default P2 duration
Definition iso14229.h:156
#define UDS_CLIENT_DEFAULT_P2_STAR_MS
default P2* timeout
Definition iso14229.h:150
UDSErr_t UDSSendRequestTransferExit(UDSClient_t *client)
Call this when finished with TransferData.
Definition iso14229.c:907
UDSErr_t UDSTpPoll(UDSTp_t *hdl)
call this at <5ms intervals
Definition iso14229.c:2899
UDSErr_t UDSSendRequestDownload(UDSClient_t *client, uint8_t dataFormatIdentifier, uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress, size_t memorySize)
Request to Download via TransferData.
Definition iso14229.c:804
#define UDS_SERVER_SEND_BUF_SIZE
reduce this at your own risk to save RAM. Fuzz testing is done with the default of UDS_TP_MTU.
Definition iso14229.h:127
#define UDS_CLIENT_RECV_BUF_SIZE
reduce this at your own risk to save RAM. Fuzz testing is done with the default of UDS_TP_MTU.
Definition iso14229.h:142
UDSErr_t UDSUnpackSecurityAccessResponse(const UDSClient_t *client, struct SecurityAccessResponse *resp)
Parse server's response to SecurityAccess.
Definition iso14229.c:1099
UDSErr_t UDSServerTpIsoTpSockInit(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr, uint32_t target_addr, uint32_t source_addr_func)
for UDSServer_t
Definition iso14229.c:3717
UDSErr_t UDSSendWDBI(UDSClient_t *client, uint16_t dataIdentifier, const uint8_t *data, uint16_t size)
Write Data By Identifier.
Definition iso14229.c:736
UDSErr_t UDSSendCommCtrl(UDSClient_t *client, uint8_t ctrl, uint8_t comm)
Change communication settings.
Definition iso14229.c:689
#define UDS_TP_MTU
ISOTP is the only supported tp type, so UDS inherits its MTU.
Definition iso14229.h:118
UDSErr_t UDSSendRequestUpload(UDSClient_t *client, uint8_t dataFormatIdentifier, uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress, size_t memorySize)
Request to Upload via TransferData.
Definition iso14229.c:841
uint32_t UDSMillis(void)
Get time in milliseconds.
UDSErr_t UDSUnpackRDBIResponse(UDSClient_t *client, UDSRDBIVar_t *vars, uint16_t numVars)
Parse server's response to RDBI.
Definition iso14229.c:1191
#define UDS_SERVER_DEFAULT_S3_MS
default S3 duration (ISO14229-2 2013 Table 5: 5000 -0/+200 ms)
Definition iso14229.h:164
UDSErr_t UDSUnpackRoutineControlResponse(const UDSClient_t *client, struct RoutineControlResponse *resp)
Parse server's response to RoutineControl.
Definition iso14229.c:1124
UDSErr_t UDSSendSecurityAccess(UDSClient_t *client, uint8_t level, const uint8_t *data, uint16_t size)
Get Security Access.
Definition iso14229.c:1062
unsigned int UDS_LogLevel_t
one of valid values for UDS_LOG_LEVEL
Definition iso14229.h:664
#define UDS_SERVER_DEFAULT_P2_STAR_MS
default P2* duration
Definition iso14229.h:160
UDSErr_t UDSClientTpIsoTpSockInit(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr, uint32_t target_addr, uint32_t target_addr_func)
for UDSClient_t
Definition iso14229.c:3744
#define UDS_SERVER_RECV_BUF_SIZE
reduce this at your own risk to save RAM. Fuzz testing is done with the default of UDS_TP_MTU.
Definition iso14229.h:132
UDSErr_t UDSSendTransferData(UDSClient_t *client, uint8_t blockSequenceCounter, uint16_t blockLength, const uint8_t *data, uint16_t size)
Transfer Data to/from a buffer.
Definition iso14229.c:876
uint8_t UDS_A_TA_Type_t
private: oneof Uds_a_ta_type
Definition iso14229.h:539
UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, uint8_t mode, const char *filePath, size_t filePathLen, size_t fileSizeUncompressed, size_t fileSizeCompressed)
filesystem-based frontend to TransferData
Definition iso14229.c:917
UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, uint8_t type, uint16_t routineIdentifier, const uint8_t *data, uint16_t size)
Request to Twiddle Routines.
Definition iso14229.c:768
UDSErr_t UDSClientTpISOTpCInit(UDSTpISOTpC_t *tp, uint32_t source_addr, uint32_t target_addr, uint32_t target_addr_func)
Initialize isotp-c transport for UDSClient_t.
Definition iso14229.c:3323
UDSErr_t
Error Codes, including NRCs defined by the standard.
Definition iso14229.h:317
void UDSTpISOTpCSocketCANDeinit(UDSTpISOTpCSocketCAN_t *tp)
release socket
Definition iso14229.c:3483
#define UDS_ISOTP_MTU
ISO-TP Maximum Transmission Unit (ISO-15764-2-2004 section 5.3.3).
Definition iso14229.h:114
UDSErr_t UDSUnpackRequestDownloadResponse(const UDSClient_t *client, struct RequestDownloadResponse *resp)
Parse server's response to RequestDownload.
Definition iso14229.c:1151
uint8_t UDS_A_Mtype_t
private: oneof Uds_a_mtype
Definition iso14229.h:531
UDSErr_t UDSCtrlDTCSetting(UDSClient_t *client, uint8_t dtcSettingType, const uint8_t *dtcSettingControlOptionRecord, uint16_t len)
control DTC setting
Definition iso14229.c:1022
UDSErr_t UDSClientInit(UDSClient_t *client)
Call this once.
Definition iso14229.c:366
#define UDS_LOG_LEVEL
sets the logging level
Definition iso14229.h:111
UDSErr_t UDSTpSend(UDSTp_t *hdl, const uint8_t *buf, size_t len, const UDSSDU_t *info)
Send to transport.
Definition iso14229.c:2884
UDSErr_t UDSServerTpISOTpCSocketCANInit(UDSTpISOTpCSocketCAN_t *tp, const char *ifname, uint32_t source_addr, uint32_t target_addr, uint32_t source_addr_func)
Initialize isotp-c over SocketCAN transport for UDSServer_t.
Definition iso14229.c:3469
UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, uint8_t mode)
Change the diagnostic session.
Definition iso14229.c:678
UDSErr_t UDSClientPoll(UDSClient_t *client)
Call at <5ms intervals.
Definition iso14229.c:1173
UDSErr_t UDSSendBytes(UDSClient_t *client, const uint8_t *data, uint16_t size)
Send user-defined bytes to a UDS server.
Definition iso14229.c:654
UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList, uint16_t numDataIdentifiers)
Read Data By Identifier.
Definition iso14229.c:712
UDSErr_t UDSServerInit(UDSServer_t *srv)
call this once
Definition iso14229.c:2773
void UDSTpIsoTpSockDeinit(const UDSTpIsoTpSock_t *tp)
release sockets
Definition iso14229.c:3770
Request download response structure.
Definition iso14229.h:789
Routine control response structure.
Definition iso14229.h:796
const uint8_t * routineStatusRecord
Definition iso14229.h:799
size_t routineStatusRecordLength
Definition iso14229.h:800
uint16_t routineIdentifier
Definition iso14229.h:798
Security access response structure.
Definition iso14229.h:780
const uint8_t * securitySeed
Definition iso14229.h:782
Clear diagnostic information arguments.
Definition iso14229.h:960
const uint8_t memorySelection
Definition iso14229.h:963
const uint32_t groupOfDTC
Definition iso14229.h:961
const bool hasMemorySelection
Definition iso14229.h:962
UDS client structure.
Definition iso14229.h:753
uint8_t cfg_file_size_parameter_length
Definition iso14229.h:763
uint8_t cfg_data_format_identifier
Definition iso14229.h:762
uint16_t p2_ms
Definition iso14229.h:766
unsigned cfg_ignore_srv_sess_timing
Definition iso14229.h:761
int(*) fn(struct UDSClient *client, UDSEvent_t evt, void *ev_data)
Definition iso14229.h:756
unsigned cfg_suppress_pos_resp
Definition iso14229.h:758
uint32_t p2_timer
Definition iso14229.h:768
size_t send_size
Definition iso14229.h:772
size_t recv_size
Definition iso14229.h:771
uint8_t send_buf[UDS_CLIENT_SEND_BUF_SIZE]
Definition iso14229.h:774
uint8_t state
Definition iso14229.h:769
uint32_t p2_star_ms
Definition iso14229.h:767
unsigned cfg_send_functional
Definition iso14229.h:759
uint8_t recv_buf[UDS_CLIENT_RECV_BUF_SIZE]
Definition iso14229.h:773
void * fn_data
Definition iso14229.h:757
UDSTp_t * tp
Definition iso14229.h:755
Communication control arguments.
Definition iso14229.h:1061
Control DTC setting arguments.
Definition iso14229.h:1227
Custom service arguments.
Definition iso14229.h:1247
uint8_t(*) copyResponse(UDSServer_t *srv, const void *src, uint16_t len)
Definition iso14229.h:1251
const uint8_t * optionRecord
Definition iso14229.h:1249
const uint16_t sid
Definition iso14229.h:1248
const uint16_t len
Definition iso14229.h:1250
Dynamically define data identifier arguments.
Definition iso14229.h:1108
const uint8_t type
Definition iso14229.h:1109
uint16_t dynamicDataId
Definition iso14229.h:1112
Diagnostic session control arguments.
Definition iso14229.h:942
const uint8_t type
Definition iso14229.h:943
ECU reset arguments.
Definition iso14229.h:951
uint32_t powerDownTimeMillis
Definition iso14229.h:953
const uint8_t type
Definition iso14229.h:952
Input/output control by identifier arguments.
Definition iso14229.h:1132
const uint8_t ioCtrlParam
Definition iso14229.h:1134
const size_t ctrlStateAndMaskLen
Definition iso14229.h:1136
uint8_t(*) copy(UDSServer_t *srv, const void *src, uint16_t count)
Definition iso14229.h:1137
const void *const ctrlStateAndMask
Definition iso14229.h:1135
const uint16_t dataId
Definition iso14229.h:1133
Link control arguments.
Definition iso14229.h:1236
const void * data
Definition iso14229.h:1240
const size_t len
Definition iso14229.h:1239
const uint8_t type
Definition iso14229.h:1237
Read data by identifier arguments.
Definition iso14229.h:1042
const uint16_t dataId
Definition iso14229.h:1043
uint8_t(*) copy(UDSServer_t *srv, const void *src, uint16_t count)
Definition iso14229.h:1044
Read data by identifier variable structure.
Definition iso14229.h:806
uint16_t len
Definition iso14229.h:808
uint16_t did
Definition iso14229.h:807
void * data
Definition iso14229.h:809
Read DTC information arguments.
Definition iso14229.h:969
uint8_t(*) copy(UDSServer_t *srv, const void *src, uint16_t count)
Definition iso14229.h:971
const uint8_t type
Definition iso14229.h:970
Read memory by address arguments.
Definition iso14229.h:1051
const uintptr_t memAddr
Definition iso14229.h:1052
uint8_t(*) copy(UDSServer_t *srv, const void *src, uint16_t count)
Definition iso14229.h:1054
const size_t memSize
Definition iso14229.h:1053
Server request context.
Definition iso14229.h:875
uint8_t send_buf[UDS_SERVER_SEND_BUF_SIZE]
Definition iso14229.h:877
size_t send_len
Definition iso14229.h:879
uint8_t recv_buf[UDS_SERVER_RECV_BUF_SIZE]
Definition iso14229.h:876
size_t recv_len
Definition iso14229.h:878
UDSSDU_t info
Definition iso14229.h:881
size_t send_buf_size
Definition iso14229.h:880
Request download arguments.
Definition iso14229.h:1156
const uint8_t dataFormatIdentifier
Definition iso14229.h:1159
uint16_t maxNumberOfBlockLength
Definition iso14229.h:1160
const uintptr_t addr
Definition iso14229.h:1157
Request file transfer arguments.
Definition iso14229.h:1200
const uint8_t modeOfOperation
Definition iso14229.h:1205
const uint8_t dataFormatIdentifier
Definition iso14229.h:1208
Request transfer exit arguments.
Definition iso14229.h:1190
uint8_t(*) copyResponse(UDSServer_t *srv, const void *src, uint16_t len)
Definition iso14229.h:1193
const uint8_t *const data
Definition iso14229.h:1191
Request upload arguments.
Definition iso14229.h:1167
uint16_t maxNumberOfBlockLength
Definition iso14229.h:1171
const uint8_t dataFormatIdentifier
Definition iso14229.h:1170
const uintptr_t addr
Definition iso14229.h:1168
Routine control arguments.
Definition iso14229.h:1144
const uint8_t * optionRecord
Definition iso14229.h:1147
const uint16_t id
Definition iso14229.h:1146
const uint16_t len
Definition iso14229.h:1148
const uint8_t ctrlType
Definition iso14229.h:1145
uint8_t(*) copyStatusRecord(UDSServer_t *srv, const void *src, uint16_t len)
Definition iso14229.h:1149
Service data unit (SDU).
Definition iso14229.h:546
uint32_t A_SA
Definition iso14229.h:549
uint32_t A_TA
Definition iso14229.h:550
uint32_t A_AE
Definition iso14229.h:552
UDS_A_Mtype_t A_Mtype
Definition iso14229.h:547
UDS_A_TA_Type_t A_TA_Type
Definition iso14229.h:551
Security access request seed arguments.
Definition iso14229.h:1070
const uint8_t *const dataRecord
Definition iso14229.h:1072
uint8_t(*) copySeed(UDSServer_t *srv, const void *src, uint16_t len)
Definition iso14229.h:1074
Security access validate key arguments.
Definition iso14229.h:1081
const uint8_t *const key
Definition iso14229.h:1083
UDS server structure.
Definition iso14229.h:887
size_t xferTotalBytes
Definition iso14229.h:915
uint32_t sec_access_auth_fail_timer
Definition iso14229.h:903
uint16_t p2_ms
Server time constants (milliseconds).
Definition iso14229.h:895
uint32_t p2_star_ms
Definition iso14229.h:896
bool notReadyToReceive
UDS-1 2013 defines the following conditions under which the server does not process incoming requests...
Definition iso14229.h:934
uint8_t securityLevel
Definition iso14229.h:920
uint32_t sec_access_boot_delay_timer
Definition iso14229.h:904
uint16_t s3_ms
Definition iso14229.h:897
UDSReq_t r
Definition iso14229.h:936
void * fn_data
Definition iso14229.h:890
UDSTp_t * tp
Definition iso14229.h:888
size_t xferBlockLength
Definition iso14229.h:917
UDSErr_t(*) fn(struct UDSServer *srv, UDSEvent_t event, void *arg)
Definition iso14229.h:889
uint32_t s3_session_timeout_timer
Definition iso14229.h:902
size_t xferByteCounter
Definition iso14229.h:916
uint8_t ecuResetScheduled
Definition iso14229.h:899
uint8_t xferBlockSequenceCounter
Definition iso14229.h:913
uint32_t p2_timer
Definition iso14229.h:901
uint8_t sessionType
Definition iso14229.h:919
bool xferIsActive
UDS-1-2013: Table 407 - 0x36 TransferData Supported negative response codes requires that the server ...
Definition iso14229.h:912
bool requestInProgress
Definition iso14229.h:923
uint32_t ecuResetTimer
Definition iso14229.h:900
isotp-c over SocketCAN implementation of UDSTp_t
Definition iso14229.h:2321
isotp-c implementation of UDSTp_t
Definition iso14229.h:2263
linux ISO-TP socket implementation of UDSTp_t
Definition iso14229.h:2369
UDS Transport layer.
Definition iso14229.h:561
UDSErr_t(*) poll(struct UDSTp *hdl)
Poll the transport layer.
Definition iso14229.h:591
UDSErr_t(*) recv(struct UDSTp *hdl, uint8_t *buf, size_t bufsiz, size_t *recvlen, UDSSDU_t *info)
Receive data from the transport.
Definition iso14229.h:583
UDSErr_t(*) send(struct UDSTp *hdl, const uint8_t *buf, const size_t len, const UDSSDU_t *info)
Send data to the transport.
Definition iso14229.h:571
Transfer data arguments.
Definition iso14229.h:1178
const uint16_t len
Definition iso14229.h:1180
uint8_t(*) copyResponse(UDSServer_t *srv, const void *src, uint16_t len)
Definition iso14229.h:1182
const uint8_t *const data
Definition iso14229.h:1179
const uint16_t maxRespLen
Definition iso14229.h:1181
Write data by identifier arguments.
Definition iso14229.h:1090
const uint16_t len
Definition iso14229.h:1093
const uint16_t dataId
Definition iso14229.h:1091
const uint8_t *const data
Definition iso14229.h:1092
Write memory by address arguments.
Definition iso14229.h:1099
const uintptr_t memAddr
Definition iso14229.h:1100
const uint8_t *const data
Definition iso14229.h:1102
struct UDSDDDIArgs_t::@052263275324350175074117356122047100356070003133::@115243115226044153303170122340357141371034352066 defineByMemAddress
struct UDSDDDIArgs_t::@052263275324350175074117356122047100356070003133::@036062102371115341142264035315270072153132273147 defineById
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@355231136245007054075200356211041150371252334044 numOfDTCByStatusMaskArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@047012174113202206257152072274143133322231236121 userDefMemDTCSnapshotRecordByDTCNumArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@154001327012172334201146116375304045171105172314 dtcStatusByMaskArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@202153233305101214231012246142343355313236156117 wwhobdDTCWithPermStatusArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@305215343063121020063152330305364065023263302342 dtcInfoByDTCReadinessGroupIdArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@316272062351030324211305365217344343316022275306 dtcStoredDataByRecordNumArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@074254175135322041140372030214006246075071061263 wwhobdDTCByMaskArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@251214024221351216066340166017235251143034105333 dtcExtDataRecordByRecordNumArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@030077060352005266364046135253225021030163312237 userDefMemDTCExtDataRecordByDTCNumArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@227353312111251376072016263157011107071271365150 dtcExtDataRecordIdArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@122167075350102041255165217274110033054226235151 numOfDTCBySeverityMaskArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@053011077231155331214107140362046363214010061172 userDefMemoryDTCByStatusMaskArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@257326070054040214361234214245165251024355111071 dtcSnapshotRecordbyDTCNumArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@370142040263172177333046321065146007342243043210 severityInfoOfDTCArgs
struct UDSRDTCIArgs_t::@242172112264143020077310143126066111376236317004::@166357164257276222002146302270155120176057041273 dtcExtDtaRecordByDTCNumArgs