iso14229 0.9.0
ISO14229-1 (UDS) C Library
Loading...
Searching...
No Matches
iso14229.h
Go to the documentation of this file.
1#ifndef ISO14229_H
2#define ISO14229_H
3
4/**
5 * @file iso14229.h
6 * @brief ISO14229-1 (UDS) library
7 * @copyright Copyright (c) Nick Kirkby
8 * @see https://github.com/driftregion/iso14229
9 */
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
15
16#define UDS_LIB_VERSION "0.9.0"
17
18
19
20#define UDS_SYS_CUSTOM 0
21#define UDS_SYS_UNIX 1
22#define UDS_SYS_WINDOWS 2
23#define UDS_SYS_ARDUINO 3
24#define UDS_SYS_ESP32 4
25
26#if !defined(UDS_SYS)
27
28#if defined(__unix__) || defined(__APPLE__)
29#define UDS_SYS UDS_SYS_UNIX
30#elif defined(_WIN32)
31#define UDS_SYS UDS_SYS_WINDOWS
32#elif defined(ARDUINO)
33#define UDS_SYS UDS_SYS_ARDUINO
34#elif defined(ESP_PLATFORM)
35#define UDS_SYS UDS_SYS_ESP32
36#else
37#define UDS_SYS UDS_SYS_CUSTOM
38#endif
39
40#endif
41
42
43
44
45#if UDS_SYS == UDS_SYS_ARDUINO
46
47#include <assert.h>
48#include <stddef.h>
49#include <stdint.h>
50#include <string.h>
51#include <stdio.h>
52#include <inttypes.h>
53#include <Arduino.h>
54
55#ifndef UDS_TP_ISOTP_C
56#define UDS_TP_ISOTP_C
57#endif
58
59#endif
60
61
62
63#if UDS_SYS == UDS_SYS_UNIX
64
65#include <assert.h>
66#include <inttypes.h>
67#include <stdbool.h>
68#include <stddef.h>
69#include <stdint.h>
70#include <stdio.h>
71#include <string.h>
72#include <sys/time.h>
73#include <sys/types.h>
74#include <time.h>
75
76#endif
77
78
79
80#if UDS_SYS == UDS_SYS_WINDOWS
81
82#include <stdint.h>
83#include <stdbool.h>
84#include <stdlib.h>
85#include <stdio.h>
86#include <string.h>
87#include <inttypes.h>
88#include <time.h>
89#include <BaseTsd.h>
90typedef SSIZE_T ssize_t;
91
92#ifdef _MSC_VER
93#define strncasecmp _strnicmp
94#define strcasecmp _stricmp
95#endif
96
97#endif
98
99
100
101#if UDS_SYS == UDS_SYS_ESP32
102
103#include <string.h>
104#include <inttypes.h>
105#include <esp_timer.h>
106
107#define UDS_TP_ISOTP_C 1
108
109#endif
110
111
112
113/** ISO-TP Maximum Transmissiable Unit (ISO-15764-2-2004 section 5.3.3) */
114#define UDS_ISOTP_MTU (4095)
115
116#ifndef UDS_TP_MTU
117#define UDS_TP_MTU UDS_ISOTP_MTU
118#endif
119
120#ifndef UDS_SERVER_SEND_BUF_SIZE
121#define UDS_SERVER_SEND_BUF_SIZE (UDS_TP_MTU)
122#endif
123
124#ifndef UDS_SERVER_RECV_BUF_SIZE
125#define UDS_SERVER_RECV_BUF_SIZE (UDS_TP_MTU)
126#endif
127
128#ifndef UDS_CLIENT_SEND_BUF_SIZE
129#define UDS_CLIENT_SEND_BUF_SIZE (UDS_TP_MTU)
130#endif
131
132#ifndef UDS_CLIENT_RECV_BUF_SIZE
133#define UDS_CLIENT_RECV_BUF_SIZE (UDS_TP_MTU)
134#endif
135
136#ifndef UDS_CLIENT_DEFAULT_P2_MS
137#define UDS_CLIENT_DEFAULT_P2_MS (150U)
138#endif
139
140#ifndef UDS_CLIENT_DEFAULT_P2_STAR_MS
141#define UDS_CLIENT_DEFAULT_P2_STAR_MS (1500U)
142#endif
143
144// Default value from ISO14229-2 2013 Table 5: 2000 ms
145#ifndef UDS_CLIENT_DEFAULT_S3_MS
146#define UDS_CLIENT_DEFAULT_S3_MS (2000)
147#endif
148
149static_assert(UDS_CLIENT_DEFAULT_P2_STAR_MS > UDS_CLIENT_DEFAULT_P2_MS, "");
150
151// Default value from ISO14229-2 2013 Table 4: 50 ms
152#ifndef UDS_SERVER_DEFAULT_P2_MS
153#define UDS_SERVER_DEFAULT_P2_MS (50)
154#endif
155
156// Default value from ISO14229-2 2013 Table 4: 5000 ms
157#ifndef UDS_SERVER_DEFAULT_P2_STAR_MS
158#define UDS_SERVER_DEFAULT_P2_STAR_MS (5000)
159#endif
160
161// Default value from ISO14229-2 2013 Table 5: 5000 -0/+200 ms
162#ifndef UDS_SERVER_DEFAULT_S3_MS
163#define UDS_SERVER_DEFAULT_S3_MS (5100)
164#endif
165
166static_assert((0 < UDS_SERVER_DEFAULT_P2_MS) &&
167 (UDS_SERVER_DEFAULT_P2_MS < UDS_SERVER_DEFAULT_P2_STAR_MS) &&
168 (UDS_SERVER_DEFAULT_P2_STAR_MS < UDS_SERVER_DEFAULT_S3_MS),
169 "");
170
171// Duration between the server sending a positive response to an ECU reset request and the emission
172// of a UDS_EVT_DoScheduledReset event. This should be set to a duration adequate for the server
173// transport layer to finish responding to the ECU reset request.
174#ifndef UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS
175#define UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS (60)
176#endif
177
178#if (UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS < UDS_SERVER_DEFAULT_P2_MS)
179#error "The server shall have adequate time to respond before reset"
180#endif
181
182// Amount of time to wait after boot before accepting 0x27 requests.
183#ifndef UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_BOOT_DELAY_MS
184#define UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_BOOT_DELAY_MS (1000)
185#endif
186
187// Amount of time to wait after an authentication failure before accepting another 0x27 request.
188#ifndef UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_AUTH_FAIL_DELAY_MS
189#define UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_AUTH_FAIL_DELAY_MS (1000)
190#endif
191
192#ifndef UDS_SERVER_DEFAULT_XFER_DATA_MAX_BLOCKLENGTH
193/*! ISO14229-1:2013 Table 396. This parameter is used by the requestDownload positive response
194message to inform the client how many data bytes (maxNumberOfBlockLength) to include in each
195TransferData request message from the client. */
196#define UDS_SERVER_DEFAULT_XFER_DATA_MAX_BLOCKLENGTH (UDS_TP_MTU)
197#endif
198
199#ifndef UDS_CUSTOM_MILLIS
200#define UDS_CUSTOM_MILLIS 0
201#endif
202
203
204
205
206#if defined UDS_TP_ISOTP_C_SOCKETCAN
207#ifndef UDS_TP_ISOTP_C
208#define UDS_TP_ISOTP_C
209#endif
210#endif
211
212enum UDSTpStatusFlags {
213 UDS_TP_IDLE = 0x0000,
214 UDS_TP_SEND_IN_PROGRESS = 0x0001,
215 UDS_TP_RECV_COMPLETE = 0x0002,
216 UDS_TP_ERR = 0x0004,
217};
218
219typedef uint32_t UDSTpStatus_t;
220
221typedef enum {
222 UDS_A_MTYPE_DIAG = 0,
223 UDS_A_MTYPE_REMOTE_DIAG,
224 UDS_A_MTYPE_SECURE_DIAG,
225 UDS_A_MTYPE_SECURE_REMOTE_DIAG,
226} UDS_A_Mtype_t;
227
228typedef enum {
229 UDS_A_TA_TYPE_PHYSICAL = 0, // unicast (1:1)
230 UDS_A_TA_TYPE_FUNCTIONAL, // multicast
231} UDS_A_TA_Type_t;
232
233typedef uint8_t UDSTpAddr_t;
234
235/**
236 * @brief Service data unit (SDU)
237 * @details data interface between the application layer and the transport layer
238 */
239typedef struct {
240 UDS_A_Mtype_t A_Mtype; /**< message type (diagnostic, remote diagnostic, secure diagnostic,
241 secure remote diagnostic) */
242 uint32_t A_SA; /**< application source address */
243 uint32_t A_TA; /**< application target address */
244 UDS_A_TA_Type_t A_TA_Type; /**< application target address type (physical or functional) */
245 uint32_t A_AE; /**< application layer remote address */
246} UDSSDU_t;
247
248#define UDS_TP_NOOP_ADDR (0xFFFFFFFF)
249
250/**
251 * @brief UDS Transport layer
252 * @note implementers should embed this struct at offset zero in their own transport layer handle
253 */
254typedef struct UDSTp {
255 /**
256 * @brief Send data to the transport
257 * @param hdl: pointer to transport handle
258 * @param buf: a pointer to the data to send
259 * @param len: length of data to send
260 * @param info: pointer to SDU info (may be NULL). If NULL, implementation should send with
261 * physical addressing
262 */
263 ssize_t (*send)(struct UDSTp *hdl, uint8_t *buf, size_t len, UDSSDU_t *info);
264
265 /**
266 * @brief Receive data from the transport
267 * @param hdl: transport handle
268 * @param buf: receive buffer
269 * @param bufsize: size of the receive buffer
270 * @param info: pointer to SDU info to be updated by transport implementation. May be NULL. If
271 * non-NULL, the transport implementation must populate it with valid values.
272 */
273 ssize_t (*recv)(struct UDSTp *hdl, uint8_t *buf, size_t bufsize, UDSSDU_t *info);
274
275 /**
276 * @brief Poll the transport layer.
277 * @param hdl: pointer to transport handle
278 * @note the transport layer user is responsible for calling this function periodically
279 * @note threaded implementations like linux isotp sockets don't need to do anything here.
280 * @return UDS_TP_IDLE if idle, otherwise UDS_TP_SEND_IN_PROGRESS or UDS_TP_RECV_COMPLETE
281 */
282 UDSTpStatus_t (*poll)(struct UDSTp *hdl);
283} UDSTp_t;
284
285ssize_t UDSTpSend(UDSTp_t *hdl, const uint8_t *buf, ssize_t len, UDSSDU_t *info);
286ssize_t UDSTpRecv(UDSTp_t *hdl, uint8_t *buf, size_t bufsize, UDSSDU_t *info);
287UDSTpStatus_t UDSTpPoll(UDSTp_t *hdl);
288
289
290
291/**
292 * @enum UDSEvent_t
293 * @brief UDS events
294 *
295 * Events are passed to the server or client callback function along with
296 * a pointer to the associated argument structure.
297 */
298typedef enum UDSEvent {
299 UDS_EVT_Err, /**< Common event. Argument type: UDSErr_t * */
300
301 UDS_EVT_DiagSessCtrl, /**< Server evt 0x10, argtype: UDSDiagSessCtrlArgs_t * */
302 UDS_EVT_EcuReset, /**< Server evt 0x11, argtype: UDSECUResetArgs_t * */
303 UDS_EVT_ClearDiagnosticInfo, /**< Server evt 0x14, argtype: UDSCDIArgs_t * */
304 UDS_EVT_ReadDTCInformation, /**< Server evt 0x19, argtype: UDSRDTCIArgs_t * */
305 UDS_EVT_ReadDataByIdent, /**< Server evt 0x22, argtype: UDSRDBIArgs_t * */
306 UDS_EVT_ReadMemByAddr, /**< Server evt 0x23, argtype: UDSReadMemByAddrArgs_t * */
307 UDS_EVT_CommCtrl, /**< Server evt 0x28, argtype: UDSCommCtrlArgs_t * */
308 UDS_EVT_SecAccessRequestSeed, /**< Server evt 0x27, argtype: UDSSecAccessRequestSeedArgs_t * */
309 UDS_EVT_SecAccessValidateKey, /**< Server evt 0x27, argtype: UDSSecAccessValidateKeyArgs_t * */
310 UDS_EVT_WriteDataByIdent, /**< Server evt 0x2E, argtype: UDSWDBIArgs_t * */
311 UDS_EVT_WriteMemByAddr, /**< Server evt 0x3D, argtype: UDSWriteMemByAddrArgs_t * */
312 UDS_EVT_DynamicDefineDataId, /**< Server evt 0x2C, argtype: UDSDDDIArgs_t * */
313 UDS_EVT_IOControl, /**< Server evt 0x2F, argtype: UDSIOCtrlArgs_t * */
314 UDS_EVT_RoutineCtrl, /**< Server evt 0x31, argtype: UDSRoutineCtrlArgs_t * */
315 UDS_EVT_RequestDownload, /**< Server evt 0x34, argtype: UDSRequestDownloadArgs_t * */
316 UDS_EVT_RequestUpload, /**< Server evt 0x35, argtype: UDSRequestUploadArgs_t * */
317 UDS_EVT_TransferData, /**< Server evt 0x36, argtype: UDSTransferDataArgs_t * */
318 UDS_EVT_RequestTransferExit, /**< Server evt 0x37, argtype: UDSRequestTransferExitArgs_t * */
319 UDS_EVT_SessionTimeout, /**< Server evt 0x38, argtype: NULL */
320 UDS_EVT_DoScheduledReset, /**< Server evt 0x39, argtype: uint8_t * */
321 UDS_EVT_RequestFileTransfer, /**< Server evt 0x38, argtype: UDSRequestFileTransferArgs_t * */
322 UDS_EVT_ControlDTCSetting, /**< Server evt 0x85, argtype: UDSControlDTCSettingArgs_t * */
323 UDS_EVT_LinkControl, /**< Server evt 0x87, argtype: UDSLinkCtrlArgs_t * */
324 UDS_EVT_Custom, /**< Server evt other, argtype: UDSCustomArgs_t * */
325
326 UDS_EVT_Poll, /**< Client evt: Poll. Argument type: NULL */
327 UDS_EVT_SendComplete, /**< Client evt: Send complete. Argument type: NULL */
328 UDS_EVT_ResponseReceived, /**< Client evt: Response received. Argument type: NULL */
329 UDS_EVT_Idle, /**< Client evt: Idle. Argument type: NULL */
330
331 UDS_EVT_MAX, /**< Unused sentinel value */
332} UDSEvent_t;
333
334typedef enum {
335 UDS_FAIL = -1, // General error
336 UDS_OK = 0, // Success
337
338 // Negative Response Codes (NRCs) as defined in ISO14229-1:2020 Table A.1 - Negative Response
339 // Code (NRC) definition and values
340 UDS_PositiveResponse = 0,
341 // 0x01 to 0x0F are reserved by ISO14229-1:2020
342 UDS_NRC_GeneralReject = 0x10,
343 UDS_NRC_ServiceNotSupported = 0x11,
344 UDS_NRC_SubFunctionNotSupported = 0x12,
345 UDS_NRC_IncorrectMessageLengthOrInvalidFormat = 0x13,
346 UDS_NRC_ResponseTooLong = 0x14,
347 // 0x15 to 0x20 are reserved by ISO14229-1:2020
348 UDS_NRC_BusyRepeatRequest = 0x21,
349 UDS_NRC_ConditionsNotCorrect = 0x22,
350 UDS_NRC_RequestSequenceError = 0x24,
351 UDS_NRC_NoResponseFromSubnetComponent = 0x25,
352 UDS_NRC_FailurePreventsExecutionOfRequestedAction = 0x26,
353 // 0x27 to 0x30 are reserved by ISO14229-1:2020
354 UDS_NRC_RequestOutOfRange = 0x31,
355 // 0x32 is reserved by ISO14229-1:2020
356 UDS_NRC_SecurityAccessDenied = 0x33,
357 UDS_NRC_AuthenticationRequired = 0x34,
358 UDS_NRC_InvalidKey = 0x35,
359 UDS_NRC_ExceedNumberOfAttempts = 0x36,
360 UDS_NRC_RequiredTimeDelayNotExpired = 0x37,
361 UDS_NRC_SecureDataTransmissionRequired = 0x38,
362 UDS_NRC_SecureDataTransmissionNotAllowed = 0x39,
363 UDS_NRC_SecureDataVerificationFailed = 0x3A,
364 // 0x3B to 0x4F are reserved by ISO14229-1:2020
365 UDS_NRC_CertficateVerificationFailedInvalidTimePeriod = 0x50,
366 UDS_NRC_CertficateVerificationFailedInvalidSignature = 0x51,
367 UDS_NRC_CertficateVerificationFailedInvalidChainOfTrust = 0x52,
368 UDS_NRC_CertficateVerificationFailedInvalidType = 0x53,
369 UDS_NRC_CertficateVerificationFailedInvalidFormat = 0x54,
370 UDS_NRC_CertficateVerificationFailedInvalidContent = 0x55,
371 UDS_NRC_CertficateVerificationFailedInvalidScope = 0x56,
372 UDS_NRC_CertficateVerificationFailedInvalidCertificate = 0x57,
373 UDS_NRC_OwnershipVerificationFailed = 0x58,
374 UDS_NRC_ChallengeCalculationFailed = 0x59,
375 UDS_NRC_SettingAccessRightsFailed = 0x5A,
376 UDS_NRC_SessionKeyCreationOrDerivationFailed = 0x5B,
377 UDS_NRC_ConfigurationDataUsageFailed = 0x5C,
378 UDS_NRC_DeAuthenticationFailed = 0x5D,
379 // 0x5E to 0x6F are reserved by ISO14229-1:2020
380 UDS_NRC_UploadDownloadNotAccepted = 0x70,
381 UDS_NRC_TransferDataSuspended = 0x71,
382 UDS_NRC_GeneralProgrammingFailure = 0x72,
383 UDS_NRC_WrongBlockSequenceCounter = 0x73,
384 // 0x74 to 0x77 are reserved by ISO14229-1:2020
385 UDS_NRC_RequestCorrectlyReceived_ResponsePending = 0x78,
386 // 0x79 to 0x7D are reserved by ISO14229-1:2020
387 UDS_NRC_SubFunctionNotSupportedInActiveSession = 0x7E,
388 UDS_NRC_ServiceNotSupportedInActiveSession = 0x7F,
389 // 0x80 is reserved by ISO14229-1:2020
390 UDS_NRC_RpmTooHigh = 0x81,
391 UDS_NRC_RpmTooLow = 0x82,
392 UDS_NRC_EngineIsRunning = 0x83,
393 UDS_NRC_EngineIsNotRunning = 0x84,
394 UDS_NRC_EngineRunTimeTooLow = 0x85,
395 UDS_NRC_TemperatureTooHigh = 0x86,
396 UDS_NRC_TemperatureTooLow = 0x87,
397 UDS_NRC_VehicleSpeedTooHigh = 0x88,
398 UDS_NRC_VehicleSpeedTooLow = 0x89,
399 UDS_NRC_ThrottlePedalTooHigh = 0x8A,
400 UDS_NRC_ThrottlePedalTooLow = 0x8B,
401 UDS_NRC_TransmissionRangeNotInNeutral = 0x8C,
402 UDS_NRC_TransmissionRangeNotInGear = 0x8D,
403 // 0x8E is reserved by ISO14229-1:2020
404 UDS_NRC_BrakeSwitchNotClosed = 0x8F,
405 UDS_NRC_ShifterLeverNotInPark = 0x90,
406 UDS_NRC_TorqueConverterClutchLocked = 0x91,
407 UDS_NRC_VoltageTooHigh = 0x92,
408 UDS_NRC_VoltageTooLow = 0x93,
409 UDS_NRC_ResourceTemporarilyNotAvailable = 0x94,
410
411 /* 0x95 to 0xEF are reservedForSpecificConditionsNotCorrect */
412 /* 0xF0 to 0xFE are vehicleManufacturerSpecificConditionsNotCorrect */
413 /* 0xFF is ISOSAEReserved */
414
415 // The following values are not defined in ISO14229-1:2020
416 UDS_ERR_TIMEOUT = 0x100, // A request has timed out
417 UDS_ERR_DID_MISMATCH, // The response DID does not match the request DID
418 UDS_ERR_SID_MISMATCH, // The response SID does not match the request SID
419 UDS_ERR_SUBFUNCTION_MISMATCH, // The response SubFunction does not match the request SubFunction
420 UDS_ERR_TPORT, // Transport error. Check the transport layer for more information
421 UDS_ERR_RESP_TOO_SHORT, // The response is too short
422 UDS_ERR_BUFSIZ, // The buffer is not large enough
423 UDS_ERR_INVALID_ARG, // The function has been called with invalid arguments
424 UDS_ERR_BUSY, // The client is busy and cannot process the request
425 UDS_ERR_MISUSE, // The library is used incorrectly
426} UDSErr_t;
427
428// ISO14229-1:2020 Table 25
429// UDS Level Diagnostic Session
430#define UDS_LEV_DS_DS 1 // Default Session
431#define UDS_LEV_DS_PRGS 2 // Programming Session
432#define UDS_LEV_DS_EXTDS 3 // Extended Diagnostic Session
433#define UDS_LEV_DS_SSDS 4 // Safety System Diagnostic Session
434
435/**
436 * @brief 0x11 ECU Reset SubFunction = [resetType]
437 * ISO14229-1:2020 Table 34
438 * UDS Level Reset Type
439 */
440#define UDS_LEV_RT_HR 1 // Hard Reset
441#define UDS_LEV_RT_KOFFONR 2 // Key Off On Reset
442#define UDS_LEV_RT_SR 3 // Soft Reset
443#define UDS_LEV_RT_ERPSD 4 // Enable Rapid Power Shut Down
444#define UDS_LEV_RT_DRPSD 5 // Disable Rapid Power Shut Down
445
446/**
447 * @brief 0x28 Communication Control SubFunction = [controlType]
448 * ISO14229-1:2020 Table 54
449 * UDS Level Control Type
450 */
451#define UDS_LEV_CTRLTP_ERXTX 0 // EnableRxAndTx
452#define UDS_LEV_CTRLTP_ERXDTX 1 // EnableRxAndDisableTx
453#define UDS_LEV_CTRLTP_DRXETX 2 // DisableRxAndEnableTx
454#define UDS_LEV_CTRLTP_DRXTX 3 // DisableRxAndTx
455
456/**
457 * @brief 0x28 Communication Control communicationType
458 * ISO14229-1:2020 Table B.1
459 */
460#define UDS_CTP_NCM 1 // NormalCommunicationMessages
461#define UDS_CTP_NWMCM 2 // NetworkManagementCommunicationMessages
462#define UDS_CTP_NWMCM_NCM 3 // NetworkManagementCommunicationMessagesAndNormalCommunicationMessages
463
464/**
465 * @brief 0x31 RoutineControl SubFunction = [routineControlType]
466 * ISO14229-1:2020 Table 426
467 */
468#define UDS_LEV_RCTP_STR 1 // StartRoutine
469#define UDS_LEV_RCTP_STPR 2 // StopRoutine
470#define UDS_LEV_RCTP_RRR 3 // RequestRoutineResults
471
472/**
473 * @brief modeOfOperation parameter used in 0x38 RequestFileTransfer
474 * ISO14229-1:2020 Table G.1
475 */
476#define UDS_MOOP_ADDFILE 1 // AddFile
477#define UDS_MOOP_DELFILE 2 // DeleteFile
478#define UDS_MOOP_REPLFILE 3 // ReplaceFile
479#define UDS_MOOP_RDFILE 4 // ReadFile
480#define UDS_MOOP_RDDIR 5 // ReadDirectory
481#define UDS_MOOP_RSFILE 6 // ResumeFile
482
483/**
484 * @brief 0x85 ControlDTCSetting SubFunction = [dtcSettingType]
485 * ISO14229-1:2020 Table 128
486 */
487#define UDS_LEV_DTCSTP_ON 1
488#define UDS_LEV_DTCSTP_OFF 2
489
490/**
491 * @brief 0x87 LinkControl SubFunction = [linkControlType]
492 * ISO14229-1:2020 Table 171
493 */
494#define UDS_LEV_LCTP_VMTWFP 1 // VerifyModeTransitionWithFixedParameter
495#define UDS_LEV_LCTP_VMTWSP 2 // VerifyModeTransitionWithSpecificParameter
496#define UDS_LEV_LCTP_TM 3 // TransitionMode
497
498// ISO-14229-1:2013 Table 2
499#define UDS_MAX_DIAGNOSTIC_SERVICES 0x7F
500
501#define UDS_RESPONSE_SID_OF(request_sid) ((request_sid) + 0x40)
502#define UDS_REQUEST_SID_OF(response_sid) ((response_sid) - 0x40)
503
504#define UDS_NEG_RESP_LEN 3U
505#define UDS_0X10_REQ_LEN 2U
506#define UDS_0X10_RESP_LEN 6U
507#define UDS_0X11_REQ_MIN_LEN 2U
508#define UDS_0X11_RESP_BASE_LEN 2U
509#define UDS_0X14_REQ_MIN_LEN 4U
510#define UDS_0X14_RESP_BASE_LEN 1U
511#define UDS_0X19_REQ_MIN_LEN 2U
512#define UDS_0X19_RESP_BASE_LEN 2U
513#define UDS_0X23_REQ_MIN_LEN 4U
514#define UDS_0X23_RESP_BASE_LEN 1U
515#define UDS_0X22_RESP_BASE_LEN 1U
516#define UDS_0X27_REQ_BASE_LEN 2U
517#define UDS_0X27_RESP_BASE_LEN 2U
518#define UDS_0X28_REQ_BASE_LEN 3U
519#define UDS_0X28_RESP_LEN 2U
520#define UDS_0X2C_REQ_MIN_LEN 2U
521#define UDS_0X2C_RESP_BASE_LEN 2U
522#define UDS_0X2E_REQ_BASE_LEN 3U
523#define UDS_0X2E_REQ_MIN_LEN 4U
524#define UDS_0X2E_RESP_LEN 3U
525#define UDS_0X2F_REQ_MIN_LEN 4U
526#define UDS_0X2F_RESP_BASE_LEN 4U
527#define UDS_0X31_REQ_MIN_LEN 4U
528#define UDS_0X31_RESP_MIN_LEN 4U
529#define UDS_0X34_REQ_BASE_LEN 3U
530#define UDS_0X34_RESP_BASE_LEN 2U
531#define UDS_0X35_REQ_BASE_LEN 3U
532#define UDS_0X35_RESP_BASE_LEN 2U
533#define UDS_0X36_REQ_BASE_LEN 2U
534#define UDS_0X36_RESP_BASE_LEN 2U
535#define UDS_0X37_REQ_BASE_LEN 1U
536#define UDS_0X37_RESP_BASE_LEN 1U
537#define UDS_0X38_REQ_BASE_LEN 9U
538#define UDS_0X38_RESP_BASE_LEN 3U
539#define UDS_0X3D_REQ_MIN_LEN 5U
540#define UDS_0X3D_RESP_BASE_LEN 2U
541#define UDS_0X3E_REQ_MIN_LEN 2U
542#define UDS_0X3E_REQ_MAX_LEN 2U
543#define UDS_0X3E_RESP_LEN 2U
544#define UDS_0X85_REQ_BASE_LEN 2U
545#define UDS_0X85_RESP_LEN 2U
546#define UDS_0X87_REQ_BASE_LEN 2U
547#define UDS_0X87_RESP_LEN 2U
548
549enum UDSDiagnosticServiceId {
550 kSID_DIAGNOSTIC_SESSION_CONTROL = 0x10,
551 kSID_ECU_RESET = 0x11,
552 kSID_CLEAR_DIAGNOSTIC_INFORMATION = 0x14,
553 kSID_READ_DTC_INFORMATION = 0x19,
554 kSID_READ_DATA_BY_IDENTIFIER = 0x22,
555 kSID_READ_MEMORY_BY_ADDRESS = 0x23,
556 kSID_READ_SCALING_DATA_BY_IDENTIFIER = 0x24,
557 kSID_SECURITY_ACCESS = 0x27,
558 kSID_COMMUNICATION_CONTROL = 0x28,
559 kSID_READ_PERIODIC_DATA_BY_IDENTIFIER = 0x2A,
560 kSID_DYNAMICALLY_DEFINE_DATA_IDENTIFIER = 0x2C,
561 kSID_WRITE_DATA_BY_IDENTIFIER = 0x2E,
562 kSID_IO_CONTROL_BY_IDENTIFIER = 0x2F,
563 kSID_ROUTINE_CONTROL = 0x31,
564 kSID_REQUEST_DOWNLOAD = 0x34,
565 kSID_REQUEST_UPLOAD = 0x35,
566 kSID_TRANSFER_DATA = 0x36,
567 kSID_REQUEST_TRANSFER_EXIT = 0x37,
568 kSID_REQUEST_FILE_TRANSFER = 0x38,
569 kSID_WRITE_MEMORY_BY_ADDRESS = 0x3D,
570 kSID_TESTER_PRESENT = 0x3E,
571 kSID_ACCESS_TIMING_PARAMETER = 0x83,
572 kSID_SECURED_DATA_TRANSMISSION = 0x84,
573 kSID_CONTROL_DTC_SETTING = 0x85,
574 kSID_RESPONSE_ON_EVENT = 0x86,
575 kSID_LINK_CONTROL = 0x87,
576};
577
578
579
580
581#ifndef UDS_ASSERT
582#include <assert.h>
583#define UDS_ASSERT(x) assert(x)
584#endif
585
586/* returns true if `a` is after `b` */
587static inline bool UDSTimeAfter(uint32_t a, uint32_t b) { return (int32_t)(a - b) > 0; }
588
589/**
590 * @brief Get time in milliseconds
591 * @return current time in milliseconds
592 */
593uint32_t UDSMillis(void);
594
595bool UDSSecurityAccessLevelIsReserved(uint8_t securityLevel);
596bool UDSErrIsNRC(UDSErr_t err);
597
598const char *UDSErrToStr(UDSErr_t err);
599const char *UDSEventToStr(UDSEvent_t evt);
600
601
602
603/**
604 * @brief logging for bring-up and unit tests.
605 * This interface was copied from ESP-IDF.
606 */
607
608
609#define UDS_LOG_NONE 0 // No log output
610#define UDS_LOG_ERROR 1 // Log errors only
611#define UDS_LOG_WARN 2 // Log warnings and errors
612#define UDS_LOG_INFO 3 // Log info, warnings, and errors
613#define UDS_LOG_DEBUG 4 // Log debug, info, warnings, and errors
614#define UDS_LOG_VERBOSE 5 // Log verbose, debug, info, warnings, and errors
615
616typedef int UDS_LogLevel_t;
617
618#ifndef UDS_LOG_LEVEL
619#define UDS_LOG_LEVEL UDS_LOG_NONE
620#endif
621
622#if UDS_CONFIG_LOG_COLORS
623#define UDS_LOG_COLOR_BLACK "30"
624#define UDS_LOG_COLOR_RED "31"
625#define UDS_LOG_COLOR_GREEN "32"
626#define UDS_LOG_COLOR_BROWN "33"
627#define UDS_LOG_COLOR_BLUE "34"
628#define UDS_LOG_COLOR_PURPLE "35"
629#define UDS_LOG_COLOR_CYAN "36"
630#define LOG_COLOR(COLOR) "\033[0;" COLOR "m"
631#define LOG_BOLD(COLOR) "\033[1;" COLOR "m"
632#define UDS_LOG_RESET_COLOR "\033[0m"
633#define UDS_LOG_COLOR_E LOG_COLOR(UDS_LOG_COLOR_RED)
634#define UDS_LOG_COLOR_W LOG_COLOR(UDS_LOG_COLOR_BROWN)
635#define UDS_LOG_COLOR_I LOG_COLOR(UDS_LOG_COLOR_GREEN)
636#define UDS_LOG_COLOR_D
637#define UDS_LOG_COLOR_V
638#else // UDS_CONFIG_LOG_COLORS
639#define UDS_LOG_COLOR_E
640#define UDS_LOG_COLOR_W
641#define UDS_LOG_COLOR_I
642#define UDS_LOG_COLOR_D
643#define UDS_LOG_COLOR_V
644#define UDS_LOG_RESET_COLOR
645#endif // UDS_CONFIG_LOG_COLORS
646
647#define UDS_LOG_FORMAT(letter, format) \
648 UDS_LOG_COLOR_##letter #letter " (%" PRIu32 ") %s: " format UDS_LOG_RESET_COLOR "\n"
649
650#if (UDS_LOG_LEVEL >= UDS_LOG_ERROR) && (UDS_LOG_LEVEL > UDS_LOG_NONE)
651#define UDS_LOGE(tag, format, ...) \
652 UDS_LogWrite(UDS_LOG_ERROR, tag, UDS_LOG_FORMAT(E, format), UDSMillis(), tag, ##__VA_ARGS__)
653#else
654#define UDS_LOGE(tag, format, ...) UDS_LogDummy(tag, format, ##__VA_ARGS__)
655#endif
656
657#if UDS_LOG_LEVEL >= UDS_LOG_WARN && UDS_LOG_LEVEL > UDS_LOG_NONE
658#define UDS_LOGW(tag, format, ...) \
659 UDS_LogWrite(UDS_LOG_WARN, tag, UDS_LOG_FORMAT(W, format), UDSMillis(), tag, ##__VA_ARGS__)
660#else
661#define UDS_LOGW(tag, format, ...) UDS_LogDummy(tag, format, ##__VA_ARGS__)
662#endif
663
664#if UDS_LOG_LEVEL >= UDS_LOG_INFO && UDS_LOG_LEVEL > UDS_LOG_NONE
665#define UDS_LOGI(tag, format, ...) \
666 UDS_LogWrite(UDS_LOG_INFO, tag, UDS_LOG_FORMAT(I, format), UDSMillis(), tag, ##__VA_ARGS__)
667#else
668#define UDS_LOGI(tag, format, ...) UDS_LogDummy(tag, format, ##__VA_ARGS__)
669#endif
670
671#if UDS_LOG_LEVEL >= UDS_LOG_DEBUG && UDS_LOG_LEVEL > UDS_LOG_NONE
672#define UDS_LOGD(tag, format, ...) \
673 UDS_LogWrite(UDS_LOG_DEBUG, tag, UDS_LOG_FORMAT(D, format), UDSMillis(), tag, ##__VA_ARGS__)
674#else
675#define UDS_LOGD(tag, format, ...) UDS_LogDummy(tag, format, ##__VA_ARGS__)
676#endif
677
678#if UDS_LOG_LEVEL >= UDS_LOG_VERBOSE && UDS_LOG_LEVEL > UDS_LOG_NONE
679#define UDS_LOGV(tag, format, ...) \
680 UDS_LogWrite(UDS_LOG_VERBOSE, tag, UDS_LOG_FORMAT(V, format), UDSMillis(), tag, ##__VA_ARGS__)
681#else
682#define UDS_LOGV(tag, format, ...) UDS_LogDummy(tag, format, ##__VA_ARGS__)
683#endif
684
685#if UDS_LOG_LEVEL >= UDS_LOG_DEBUG && UDS_LOG_LEVEL > UDS_LOG_NONE
686#define UDS_LOG_SDU(tag, buffer, buff_len, info) \
687 UDS_LogSDUInternal(UDS_LOG_DEBUG, tag, buffer, buff_len, info)
688#else
689#define UDS_LOG_SDU(tag, buffer, buff_len, info) UDS_LogSDUDummy(tag, buffer, buff_len, info)
690#endif
691
692#if defined(__GNUC__) || defined(__clang__)
693#define UDS_PRINTF_FORMAT(fmt_index, first_arg) \
694 __attribute__((format(printf, fmt_index, first_arg)))
695#else
696#define UDS_PRINTF_FORMAT(fmt_index, first_arg)
697#endif
698
699#if UDS_LOG_LEVEL > UDS_LOG_NONE
700void UDS_LogWrite(UDS_LogLevel_t level, const char *tag, const char *format, ...)
701 UDS_PRINTF_FORMAT(3, 4);
702void UDS_LogSDUInternal(UDS_LogLevel_t level, const char *tag, const uint8_t *buffer,
703 size_t buff_len, UDSSDU_t *info);
704#endif
705
706// Dummy function that consumes arguments but does nothing
707static inline void UDS_LogDummy(const char *tag, const char *format, ...) {
708 (void)tag;
709 (void)format;
710}
711static inline void UDS_LogSDUDummy(const char *tag, const uint8_t *buffer, size_t buff_len,
712 void *info) {
713 (void)tag;
714 (void)buffer;
715 (void)buff_len;
716 (void)info;
717}
718
719
720
721
722#define UDS_SUPPRESS_POS_RESP 0x1 // set the suppress positive response bit
723#define UDS_FUNCTIONAL 0x2 // send the request as a functional request
724#define UDS_IGNORE_SRV_TIMINGS 0x8 // ignore the server-provided p2 and p2_star
725
726/**
727 * @brief UDS client structure
728 */
729typedef struct UDSClient {
730 uint16_t p2_ms; /**< p2 timeout in milliseconds */
731 uint32_t p2_star_ms; /**< p2* timeout in milliseconds (for 0x78 response) */
732 UDSTp_t *tp; /**< transport layer handle */
733
734 uint32_t p2_timer; /**< p2 timer value */
735 uint8_t state; /**< client request state */
736
737 uint8_t options; /**< current request options */
738 uint8_t defaultOptions; /**< default options for all requests */
739 uint8_t _options_copy; /**< copy of options at the time a request is made */
740
741 int (*fn)(struct UDSClient *client, UDSEvent_t evt, void *ev_data); /**< callback function */
742 void *fn_data; /**< user-specified function data */
743
744 uint16_t recv_size; /**< size of received data */
745 uint16_t send_size; /**< size of data to send */
746 uint8_t recv_buf[UDS_CLIENT_RECV_BUF_SIZE]; /**< receive buffer */
747 uint8_t send_buf[UDS_CLIENT_SEND_BUF_SIZE]; /**< send buffer */
749
750/**
751 * @brief Security access response structure
752 */
754 uint8_t securityAccessType; /**< security access type (subfunction) */
755 const uint8_t *securitySeed; /**< pointer to security seed data */
756 uint16_t securitySeedLength; /**< length of security seed */
757};
758
759/**
760 * @brief Request download response structure
761 */
763 size_t maxNumberOfBlockLength; /**< maximum number of block length */
764};
765
766/**
767 * @brief Routine control response structure
768 */
770 uint8_t routineControlType; /**< routine control type (subfunction) */
771 uint16_t routineIdentifier; /**< routine identifier */
772 const uint8_t *routineStatusRecord; /**< pointer to routine status record */
773 uint16_t routineStatusRecordLength; /**< length of routine status record */
774};
775
776/**
777 * @brief Read data by identifier variable structure
778 */
779typedef struct {
780 uint16_t did; /**< data identifier */
781 uint16_t len; /**< data length */
782 void *data; /**< pointer to data buffer */
783 void *(*UnpackFn)(void *dst, const void *src, size_t n); /**< optional unpack function */
785
786UDSErr_t UDSClientInit(UDSClient_t *client);
787UDSErr_t UDSClientPoll(UDSClient_t *client);
788UDSErr_t UDSSendBytes(UDSClient_t *client, const uint8_t *data, uint16_t size);
789UDSErr_t UDSSendECUReset(UDSClient_t *client, uint8_t type);
790UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, uint8_t mode);
791UDSErr_t UDSSendSecurityAccess(UDSClient_t *client, uint8_t level, uint8_t *data, uint16_t size);
792UDSErr_t UDSSendCommCtrl(UDSClient_t *client, uint8_t ctrl, uint8_t comm);
793UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList,
794 const uint16_t numDataIdentifiers);
795UDSErr_t UDSSendWDBI(UDSClient_t *client, uint16_t dataIdentifier, const uint8_t *data,
796 uint16_t size);
797UDSErr_t UDSSendTesterPresent(UDSClient_t *client);
798UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, uint8_t type, uint16_t routineIdentifier,
799 const uint8_t *data, uint16_t size);
800
801UDSErr_t UDSSendRequestDownload(UDSClient_t *client, uint8_t dataFormatIdentifier,
802 uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress,
803 size_t memorySize);
804
805UDSErr_t UDSSendRequestUpload(UDSClient_t *client, uint8_t dataFormatIdentifier,
806 uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress,
807 size_t memorySize);
808UDSErr_t UDSSendTransferData(UDSClient_t *client, uint8_t blockSequenceCounter,
809 const uint16_t blockLength, const uint8_t *data, uint16_t size);
810UDSErr_t UDSSendTransferDataStream(UDSClient_t *client, uint8_t blockSequenceCounter,
811 const uint16_t blockLength, FILE *fd);
812UDSErr_t UDSSendRequestTransferExit(UDSClient_t *client);
813
814UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, uint8_t mode, const char *filePath,
815 uint8_t dataFormatIdentifier, uint8_t fileSizeParameterLength,
816 size_t fileSizeUncompressed, size_t fileSizeCompressed);
817
818UDSErr_t UDSCtrlDTCSetting(UDSClient_t *client, uint8_t dtcSettingType,
819 uint8_t *dtcSettingControlOptionRecord, uint16_t len);
820UDSErr_t UDSUnpackRDBIResponse(UDSClient_t *client, UDSRDBIVar_t *vars, uint16_t numVars);
821UDSErr_t UDSUnpackSecurityAccessResponse(const UDSClient_t *client,
822 struct SecurityAccessResponse *resp);
823UDSErr_t UDSUnpackRequestDownloadResponse(const UDSClient_t *client,
824 struct RequestDownloadResponse *resp);
825UDSErr_t UDSUnpackRoutineControlResponse(const UDSClient_t *client,
826 struct RoutineControlResponse *resp);
827
828UDSErr_t UDSConfigDownload(UDSClient_t *client, uint8_t dataFormatIdentifier,
829 uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress,
830 size_t memorySize, FILE *fd);
831
832
833
834
835/**
836 * @brief Server request context
837 */
838typedef struct {
839 uint8_t recv_buf[UDS_SERVER_RECV_BUF_SIZE]; /**< receive buffer */
840 uint8_t send_buf[UDS_SERVER_SEND_BUF_SIZE]; /**< send buffer */
841 size_t recv_len; /**< received data length */
842 size_t send_len; /**< send data length */
843 size_t send_buf_size; /**< send buffer size */
844 UDSSDU_t info; /**< service data unit information */
845} UDSReq_t;
846
847/**
848 * @brief UDS server structure
849 */
850typedef struct UDSServer {
851 UDSTp_t *tp; /**< transport layer handle */
852 UDSErr_t (*fn)(struct UDSServer *srv, UDSEvent_t event, void *arg); /**< callback function */
853 void *fn_data; /**< user-specified function data */
854
855 /**
856 * @brief Server time constants (milliseconds)
857 */
858 uint16_t p2_ms; /**< Default P2_server_max timing supported by the server */
859 uint32_t p2_star_ms; /**< Enhanced (NRC 0x78) P2_server_max supported by the server */
860 uint16_t s3_ms; /**< Session timeout */
861
862 uint8_t ecuResetScheduled; /**< nonzero indicates that an ECUReset has been scheduled */
863 uint32_t ecuResetTimer; /**< for delaying resetting until a response has been sent */
864 uint32_t p2_timer; /**< for rate limiting server responses */
865 uint32_t s3_session_timeout_timer; /**< indicates that diagnostic session has timed out */
866 uint32_t sec_access_auth_fail_timer; /**< brute-force hardening: rate limit security access */
867 uint32_t sec_access_boot_delay_timer; /**< brute-force hardening: restrict security access until
868 timer expires */
869
870 /**
871 * @brief UDS-1-2013: Table 407 - 0x36 TransferData Supported negative
872 * response codes requires that the server keep track of whether the
873 * transfer is active
874 */
875 bool xferIsActive; /**< transfer is active */
876 uint8_t xferBlockSequenceCounter; /**< UDS-1-2013: 14.4.2.3, Table 404: block sequence counter
877 starts at 0x01 */
878 size_t xferTotalBytes; /**< total transfer size in bytes requested by the client */
879 size_t xferByteCounter; /**< total number of bytes transferred */
880 size_t xferBlockLength; /**< block length (convenience for the TransferData API) */
881
882 uint8_t sessionType; /**< diagnostic session type (0x10) */
883 uint8_t securityLevel; /**< SecurityAccess (0x27) level */
884
885 bool RCRRP; /**< set to true when user fn returns 0x78 and false otherwise */
886 bool requestInProgress; /**< set to true when a request has been processed but the response has
887 not yet been sent */
888
889 /**
890 * @brief UDS-1 2013 defines the following conditions under which the server does not
891 * process incoming requests:
892 * - not ready to receive (Table A.1 0x78)
893 * - not accepting request messages and not sending responses (9.3.1)
894 *
895 * when this variable is set to true, incoming ISO-TP data will not be processed.
896 */
897 bool notReadyToReceive; /**< incoming ISO-TP data will not be processed */
898
899 UDSReq_t r; /**< request context */
901
902/**
903 * @brief Diagnostic session control arguments
904 */
905typedef struct {
906 const uint8_t type; /*! requested diagnostic session type */
907 uint16_t p2_ms; /*! optional: p2 timing override */
908 uint32_t p2_star_ms; /*! optional: p2* timing override */
910
911/**
912 * @brief ECU reset arguments
913 */
914typedef struct {
915 const uint8_t type; /**< reset type requested by client */
916 uint32_t powerDownTimeMillis; /**< when this much time has elapsed after a UDS_PositiveResponse,
917 a UDS_EVT_DoScheduledReset will be issued */
919
920/**
921 * @brief Clear diagnostic information arguments
922 */
923typedef struct {
924 const uint32_t groupOfDTC; /*! lower 3 bytes describe the groupOfDTC */
925 const bool hasMemorySelection; /*! `true` when a memory selection byte is present */
926 const uint8_t memorySelection; /*! memorySelection byte (optional) */
928
929/**
930 * @brief Read DTC information arguments
931 */
932typedef struct {
933 const uint8_t type; /*! invoked subfunction */
934 uint8_t (*copy)(UDSServer_t *srv, const void *src,
935 uint16_t count); /*! function for copying data */
936
937 union {
938 struct {
939 uint8_t mask; /*! DTC status mask */
940 } numOfDTCByStatusMaskArgs, dtcStatusByMaskArgs;
941 struct {
942 uint32_t dtc; /*! DTC Mask Record */
943 uint8_t snapshotNum; /*! DTC Snaphot Record Number */
944 uint8_t memory; /*! Memory Selection (only used when type == 0x18) */
945 } dtcSnapshotRecordbyDTCNumArgs, userDefMemDTCSnapshotRecordByDTCNumArgs;
946 struct {
947 uint8_t recordNum; /*! DTC Data Record Number */
948 } dtcStoredDataByRecordNumArgs, dtcExtDataRecordByRecordNumArgs, dtcExtDataRecordIdArgs;
949 struct {
950 uint32_t dtc; /*! DTC Mask Record */
951 uint8_t extDataRecNum; /*! DTC Extended Data Record Number */
952 uint8_t memory; /*! Memory Selection (only used when type == 0x19) */
953 } dtcExtDtaRecordByDTCNumArgs, userDefMemDTCExtDataRecordByDTCNumArgs;
954 struct {
955 uint8_t
956 functionalGroup; /*! Functional Group Identifier (only used when type == 0x42) */
957 uint8_t severityMask; /*! DTC Severity Mask */
958 uint8_t statusMask; /*! DTC Status Mask */
959 } numOfDTCBySeverityMaskArgs, dtcBySeverityMaskArgs, wwhobdDTCByMaskArgs;
960 struct {
961 uint32_t dtc; /*! DTC Mask Record */
962 } severityInfoOfDTCArgs;
963 struct {
964 uint8_t mask; /*! DTC status mask */
965 uint8_t memory; /*! Memory Selection */
966 } userDefMemoryDTCByStatusMaskArgs;
967 struct {
968 uint8_t functionalGroup; /*! Functional Group Identifier */
969 uint8_t
970 readinessGroup; /*! DTC Readiness Group Identifier (only used when type == 0x56) */
971 } wwhobdDTCWithPermStatusArgs, dtcInfoByDTCReadinessGroupIdArgs;
972 } subFuncArgs;
974
975/**
976 * @brief Read data by identifier arguments
977 */
978typedef struct {
979 const uint16_t dataId; /*! RDBI Data Identifier */
980 uint8_t (*copy)(UDSServer_t *srv, const void *src,
981 uint16_t count); /*! function for copying data */
983
984/**
985 * @brief Read memory by address arguments
986 */
987typedef struct {
988 const void *memAddr;
989 const size_t memSize;
990 uint8_t (*copy)(UDSServer_t *srv, const void *src,
991 uint16_t count); /*! function for copying data */
993
994/**
995 * @brief Communication control arguments
996 */
997typedef struct {
998 uint8_t ctrlType; /*! ControlType */
999 uint8_t commType; /*! CommunicationType */
1000 uint16_t nodeId; /*! NodeIdentificationNumber (only used when ctrlType is 0x04 or 0x05) */
1002
1003/**
1004 * @brief Security access request seed arguments
1005 */
1006typedef struct {
1007 const uint8_t level; /*! requested security level */
1008 const uint8_t *const dataRecord; /*! pointer to request data */
1009 const uint16_t len; /*! size of request data */
1010 uint8_t (*copySeed)(UDSServer_t *srv, const void *src,
1011 uint16_t len); /*! function for copying data */
1013
1014/**
1015 * @brief Security access validate key arguments
1016 */
1017typedef struct {
1018 const uint8_t level; /*! security level to be validated */
1019 const uint8_t *const key; /*! key sent by client */
1020 const uint16_t len; /*! length of key */
1022
1023/**
1024 * @brief Write data by identifier arguments
1025 */
1026typedef struct {
1027 const uint16_t dataId; /*! WDBI Data Identifier */
1028 const uint8_t *const data; /*! pointer to data */
1029 const uint16_t len; /*! length of data */
1031
1032/**
1033 * @brief Write memory by address arguments
1034 */
1035typedef struct {
1036 const void *memAddr; /*! pointer to memory address */
1037 const size_t memSize; /*! size of memory */
1038 const uint8_t *const data; /*! pointer to data */
1040
1041/**
1042 * @brief Dynamically define data identifier arguments
1043 */
1044typedef struct {
1045 const uint8_t type; /*! invoked subfunction */
1046 bool allDataIds; /*! is true when request is for all data identifiers (only relevant for
1047 subFunc 0x03) */
1048 uint16_t dynamicDataId; /*! dynamicallyDefinedDataIdentifier */
1049
1050 union {
1051 struct {
1052 uint16_t sourceDataId; /*! source DataIdentifier */
1053 uint8_t position; /*! position in source data record */
1054 uint8_t size; /*! number of bytes to be copied */
1055 } defineById;
1056 struct {
1057 void *memAddr;
1058 size_t memSize;
1059 } defineByMemAddress;
1060 } subFuncArgs;
1062
1063/**
1064 * @brief Input/output control by identifier arguments
1065 */
1066typedef struct {
1067 const uint16_t dataId; /*! Data Identifier */
1068 const uint8_t ioCtrlParam; /*! inputOutputControlParameter */
1069 const void *const ctrlStateAndMask; /*! controlState bytes and controlMask (optional) */
1070 const size_t ctrlStateAndMaskLen; /*! number of bytes in `ctrlStateAndMask` */
1071 uint8_t (*copy)(UDSServer_t *srv, const void *src,
1072 uint16_t count); /*! function for copying data */
1074
1075/**
1076 * @brief Routine control arguments
1077 */
1078typedef struct {
1079 const uint8_t ctrlType; /*! routineControlType */
1080 const uint16_t id; /*! routineIdentifier */
1081 const uint8_t *optionRecord; /*! optional data */
1082 const uint16_t len; /*! length of optional data */
1083 uint8_t (*copyStatusRecord)(UDSServer_t *srv, const void *src,
1084 uint16_t len); /*! function for copying response data */
1086
1087/**
1088 * @brief Request download arguments
1089 */
1090typedef struct {
1091 const void *addr; /*! requested address */
1092 const size_t size; /*! requested download size */
1093 const uint8_t dataFormatIdentifier; /*! optional specifier for format of data */
1094 uint16_t maxNumberOfBlockLength; /*! optional response: inform client how many data bytes to
1095 send in each `TransferData` request */
1097
1098/**
1099 * @brief Request upload arguments
1100 */
1101typedef struct {
1102 const void *addr; /*! requested address */
1103 const size_t size; /*! requested download size */
1104 const uint8_t dataFormatIdentifier; /*! optional specifier for format of data */
1105 uint16_t maxNumberOfBlockLength; /*! optional response: inform client how many data bytes to
1106 send in each `TransferData` request */
1108
1109/**
1110 * @brief Transfer data arguments
1111 */
1112typedef struct {
1113 const uint8_t *const data; /*! transfer data */
1114 const uint16_t len; /*! transfer data length */
1115 const uint16_t maxRespLen; /*! don't send more than this many bytes with copyResponse */
1116 uint8_t (*copyResponse)(
1117 UDSServer_t *srv, const void *src,
1118 uint16_t len); /*! function for copying transfer data response data (optional) */
1120
1121/**
1122 * @brief Request transfer exit arguments
1123 */
1124typedef struct {
1125 const uint8_t *const data; /*! request data */
1126 const uint16_t len; /*! request data length */
1127 uint8_t (*copyResponse)(UDSServer_t *srv, const void *src,
1128 uint16_t len); /*! function for copying response data (optional) */
1130
1131/**
1132 * @brief Request file transfer arguments
1133 */
1134typedef struct {
1135 const uint8_t modeOfOperation; /*! requested specifier for operation mode */
1136 const uint16_t filePathLen; /*! request data length */
1137 const uint8_t *filePath; /*! requested file path and name */
1138 const uint8_t dataFormatIdentifier; /*! optional specifier for format of data */
1139 const size_t fileSizeUnCompressed; /*! optional file size */
1140 const size_t fileSizeCompressed; /*! optional file size */
1141 uint16_t maxNumberOfBlockLength; /*! optional response: inform client how many data bytes to
1142 send in each `TransferData` request */
1144
1145/**
1146 * @brief Control DTC setting arguments
1147 */
1148typedef struct {
1149 uint8_t type; /*! invoked subfunction */
1150 size_t len; /*! length of data */
1151 void *data; /*! DTCSettingControlOptionRecord */
1153
1154/**
1155 * @brief Link control arguments
1156 */
1157typedef struct {
1158 const uint8_t type; /*! invoked subfunction */
1159 /* purposefully left generic to allow vehicle- and supplier specific data of different sizes */
1160 const size_t len; /*! length of data */
1161 const void *data; /*! data used in the subfunction. E.g. on SubFunction 0x01 this is the
1162 linkControlModelIdentifier, on SubFunction 0x02 this is the linkRecord */
1164
1165/**
1166 * @brief Custom service arguments
1167 */
1168typedef struct {
1169 const uint16_t sid; /*! serviceIdentifier */
1170 const uint8_t *optionRecord; /*! optional data */
1171 const uint16_t len; /*! length of optional data */
1172 uint8_t (*copyResponse)(UDSServer_t *srv, const void *src,
1173 uint16_t len); /*! function for copying response data (optional) */
1175
1176UDSErr_t UDSServerInit(UDSServer_t *srv);
1177void UDSServerPoll(UDSServer_t *srv);
1178
1179#if defined(UDS_TP_ISOTP_C)
1180#define ISO_TP_USER_SEND_CAN_ARG 1
1181#ifndef ISOTPC_CONFIG_H
1182#define ISOTPC_CONFIG_H
1183
1184/* Max number of messages the receiver can receive at one time, this value
1185 * is affected by can driver queue length
1186 */
1187#define ISO_TP_DEFAULT_BLOCK_SIZE 8
1188
1189/* The STmin parameter value specifies the minimum time gap allowed between
1190 * the transmission of consecutive frame network protocol data units
1191 */
1192#define ISO_TP_DEFAULT_ST_MIN_US 0
1193
1194/* This parameter indicate how many FC N_PDU WTs can be transmitted by the
1195 * receiver in a row.
1196 */
1197#define ISO_TP_MAX_WFT_NUMBER 1
1198
1199/* Private: The default timeout to use when waiting for a response during a
1200 * multi-frame send or receive.
1201 */
1202#define ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US 100000
1203
1204/* Private: Determines if by default, padding is added to ISO-TP message frames.
1205 */
1206//#define ISO_TP_FRAME_PADDING
1207
1208/* Private: Value to use when padding frames if enabled by ISO_TP_FRAME_PADDING
1209 */
1210#ifndef ISO_TP_FRAME_PADDING_VALUE
1211#define ISO_TP_FRAME_PADDING_VALUE 0xAA
1212#endif
1213
1214/* Private: Determines if by default, an additional argument is present in the
1215 * definition of isotp_user_send_can.
1216 */
1217//#define ISO_TP_USER_SEND_CAN_ARG
1218
1219#endif // ISOTPC_CONFIG_H
1220
1221#ifndef ISOTPC_USER_DEFINITIONS_H
1222#define ISOTPC_USER_DEFINITIONS_H
1223
1224#include <stdint.h>
1225
1226/**************************************************************
1227 * compiler specific defines
1228 *************************************************************/
1229#ifdef __GNUC__
1230#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1231#define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1232#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1233#else
1234#error "unsupported byte ordering"
1235#endif
1236#endif
1237
1238/**************************************************************
1239 * OS specific defines
1240 *************************************************************/
1241#ifdef _WIN32
1242#define snprintf _snprintf
1243#endif
1244
1245#ifdef _WIN32
1246#include <windows.h>
1247#define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1248#define __builtin_bswap8 _byteswap_uint8
1249#define __builtin_bswap16 _byteswap_uint16
1250#define __builtin_bswap32 _byteswap_uint32
1251#define __builtin_bswap64 _byteswap_uint64
1252#endif
1253
1254/**************************************************************
1255 * internal used defines
1256 *************************************************************/
1257#define ISOTP_RET_OK 0
1258#define ISOTP_RET_ERROR -1
1259#define ISOTP_RET_INPROGRESS -2
1260#define ISOTP_RET_OVERFLOW -3
1261#define ISOTP_RET_WRONG_SN -4
1262#define ISOTP_RET_NO_DATA -5
1263#define ISOTP_RET_TIMEOUT -6
1264#define ISOTP_RET_LENGTH -7
1265#define ISOTP_RET_NOSPACE -8
1266
1267/* return logic true if 'a' is after 'b' */
1268#define IsoTpTimeAfter(a,b) ((int32_t)((int32_t)(b) - (int32_t)(a)) < 0)
1269
1270/* invalid bs */
1271#define ISOTP_INVALID_BS 0xFFFF
1272
1273/* ISOTP sender status */
1274typedef enum {
1275 ISOTP_SEND_STATUS_IDLE,
1276 ISOTP_SEND_STATUS_INPROGRESS,
1277 ISOTP_SEND_STATUS_ERROR,
1278} IsoTpSendStatusTypes;
1279
1280/* ISOTP receiver status */
1281typedef enum {
1282 ISOTP_RECEIVE_STATUS_IDLE,
1283 ISOTP_RECEIVE_STATUS_INPROGRESS,
1284 ISOTP_RECEIVE_STATUS_FULL,
1285} IsoTpReceiveStatusTypes;
1286
1287/* can fram defination */
1288#if defined(ISOTP_BYTE_ORDER_LITTLE_ENDIAN)
1289typedef struct {
1290 uint8_t reserve_1:4;
1291 uint8_t type:4;
1292 uint8_t reserve_2[7];
1293} IsoTpPciType;
1294
1295typedef struct {
1296 uint8_t SF_DL:4;
1297 uint8_t type:4;
1298 uint8_t data[7];
1300
1301typedef struct {
1302 uint8_t FF_DL_high:4;
1303 uint8_t type:4;
1304 uint8_t FF_DL_low;
1305 uint8_t data[6];
1307
1308typedef struct {
1309 uint8_t SN:4;
1310 uint8_t type:4;
1311 uint8_t data[7];
1313
1314typedef struct {
1315 uint8_t FS:4;
1316 uint8_t type:4;
1317 uint8_t BS;
1318 uint8_t STmin;
1319 uint8_t reserve[5];
1321
1322#else
1323
1324typedef struct {
1325 uint8_t type:4;
1326 uint8_t reserve_1:4;
1327 uint8_t reserve_2[7];
1328} IsoTpPciType;
1329
1330/*
1331* single frame
1332* +-------------------------+-----+
1333* | byte #0 | ... |
1334* +-------------------------+-----+
1335* | nibble #0 | nibble #1 | ... |
1336* +-------------+-----------+ ... +
1337* | PCIType = 0 | SF_DL | ... |
1338* +-------------+-----------+-----+
1339*/
1340typedef struct {
1341 uint8_t type:4;
1342 uint8_t SF_DL:4;
1343 uint8_t data[7];
1345
1346/*
1347* first frame
1348* +-------------------------+-----------------------+-----+
1349* | byte #0 | byte #1 | ... |
1350* +-------------------------+-----------+-----------+-----+
1351* | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... |
1352* +-------------+-----------+-----------+-----------+-----+
1353* | PCIType = 1 | FF_DL | ... |
1354* +-------------+-----------+-----------------------+-----+
1355*/
1356typedef struct {
1357 uint8_t type:4;
1358 uint8_t FF_DL_high:4;
1359 uint8_t FF_DL_low;
1360 uint8_t data[6];
1362
1363/*
1364* consecutive frame
1365* +-------------------------+-----+
1366* | byte #0 | ... |
1367* +-------------------------+-----+
1368* | nibble #0 | nibble #1 | ... |
1369* +-------------+-----------+ ... +
1370* | PCIType = 0 | SN | ... |
1371* +-------------+-----------+-----+
1372*/
1373typedef struct {
1374 uint8_t type:4;
1375 uint8_t SN:4;
1376 uint8_t data[7];
1378
1379/*
1380* flow control frame
1381* +-------------------------+-----------------------+-----------------------+-----+
1382* | byte #0 | byte #1 | byte #2 | ... |
1383* +-------------------------+-----------+-----------+-----------+-----------+-----+
1384* | nibble #0 | nibble #1 | nibble #2 | nibble #3 | nibble #4 | nibble #5 | ... |
1385* +-------------+-----------+-----------+-----------+-----------+-----------+-----+
1386* | PCIType = 1 | FS | BS | STmin | ... |
1387* +-------------+-----------+-----------------------+-----------------------+-----+
1388*/
1389typedef struct {
1390 uint8_t type:4;
1391 uint8_t FS:4;
1392 uint8_t BS;
1393 uint8_t STmin;
1394 uint8_t reserve[5];
1396
1397#endif
1398
1399typedef struct {
1400 uint8_t ptr[8];
1402
1403typedef struct {
1404 union {
1405 IsoTpPciType common;
1406 IsoTpSingleFrame single_frame;
1407 IsoTpFirstFrame first_frame;
1408 IsoTpConsecutiveFrame consecutive_frame;
1409 IsoTpFlowControl flow_control;
1410 IsoTpDataArray data_array;
1411 } as;
1413
1414/**************************************************************
1415 * protocol specific defines
1416 *************************************************************/
1417
1418/* Private: Protocol Control Information (PCI) types, for identifying each frame of an ISO-TP message.
1419 */
1420typedef enum {
1421 ISOTP_PCI_TYPE_SINGLE = 0x0,
1422 ISOTP_PCI_TYPE_FIRST_FRAME = 0x1,
1423 TSOTP_PCI_TYPE_CONSECUTIVE_FRAME = 0x2,
1424 ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME = 0x3
1425} IsoTpProtocolControlInformation;
1426
1427/* Private: Protocol Control Information (PCI) flow control identifiers.
1428 */
1429typedef enum {
1430 PCI_FLOW_STATUS_CONTINUE = 0x0,
1431 PCI_FLOW_STATUS_WAIT = 0x1,
1432 PCI_FLOW_STATUS_OVERFLOW = 0x2
1433} IsoTpFlowStatus;
1434
1435/* Private: network layer resault code.
1436 */
1437#define ISOTP_PROTOCOL_RESULT_OK 0
1438#define ISOTP_PROTOCOL_RESULT_TIMEOUT_A -1
1439#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS -2
1440#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR -3
1441#define ISOTP_PROTOCOL_RESULT_WRONG_SN -4
1442#define ISOTP_PROTOCOL_RESULT_INVALID_FS -5
1443#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU -6
1444#define ISOTP_PROTOCOL_RESULT_WFT_OVRN -7
1445#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW -8
1446#define ISOTP_PROTOCOL_RESULT_ERROR -9
1447
1448#endif // ISOTPC_USER_DEFINITIONS_H
1449#ifndef ISOTPC_USER_H
1450#define ISOTPC_USER_H
1451
1452#include <stdint.h>
1453
1454#ifdef __cplusplus
1455extern "C" {
1456#endif
1457
1458/** @brief user implemented, print debug message */
1459void isotp_user_debug(const char* message, ...);
1460
1461/**
1462 * @brief user implemented, send can message. should return ISOTP_RET_OK when success.
1463 *
1464 * @return may return ISOTP_RET_NOSPACE if the CAN transfer should be retried later
1465 * or ISOTP_RET_ERROR if transmission couldn't be completed
1466 */
1467int isotp_user_send_can(const uint32_t arbitration_id,
1468 const uint8_t* data, const uint8_t size
1469#if ISO_TP_USER_SEND_CAN_ARG
1470,void *arg
1471#endif
1472 );
1473
1474/**
1475 * @brief user implemented, gets the amount of time passed since the last call in microseconds
1476 */
1477uint32_t isotp_user_get_us(void);
1478
1479#ifdef __cplusplus
1480}
1481#endif
1482
1483#endif // ISOTPC_USER_H
1484
1485
1486#ifndef ISOTPC_H
1487#define ISOTPC_H
1488
1489#include <stdio.h>
1490#include <string.h>
1491
1492#ifdef __cplusplus
1493#include <stdint.h>
1494
1495extern "C" {
1496#endif
1497
1498
1499/**
1500 * @brief Struct containing the data for linking an application to a CAN instance.
1501 * The data stored in this struct is used internally and may be used by software programs
1502 * using this library.
1503 */
1504typedef struct IsoTpLink {
1505 /* sender paramters */
1506 uint32_t send_arbitration_id; /* used to reply consecutive frame */
1507 /* message buffer */
1508 uint8_t* send_buffer;
1509 uint16_t send_buf_size;
1510 uint16_t send_size;
1511 uint16_t send_offset;
1512 /* multi-frame flags */
1513 uint8_t send_sn;
1514 uint16_t send_bs_remain; /* Remaining block size */
1515 uint32_t send_st_min_us; /* Separation Time between consecutive frames */
1516 uint8_t send_wtf_count; /* Maximum number of FC.Wait frame transmissions */
1517 uint32_t send_timer_st; /* Last time send consecutive frame */
1518 uint32_t send_timer_bs; /* Time until reception of the next FlowControl N_PDU
1519 start at sending FF, CF, receive FC
1520 end at receive FC */
1521 int send_protocol_result;
1522 uint8_t send_status;
1523 /* receiver paramters */
1524 uint32_t receive_arbitration_id;
1525 /* message buffer */
1526 uint8_t* receive_buffer;
1527 uint16_t receive_buf_size;
1528 uint16_t receive_size;
1529 uint16_t receive_offset;
1530 /* multi-frame control */
1531 uint8_t receive_sn;
1532 uint8_t receive_bs_count; /* Maximum number of FC.Wait frame transmissions */
1533 uint32_t receive_timer_cr; /* Time until transmission of the next ConsecutiveFrame N_PDU
1534 start at sending FC, receive CF
1535 end at receive FC */
1536 int receive_protocol_result;
1537 uint8_t receive_status;
1538
1539#if defined(ISO_TP_USER_SEND_CAN_ARG)
1540 void* user_send_can_arg;
1541#endif
1542} IsoTpLink;
1543
1544/**
1545 * @brief Initialises the ISO-TP library.
1546 *
1547 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1548 * @param sendid The ID used to send data to other CAN nodes.
1549 * @param sendbuf A pointer to an area in memory which can be used as a buffer for data to be sent.
1550 * @param sendbufsize The size of the buffer area.
1551 * @param recvbuf A pointer to an area in memory which can be used as a buffer for data to be received.
1552 * @param recvbufsize The size of the buffer area.
1553 */
1554void isotp_init_link(IsoTpLink *link, uint32_t sendid,
1555 uint8_t *sendbuf, uint16_t sendbufsize,
1556 uint8_t *recvbuf, uint16_t recvbufsize);
1557
1558/**
1559 * @brief Polling function; call this function periodically to handle timeouts, send consecutive frames, etc.
1560 *
1561 * @param link The @code IsoTpLink @endcode instance used.
1562 */
1563void isotp_poll(IsoTpLink *link);
1564
1565/**
1566 * @brief Handles incoming CAN messages.
1567 * Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly.
1568 *
1569 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1570 * @param data The data received via CAN.
1571 * @param len The length of the data received.
1572 */
1573void isotp_on_can_message(IsoTpLink *link, const uint8_t *data, uint8_t len);
1574
1575/**
1576 * @brief Sends ISO-TP frames via CAN, using the ID set in the initialising function.
1577 *
1578 * Single-frame messages will be sent immediately when calling this function.
1579 * Multi-frame messages will be sent consecutively when calling isotp_poll.
1580 *
1581 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1582 * @param payload The payload to be sent. (Up to 4095 bytes).
1583 * @param size The size of the payload to be sent.
1584 *
1585 * @return Possible return values:
1586 * - @code ISOTP_RET_OVERFLOW @endcode
1587 * - @code ISOTP_RET_INPROGRESS @endcode
1588 * - @code ISOTP_RET_OK @endcode
1589 * - The return value of the user shim function isotp_user_send_can().
1590 */
1591int isotp_send(IsoTpLink *link, const uint8_t payload[], uint16_t size);
1592
1593/**
1594 * @brief See @link isotp_send @endlink, with the exception that this function is used only for functional addressing.
1595 */
1596int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], uint16_t size);
1597
1598/**
1599 * @brief Receives and parses the received data and copies the parsed data in to the internal buffer.
1600 * @param link The @link IsoTpLink @endlink instance used to transceive data.
1601 * @param payload A pointer to an area in memory where the raw data is copied from.
1602 * @param payload_size The size of the received (raw) CAN data.
1603 * @param out_size A reference to a variable which will contain the size of the actual (parsed) data.
1604 *
1605 * @return Possible return values:
1606 * - @link ISOTP_RET_OK @endlink
1607 * - @link ISOTP_RET_NO_DATA @endlink
1608 */
1609int isotp_receive(IsoTpLink *link, uint8_t *payload, const uint16_t payload_size, uint16_t *out_size);
1610
1611#ifdef __cplusplus
1612}
1613#endif
1614
1615#endif // ISOTPC_H
1616
1617#endif
1618
1619#if defined(UDS_TP_ISOTP_C)
1620
1621
1622typedef struct {
1623 UDSTp_t hdl;
1624 IsoTpLink phys_link;
1625 IsoTpLink func_link;
1626 uint8_t send_buf[UDS_ISOTP_MTU];
1627 uint8_t recv_buf[UDS_ISOTP_MTU];
1628 uint32_t phys_sa, phys_ta;
1629 uint32_t func_sa, func_ta;
1630} UDSISOTpC_t;
1631
1632typedef struct {
1633 uint32_t source_addr;
1634 uint32_t target_addr;
1635 uint32_t source_addr_func;
1636 uint32_t target_addr_func;
1638
1639UDSErr_t UDSISOTpCInit(UDSISOTpC_t *tp, const UDSISOTpCConfig_t *cfg);
1640
1641void UDSISOTpCDeinit(UDSISOTpC_t *tp);
1642
1643#endif
1644
1645
1646
1647#if defined(UDS_TP_ISOTP_C_SOCKETCAN)
1648
1649
1650typedef struct {
1651 UDSTp_t hdl;
1652 IsoTpLink phys_link;
1653 IsoTpLink func_link;
1654 uint8_t send_buf[UDS_ISOTP_MTU];
1655 uint8_t recv_buf[UDS_ISOTP_MTU];
1656 int fd;
1657 uint32_t phys_sa, phys_ta;
1658 uint32_t func_sa, func_ta;
1659 char tag[16];
1661
1662UDSErr_t UDSTpISOTpCInit(UDSTpISOTpC_t *tp, const char *ifname, uint32_t source_addr,
1663 uint32_t target_addr, uint32_t source_addr_func,
1664 uint32_t target_addr_func);
1665void UDSTpISOTpCDeinit(UDSTpISOTpC_t *tp);
1666
1667#endif
1668
1669
1670#if defined(UDS_TP_ISOTP_SOCK)
1671
1672
1673typedef struct {
1674 UDSTp_t hdl;
1675 uint8_t recv_buf[UDS_ISOTP_MTU];
1676 uint8_t send_buf[UDS_ISOTP_MTU];
1677 size_t recv_len;
1678 UDSSDU_t recv_info;
1679 int phys_fd;
1680 int func_fd;
1681 uint32_t phys_sa, phys_ta;
1682 uint32_t func_sa, func_ta;
1683 char tag[16];
1685
1686UDSErr_t UDSTpIsoTpSockInitServer(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
1687 uint32_t target_addr, uint32_t source_addr_func);
1688UDSErr_t UDSTpIsoTpSockInitClient(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
1689 uint32_t target_addr, uint32_t target_addr_func);
1690void UDSTpIsoTpSockDeinit(UDSTpIsoTpSock_t *tp);
1691
1692#endif
1693
1694
1695/**
1696 * @file isotp_mock.h
1697 * @brief in-memory ISO15765 (ISO-TP) transport layer implementation for testing
1698 * @date 2023-10-21
1699 *
1700 */
1701#if defined(UDS_TP_ISOTP_MOCK)
1702
1703
1704
1705typedef struct ISOTPMock {
1706 UDSTp_t hdl;
1707 uint8_t recv_buf[UDS_TP_MTU];
1708 uint8_t send_buf[UDS_TP_MTU];
1709 size_t recv_len;
1710 UDSSDU_t recv_info;
1711 uint32_t sa_phys; // source address - physical messages are sent from this address
1712 uint32_t ta_phys; // target address - physical messages are sent to this address
1713 uint32_t sa_func; // source address - functional messages are sent from this address
1714 uint32_t ta_func; // target address - functional messages are sent to this address
1715 uint32_t send_tx_delay_ms; // simulated delay
1716 uint32_t send_buf_size; // simulated size of the send buffer
1717 char name[32]; // name for logging
1718} ISOTPMock_t;
1719
1720typedef struct {
1721 uint32_t sa_phys; // source address - physical messages are sent from this address
1722 uint32_t ta_phys; // target address - physical messages are sent to this address
1723 uint32_t sa_func; // source address - functional messages are sent from this address
1724 uint32_t ta_func; // target address - functional messages are sent to this address
1726
1727/**
1728 * @brief Create a mock transport. It is connected by default to a broadcast network of all other
1729 * mock transports in the same process.
1730 * @param name optional name of the transport (can be NULL)
1731 * @return UDSTp_t*
1732 */
1733UDSTp_t *ISOTPMockNew(const char *name, ISOTPMockArgs_t *args);
1734void ISOTPMockFree(UDSTp_t *tp);
1735
1736/**
1737 * @brief write all messages to a file
1738 * @note uses UDSMillis() to get the current time
1739 * @param filename log file name (will be overwritten)
1740 */
1741void ISOTPMockLogToFile(const char *filename);
1742void ISOTPMockLogToStdout(void);
1743
1744/**
1745 * @brief clear all transports and close the log file
1746 */
1747void ISOTPMockReset(void);
1748
1749#endif
1750
1751
1752#ifdef __cplusplus
1753}
1754#endif
1755
1756#endif
UDSEvent_t
UDS events.
Definition iso14229.h:298
@ UDS_EVT_Custom
Definition iso14229.h:324
@ UDS_EVT_RequestFileTransfer
Definition iso14229.h:321
@ UDS_EVT_ReadDTCInformation
Definition iso14229.h:304
@ UDS_EVT_ClearDiagnosticInfo
Definition iso14229.h:303
@ UDS_EVT_DiagSessCtrl
Definition iso14229.h:301
@ UDS_EVT_DynamicDefineDataId
Definition iso14229.h:312
@ UDS_EVT_SecAccessRequestSeed
Definition iso14229.h:308
@ UDS_EVT_SessionTimeout
Definition iso14229.h:319
@ UDS_EVT_WriteMemByAddr
Definition iso14229.h:311
@ UDS_EVT_SecAccessValidateKey
Definition iso14229.h:309
@ UDS_EVT_TransferData
Definition iso14229.h:317
@ UDS_EVT_RequestDownload
Definition iso14229.h:315
@ UDS_EVT_RoutineCtrl
Definition iso14229.h:314
@ UDS_EVT_Poll
Definition iso14229.h:326
@ UDS_EVT_WriteDataByIdent
Definition iso14229.h:310
@ UDS_EVT_RequestTransferExit
Definition iso14229.h:318
@ UDS_EVT_ReadMemByAddr
Definition iso14229.h:306
@ UDS_EVT_CommCtrl
Definition iso14229.h:307
@ UDS_EVT_ResponseReceived
Definition iso14229.h:328
@ UDS_EVT_SendComplete
Definition iso14229.h:327
@ UDS_EVT_Idle
Definition iso14229.h:329
@ UDS_EVT_RequestUpload
Definition iso14229.h:316
@ UDS_EVT_LinkControl
Definition iso14229.h:323
@ UDS_EVT_ControlDTCSetting
Definition iso14229.h:322
@ UDS_EVT_IOControl
Definition iso14229.h:313
@ UDS_EVT_EcuReset
Definition iso14229.h:302
@ UDS_EVT_DoScheduledReset
Definition iso14229.h:320
@ UDS_EVT_Err
Definition iso14229.h:299
@ UDS_EVT_MAX
Definition iso14229.h:331
@ UDS_EVT_ReadDataByIdent
Definition iso14229.h:305
void isotp_user_debug(const char *message,...)
user implemented, print debug message
uint32_t isotp_user_get_us(void)
user implemented, gets the amount of time passed since the last call in microseconds
Definition iso14229.c:3029
UDSTp_t * ISOTPMockNew(const char *name, ISOTPMockArgs_t *args)
Create a mock transport. It is connected by default to a broadcast network of all other mock transpor...
Definition iso14229.c:3660
uint32_t UDSMillis(void)
Get time in milliseconds.
Definition iso14229.c:2532
int isotp_receive(IsoTpLink *link, uint8_t *payload, const uint16_t payload_size, uint16_t *out_size)
Receives and parses the received data and copies the parsed data in to the internal buffer.
Definition iso14229.c:4185
void isotp_on_can_message(IsoTpLink *link, const uint8_t *data, uint8_t len)
Handles incoming CAN messages. Determines whether an incoming message is a valid ISO-TP frame or not ...
Definition iso14229.c:4036
void isotp_init_link(IsoTpLink *link, uint32_t sendid, uint8_t *sendbuf, uint16_t sendbufsize, uint8_t *recvbuf, uint16_t recvbufsize)
Initialises the ISO-TP library.
Definition iso14229.c:4205
void isotp_poll(IsoTpLink *link)
Polling function; call this function periodically to handle timeouts, send consecutive frames,...
Definition iso14229.c:4218
int isotp_user_send_can(const uint32_t arbitration_id, const uint8_t *data, const uint8_t size, void *arg)
user implemented, send can message. should return ISOTP_RET_OK when success.
Definition iso14229.c:3041
void ISOTPMockReset(void)
clear all transports and close the log file
Definition iso14229.c:3704
bool UDSSecurityAccessLevelIsReserved(uint8_t securityLevel)
Check if a security level is reserved per ISO14229-1:2020 Table 42.
Definition iso14229.c:2560
int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], uint16_t size)
See isotp_send, with the exception that this function is used only for functional addressing.
Definition iso14229.c:3983
#define UDS_ISOTP_MTU
Definition iso14229.h:114
int isotp_send(IsoTpLink *link, const uint8_t payload[], uint16_t size)
Sends ISO-TP frames via CAN, using the ID set in the initialising function.
Definition iso14229.c:3979
void ISOTPMockLogToFile(const char *filename)
write all messages to a file
Definition iso14229.c:3680
Request download response structure.
Definition iso14229.h:762
Routine control response structure.
Definition iso14229.h:769
const uint8_t * routineStatusRecord
Definition iso14229.h:772
uint16_t routineIdentifier
Definition iso14229.h:771
uint16_t routineStatusRecordLength
Definition iso14229.h:773
Security access response structure.
Definition iso14229.h:753
uint16_t securitySeedLength
Definition iso14229.h:756
const uint8_t * securitySeed
Definition iso14229.h:755
Clear diagnostic information arguments.
Definition iso14229.h:923
const uint8_t memorySelection
Definition iso14229.h:926
const bool hasMemorySelection
Definition iso14229.h:925
UDS client structure.
Definition iso14229.h:729
uint16_t p2_ms
Definition iso14229.h:730
uint8_t defaultOptions
Definition iso14229.h:738
uint32_t p2_timer
Definition iso14229.h:734
uint8_t state
Definition iso14229.h:735
uint16_t send_size
Definition iso14229.h:745
uint32_t p2_star_ms
Definition iso14229.h:731
uint8_t _options_copy
Definition iso14229.h:739
uint8_t options
Definition iso14229.h:737
void * fn_data
Definition iso14229.h:742
uint16_t recv_size
Definition iso14229.h:744
UDSTp_t * tp
Definition iso14229.h:732
Communication control arguments.
Definition iso14229.h:997
Control DTC setting arguments.
Definition iso14229.h:1148
Custom service arguments.
Definition iso14229.h:1168
const uint8_t * optionRecord
Definition iso14229.h:1170
const uint16_t len
Definition iso14229.h:1171
Dynamically define data identifier arguments.
Definition iso14229.h:1044
uint8_t size
Definition iso14229.h:1054
uint8_t position
Definition iso14229.h:1053
uint16_t dynamicDataId
Definition iso14229.h:1048
Diagnostic session control arguments.
Definition iso14229.h:905
ECU reset arguments.
Definition iso14229.h:914
uint32_t powerDownTimeMillis
Definition iso14229.h:916
const uint8_t type
Definition iso14229.h:915
Input/output control by identifier arguments.
Definition iso14229.h:1066
const uint8_t ioCtrlParam
Definition iso14229.h:1068
const size_t ctrlStateAndMaskLen
Definition iso14229.h:1070
const void *const ctrlStateAndMask
Definition iso14229.h:1069
Link control arguments.
Definition iso14229.h:1157
const void * data
Definition iso14229.h:1161
const size_t len
Definition iso14229.h:1160
Read data by identifier arguments.
Definition iso14229.h:978
Read data by identifier variable structure.
Definition iso14229.h:779
uint16_t len
Definition iso14229.h:781
uint16_t did
Definition iso14229.h:780
void * data
Definition iso14229.h:782
Read DTC information arguments.
Definition iso14229.h:932
uint8_t statusMask
Definition iso14229.h:958
uint8_t extDataRecNum
Definition iso14229.h:951
uint8_t memory
Definition iso14229.h:944
uint8_t snapshotNum
Definition iso14229.h:943
uint8_t severityMask
Definition iso14229.h:957
uint8_t readinessGroup
Definition iso14229.h:970
Read memory by address arguments.
Definition iso14229.h:987
Server request context.
Definition iso14229.h:838
size_t send_len
Definition iso14229.h:842
size_t recv_len
Definition iso14229.h:841
UDSSDU_t info
Definition iso14229.h:844
size_t send_buf_size
Definition iso14229.h:843
Request download arguments.
Definition iso14229.h:1090
const uint8_t dataFormatIdentifier
Definition iso14229.h:1093
uint16_t maxNumberOfBlockLength
Definition iso14229.h:1094
Request file transfer arguments.
Definition iso14229.h:1134
const size_t fileSizeUnCompressed
Definition iso14229.h:1139
const size_t fileSizeCompressed
Definition iso14229.h:1140
const uint8_t dataFormatIdentifier
Definition iso14229.h:1138
Request transfer exit arguments.
Definition iso14229.h:1124
Request upload arguments.
Definition iso14229.h:1101
uint16_t maxNumberOfBlockLength
Definition iso14229.h:1105
const uint8_t dataFormatIdentifier
Definition iso14229.h:1104
Routine control arguments.
Definition iso14229.h:1078
const uint8_t * optionRecord
Definition iso14229.h:1081
const uint16_t id
Definition iso14229.h:1080
const uint16_t len
Definition iso14229.h:1082
Service data unit (SDU)
Definition iso14229.h:239
uint32_t A_SA
Definition iso14229.h:242
uint32_t A_TA
Definition iso14229.h:243
uint32_t A_AE
Definition iso14229.h:245
UDS_A_Mtype_t A_Mtype
Definition iso14229.h:240
UDS_A_TA_Type_t A_TA_Type
Definition iso14229.h:244
Security access request seed arguments.
Definition iso14229.h:1006
const uint8_t *const dataRecord
Definition iso14229.h:1008
Security access validate key arguments.
Definition iso14229.h:1017
const uint8_t *const key
Definition iso14229.h:1019
UDS server structure.
Definition iso14229.h:850
size_t xferTotalBytes
Definition iso14229.h:878
uint32_t sec_access_auth_fail_timer
Definition iso14229.h:866
uint16_t p2_ms
Server time constants (milliseconds)
Definition iso14229.h:858
uint32_t p2_star_ms
Definition iso14229.h:859
bool notReadyToReceive
UDS-1 2013 defines the following conditions under which the server does not process incoming requests...
Definition iso14229.h:897
uint8_t securityLevel
Definition iso14229.h:883
uint32_t sec_access_boot_delay_timer
Definition iso14229.h:867
uint16_t s3_ms
Definition iso14229.h:860
UDSReq_t r
Definition iso14229.h:899
void * fn_data
Definition iso14229.h:853
UDSTp_t * tp
Definition iso14229.h:851
size_t xferBlockLength
Definition iso14229.h:880
uint32_t s3_session_timeout_timer
Definition iso14229.h:865
size_t xferByteCounter
Definition iso14229.h:879
uint8_t ecuResetScheduled
Definition iso14229.h:862
uint8_t xferBlockSequenceCounter
Definition iso14229.h:876
uint32_t p2_timer
Definition iso14229.h:864
uint8_t sessionType
Definition iso14229.h:882
bool xferIsActive
UDS-1-2013: Table 407 - 0x36 TransferData Supported negative response codes requires that the server ...
Definition iso14229.h:875
bool requestInProgress
Definition iso14229.h:886
uint32_t ecuResetTimer
Definition iso14229.h:863
UDS Transport layer.
Definition iso14229.h:254
Transfer data arguments.
Definition iso14229.h:1112
const uint16_t len
Definition iso14229.h:1114
const uint16_t maxRespLen
Definition iso14229.h:1115
Write data by identifier arguments.
Definition iso14229.h:1026
const uint16_t len
Definition iso14229.h:1029
const uint8_t *const data
Definition iso14229.h:1028
Write memory by address arguments.
Definition iso14229.h:1035
const uint8_t *const data
Definition iso14229.h:1038