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#ifndef ISO_TP_DEFAULT_BLOCK_SIZE
1188#define ISO_TP_DEFAULT_BLOCK_SIZE 8
1189#endif
1190
1191/* The STmin parameter value specifies the minimum time gap allowed between
1192 * the transmission of consecutive frame network protocol data units
1193 */
1194#ifndef ISO_TP_DEFAULT_ST_MIN_US
1195#define ISO_TP_DEFAULT_ST_MIN_US 0
1196#endif
1197
1198/* This parameter indicate how many FC N_PDU WTs can be transmitted by the
1199 * receiver in a row.
1200 */
1201#ifndef ISO_TP_MAX_WFT_NUMBER
1202#define ISO_TP_MAX_WFT_NUMBER 1
1203#endif
1204
1205/* Private: The default timeout to use when waiting for a response during a
1206 * multi-frame send or receive.
1207 */
1208#ifndef ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US
1209#define ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US 100000
1210#endif
1211
1212/* Private: Determines if by default, padding is added to ISO-TP message frames.
1213 */
1214//#define ISO_TP_FRAME_PADDING
1215
1216/* Private: Value to use when padding frames if enabled by ISO_TP_FRAME_PADDING
1217 */
1218#ifndef ISO_TP_FRAME_PADDING_VALUE
1219#define ISO_TP_FRAME_PADDING_VALUE 0xAA
1220#endif
1221
1222/* Private: Determines if by default, an additional argument is present in the
1223 * definition of isotp_user_send_can.
1224 */
1225//#define ISO_TP_USER_SEND_CAN_ARG
1226
1227#endif // ISOTPC_CONFIG_H
1228
1229#ifndef ISOTPC_USER_DEFINITIONS_H
1230#define ISOTPC_USER_DEFINITIONS_H
1231
1232#include <stdint.h>
1233
1234/**************************************************************
1235 * compiler specific defines
1236 *************************************************************/
1237#ifdef __GNUC__
1238#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1239#define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1240#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1241#else
1242#error "unsupported byte ordering"
1243#endif
1244#endif
1245
1246/**************************************************************
1247 * OS specific defines
1248 *************************************************************/
1249#ifdef _WIN32
1250#define snprintf _snprintf
1251#endif
1252
1253#ifdef _WIN32
1254#include <windows.h>
1255#define ISOTP_BYTE_ORDER_LITTLE_ENDIAN
1256#define __builtin_bswap8 _byteswap_uint8
1257#define __builtin_bswap16 _byteswap_uint16
1258#define __builtin_bswap32 _byteswap_uint32
1259#define __builtin_bswap64 _byteswap_uint64
1260#endif
1261
1262/**************************************************************
1263 * internal used defines
1264 *************************************************************/
1265#define ISOTP_RET_OK 0
1266#define ISOTP_RET_ERROR -1
1267#define ISOTP_RET_INPROGRESS -2
1268#define ISOTP_RET_OVERFLOW -3
1269#define ISOTP_RET_WRONG_SN -4
1270#define ISOTP_RET_NO_DATA -5
1271#define ISOTP_RET_TIMEOUT -6
1272#define ISOTP_RET_LENGTH -7
1273#define ISOTP_RET_NOSPACE -8
1274
1275/* return logic true if 'a' is after 'b' */
1276#define IsoTpTimeAfter(a,b) ((int32_t)((int32_t)(b) - (int32_t)(a)) < 0)
1277
1278/* invalid bs */
1279#define ISOTP_INVALID_BS 0xFFFF
1280
1281/* ISOTP sender status */
1282typedef enum {
1283 ISOTP_SEND_STATUS_IDLE,
1284 ISOTP_SEND_STATUS_INPROGRESS,
1285 ISOTP_SEND_STATUS_ERROR,
1286} IsoTpSendStatusTypes;
1287
1288/* ISOTP receiver status */
1289typedef enum {
1290 ISOTP_RECEIVE_STATUS_IDLE,
1291 ISOTP_RECEIVE_STATUS_INPROGRESS,
1292 ISOTP_RECEIVE_STATUS_FULL,
1293} IsoTpReceiveStatusTypes;
1294
1295/* can fram defination */
1296#if defined(ISOTP_BYTE_ORDER_LITTLE_ENDIAN)
1297typedef struct {
1298 uint8_t reserve_1:4;
1299 uint8_t type:4;
1300 uint8_t reserve_2[7];
1301} IsoTpPciType;
1302
1303typedef struct {
1304 uint8_t SF_DL:4;
1305 uint8_t type:4;
1306 uint8_t data[7];
1308
1309typedef struct {
1310 uint8_t FF_DL_high:4;
1311 uint8_t type:4;
1312 uint8_t FF_DL_low;
1313 uint8_t data[6];
1315
1316typedef struct {
1317 uint8_t SN:4;
1318 uint8_t type:4;
1319 uint8_t data[7];
1321
1322typedef struct {
1323 uint8_t FS:4;
1324 uint8_t type:4;
1325 uint8_t BS;
1326 uint8_t STmin;
1327 uint8_t reserve[5];
1329
1330#else
1331
1332typedef struct {
1333 uint8_t type:4;
1334 uint8_t reserve_1:4;
1335 uint8_t reserve_2[7];
1336} IsoTpPciType;
1337
1338/*
1339* single frame
1340* +-------------------------+-----+
1341* | byte #0 | ... |
1342* +-------------------------+-----+
1343* | nibble #0 | nibble #1 | ... |
1344* +-------------+-----------+ ... +
1345* | PCIType = 0 | SF_DL | ... |
1346* +-------------+-----------+-----+
1347*/
1348typedef struct {
1349 uint8_t type:4;
1350 uint8_t SF_DL:4;
1351 uint8_t data[7];
1353
1354/*
1355* first frame
1356* +-------------------------+-----------------------+-----+
1357* | byte #0 | byte #1 | ... |
1358* +-------------------------+-----------+-----------+-----+
1359* | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... |
1360* +-------------+-----------+-----------+-----------+-----+
1361* | PCIType = 1 | FF_DL | ... |
1362* +-------------+-----------+-----------------------+-----+
1363*/
1364typedef struct {
1365 uint8_t type:4;
1366 uint8_t FF_DL_high:4;
1367 uint8_t FF_DL_low;
1368 uint8_t data[6];
1370
1371/*
1372* consecutive frame
1373* +-------------------------+-----+
1374* | byte #0 | ... |
1375* +-------------------------+-----+
1376* | nibble #0 | nibble #1 | ... |
1377* +-------------+-----------+ ... +
1378* | PCIType = 0 | SN | ... |
1379* +-------------+-----------+-----+
1380*/
1381typedef struct {
1382 uint8_t type:4;
1383 uint8_t SN:4;
1384 uint8_t data[7];
1386
1387/*
1388* flow control frame
1389* +-------------------------+-----------------------+-----------------------+-----+
1390* | byte #0 | byte #1 | byte #2 | ... |
1391* +-------------------------+-----------+-----------+-----------+-----------+-----+
1392* | nibble #0 | nibble #1 | nibble #2 | nibble #3 | nibble #4 | nibble #5 | ... |
1393* +-------------+-----------+-----------+-----------+-----------+-----------+-----+
1394* | PCIType = 1 | FS | BS | STmin | ... |
1395* +-------------+-----------+-----------------------+-----------------------+-----+
1396*/
1397typedef struct {
1398 uint8_t type:4;
1399 uint8_t FS:4;
1400 uint8_t BS;
1401 uint8_t STmin;
1402 uint8_t reserve[5];
1404
1405#endif
1406
1407typedef struct {
1408 uint8_t ptr[8];
1410
1411typedef struct {
1412 union {
1413 IsoTpPciType common;
1414 IsoTpSingleFrame single_frame;
1415 IsoTpFirstFrame first_frame;
1416 IsoTpConsecutiveFrame consecutive_frame;
1417 IsoTpFlowControl flow_control;
1418 IsoTpDataArray data_array;
1419 } as;
1421
1422/**************************************************************
1423 * protocol specific defines
1424 *************************************************************/
1425
1426/* Private: Protocol Control Information (PCI) types, for identifying each frame of an ISO-TP message.
1427 */
1428typedef enum {
1429 ISOTP_PCI_TYPE_SINGLE = 0x0,
1430 ISOTP_PCI_TYPE_FIRST_FRAME = 0x1,
1431 TSOTP_PCI_TYPE_CONSECUTIVE_FRAME = 0x2,
1432 ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME = 0x3
1433} IsoTpProtocolControlInformation;
1434
1435/* Private: Protocol Control Information (PCI) flow control identifiers.
1436 */
1437typedef enum {
1438 PCI_FLOW_STATUS_CONTINUE = 0x0,
1439 PCI_FLOW_STATUS_WAIT = 0x1,
1440 PCI_FLOW_STATUS_OVERFLOW = 0x2
1441} IsoTpFlowStatus;
1442
1443/* Private: network layer resault code.
1444 */
1445#define ISOTP_PROTOCOL_RESULT_OK 0
1446#define ISOTP_PROTOCOL_RESULT_TIMEOUT_A -1
1447#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS -2
1448#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR -3
1449#define ISOTP_PROTOCOL_RESULT_WRONG_SN -4
1450#define ISOTP_PROTOCOL_RESULT_INVALID_FS -5
1451#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU -6
1452#define ISOTP_PROTOCOL_RESULT_WFT_OVRN -7
1453#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW -8
1454#define ISOTP_PROTOCOL_RESULT_ERROR -9
1455
1456#endif // ISOTPC_USER_DEFINITIONS_H
1457#ifndef ISOTPC_USER_H
1458#define ISOTPC_USER_H
1459
1460#include <stdint.h>
1461
1462#ifdef __cplusplus
1463extern "C" {
1464#endif
1465
1466/** @brief user implemented, print debug message */
1467void isotp_user_debug(const char* message, ...);
1468
1469/**
1470 * @brief user implemented, send can message. should return ISOTP_RET_OK when success.
1471 *
1472 * @return may return ISOTP_RET_NOSPACE if the CAN transfer should be retried later
1473 * or ISOTP_RET_ERROR if transmission couldn't be completed
1474 */
1475int isotp_user_send_can(const uint32_t arbitration_id,
1476 const uint8_t* data, const uint8_t size
1477#if ISO_TP_USER_SEND_CAN_ARG
1478,void *arg
1479#endif
1480 );
1481
1482/**
1483 * @brief user implemented, gets the amount of time passed since the last call in microseconds
1484 */
1485uint32_t isotp_user_get_us(void);
1486
1487#ifdef __cplusplus
1488}
1489#endif
1490
1491#endif // ISOTPC_USER_H
1492
1493
1494#ifndef ISOTPC_H
1495#define ISOTPC_H
1496
1497#include <stdio.h>
1498#include <string.h>
1499
1500#ifdef __cplusplus
1501#include <stdint.h>
1502
1503extern "C" {
1504#endif
1505
1506
1507/**
1508 * @brief Struct containing the data for linking an application to a CAN instance.
1509 * The data stored in this struct is used internally and may be used by software programs
1510 * using this library.
1511 */
1512typedef struct IsoTpLink {
1513 /* sender paramters */
1514 uint32_t send_arbitration_id; /* used to reply consecutive frame */
1515 /* message buffer */
1516 uint8_t* send_buffer;
1517 uint16_t send_buf_size;
1518 uint16_t send_size;
1519 uint16_t send_offset;
1520 /* multi-frame flags */
1521 uint8_t send_sn;
1522 uint16_t send_bs_remain; /* Remaining block size */
1523 uint32_t send_st_min_us; /* Separation Time between consecutive frames */
1524 uint8_t send_wtf_count; /* Maximum number of FC.Wait frame transmissions */
1525 uint32_t send_timer_st; /* Last time send consecutive frame */
1526 uint32_t send_timer_bs; /* Time until reception of the next FlowControl N_PDU
1527 start at sending FF, CF, receive FC
1528 end at receive FC */
1529 int send_protocol_result;
1530 uint8_t send_status;
1531 /* receiver paramters */
1532 uint32_t receive_arbitration_id;
1533 /* message buffer */
1534 uint8_t* receive_buffer;
1535 uint16_t receive_buf_size;
1536 uint16_t receive_size;
1537 uint16_t receive_offset;
1538 /* multi-frame control */
1539 uint8_t receive_sn;
1540 uint8_t receive_bs_count; /* Maximum number of FC.Wait frame transmissions */
1541 uint32_t receive_timer_cr; /* Time until transmission of the next ConsecutiveFrame N_PDU
1542 start at sending FC, receive CF
1543 end at receive FC */
1544 int receive_protocol_result;
1545 uint8_t receive_status;
1546
1547#if defined(ISO_TP_USER_SEND_CAN_ARG)
1548 void* user_send_can_arg;
1549#endif
1550} IsoTpLink;
1551
1552/**
1553 * @brief Initialises the ISO-TP library.
1554 *
1555 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1556 * @param sendid The ID used to send data to other CAN nodes.
1557 * @param sendbuf A pointer to an area in memory which can be used as a buffer for data to be sent.
1558 * @param sendbufsize The size of the buffer area.
1559 * @param recvbuf A pointer to an area in memory which can be used as a buffer for data to be received.
1560 * @param recvbufsize The size of the buffer area.
1561 */
1562void isotp_init_link(IsoTpLink *link, uint32_t sendid,
1563 uint8_t *sendbuf, uint16_t sendbufsize,
1564 uint8_t *recvbuf, uint16_t recvbufsize);
1565
1566/**
1567 * @brief Polling function; call this function periodically to handle timeouts, send consecutive frames, etc.
1568 *
1569 * @param link The @code IsoTpLink @endcode instance used.
1570 */
1571void isotp_poll(IsoTpLink *link);
1572
1573/**
1574 * @brief Handles incoming CAN messages.
1575 * Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly.
1576 *
1577 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1578 * @param data The data received via CAN.
1579 * @param len The length of the data received.
1580 */
1581void isotp_on_can_message(IsoTpLink *link, const uint8_t *data, uint8_t len);
1582
1583/**
1584 * @brief Sends ISO-TP frames via CAN, using the ID set in the initialising function.
1585 *
1586 * Single-frame messages will be sent immediately when calling this function.
1587 * Multi-frame messages will be sent consecutively when calling isotp_poll.
1588 *
1589 * @param link The @code IsoTpLink @endcode instance used for transceiving data.
1590 * @param payload The payload to be sent. (Up to 4095 bytes).
1591 * @param size The size of the payload to be sent.
1592 *
1593 * @return Possible return values:
1594 * - @code ISOTP_RET_OVERFLOW @endcode
1595 * - @code ISOTP_RET_INPROGRESS @endcode
1596 * - @code ISOTP_RET_OK @endcode
1597 * - The return value of the user shim function isotp_user_send_can().
1598 */
1599int isotp_send(IsoTpLink *link, const uint8_t payload[], uint16_t size);
1600
1601/**
1602 * @brief See @link isotp_send @endlink, with the exception that this function is used only for functional addressing.
1603 */
1604int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], uint16_t size);
1605
1606/**
1607 * @brief Receives and parses the received data and copies the parsed data in to the internal buffer.
1608 * @param link The @link IsoTpLink @endlink instance used to transceive data.
1609 * @param payload A pointer to an area in memory where the raw data is copied from.
1610 * @param payload_size The size of the received (raw) CAN data.
1611 * @param out_size A reference to a variable which will contain the size of the actual (parsed) data.
1612 *
1613 * @return Possible return values:
1614 * - @link ISOTP_RET_OK @endlink
1615 * - @link ISOTP_RET_NO_DATA @endlink
1616 */
1617int isotp_receive(IsoTpLink *link, uint8_t *payload, const uint16_t payload_size, uint16_t *out_size);
1618
1619#ifdef __cplusplus
1620}
1621#endif
1622
1623#endif // ISOTPC_H
1624
1625#endif
1626
1627#if defined(UDS_TP_ISOTP_C)
1628
1629
1630typedef struct {
1631 UDSTp_t hdl;
1632 IsoTpLink phys_link;
1633 IsoTpLink func_link;
1634 uint8_t send_buf[UDS_ISOTP_MTU];
1635 uint8_t recv_buf[UDS_ISOTP_MTU];
1636 uint32_t phys_sa, phys_ta;
1637 uint32_t func_sa, func_ta;
1638} UDSISOTpC_t;
1639
1640typedef struct {
1641 uint32_t source_addr;
1642 uint32_t target_addr;
1643 uint32_t source_addr_func;
1644 uint32_t target_addr_func;
1646
1647UDSErr_t UDSISOTpCInit(UDSISOTpC_t *tp, const UDSISOTpCConfig_t *cfg);
1648
1649void UDSISOTpCDeinit(UDSISOTpC_t *tp);
1650
1651#endif
1652
1653
1654
1655#if defined(UDS_TP_ISOTP_C_SOCKETCAN)
1656
1657
1658typedef struct {
1659 UDSTp_t hdl;
1660 IsoTpLink phys_link;
1661 IsoTpLink func_link;
1662 uint8_t send_buf[UDS_ISOTP_MTU];
1663 uint8_t recv_buf[UDS_ISOTP_MTU];
1664 int fd;
1665 uint32_t phys_sa, phys_ta;
1666 uint32_t func_sa, func_ta;
1667 char tag[16];
1669
1670UDSErr_t UDSTpISOTpCInit(UDSTpISOTpC_t *tp, const char *ifname, uint32_t source_addr,
1671 uint32_t target_addr, uint32_t source_addr_func,
1672 uint32_t target_addr_func);
1673void UDSTpISOTpCDeinit(UDSTpISOTpC_t *tp);
1674
1675#endif
1676
1677
1678#if defined(UDS_TP_ISOTP_SOCK)
1679
1680
1681typedef struct {
1682 UDSTp_t hdl;
1683 uint8_t recv_buf[UDS_ISOTP_MTU];
1684 uint8_t send_buf[UDS_ISOTP_MTU];
1685 size_t recv_len;
1686 UDSSDU_t recv_info;
1687 int phys_fd;
1688 int func_fd;
1689 uint32_t phys_sa, phys_ta;
1690 uint32_t func_sa, func_ta;
1691 char tag[16];
1693
1694UDSErr_t UDSTpIsoTpSockInitServer(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
1695 uint32_t target_addr, uint32_t source_addr_func);
1696UDSErr_t UDSTpIsoTpSockInitClient(UDSTpIsoTpSock_t *tp, const char *ifname, uint32_t source_addr,
1697 uint32_t target_addr, uint32_t target_addr_func);
1698void UDSTpIsoTpSockDeinit(UDSTpIsoTpSock_t *tp);
1699
1700#endif
1701
1702
1703/**
1704 * @file isotp_mock.h
1705 * @brief in-memory ISO15765 (ISO-TP) transport layer implementation for testing
1706 * @date 2023-10-21
1707 *
1708 */
1709#if defined(UDS_TP_ISOTP_MOCK)
1710
1711
1712
1713typedef struct ISOTPMock {
1714 UDSTp_t hdl;
1715 uint8_t recv_buf[UDS_TP_MTU];
1716 uint8_t send_buf[UDS_TP_MTU];
1717 size_t recv_len;
1718 UDSSDU_t recv_info;
1719 uint32_t sa_phys; // source address - physical messages are sent from this address
1720 uint32_t ta_phys; // target address - physical messages are sent to this address
1721 uint32_t sa_func; // source address - functional messages are sent from this address
1722 uint32_t ta_func; // target address - functional messages are sent to this address
1723 uint32_t send_tx_delay_ms; // simulated delay
1724 uint32_t send_buf_size; // simulated size of the send buffer
1725 char name[32]; // name for logging
1726} ISOTPMock_t;
1727
1728typedef struct {
1729 uint32_t sa_phys; // source address - physical messages are sent from this address
1730 uint32_t ta_phys; // target address - physical messages are sent to this address
1731 uint32_t sa_func; // source address - functional messages are sent from this address
1732 uint32_t ta_func; // target address - functional messages are sent to this address
1734
1735/**
1736 * @brief Create a mock transport. It is connected by default to a broadcast network of all other
1737 * mock transports in the same process.
1738 * @param name optional name of the transport (can be NULL)
1739 * @return UDSTp_t*
1740 */
1741UDSTp_t *ISOTPMockNew(const char *name, ISOTPMockArgs_t *args);
1742void ISOTPMockFree(UDSTp_t *tp);
1743
1744/**
1745 * @brief write all messages to a file
1746 * @note uses UDSMillis() to get the current time
1747 * @param filename log file name (will be overwritten)
1748 */
1749void ISOTPMockLogToFile(const char *filename);
1750void ISOTPMockLogToStdout(void);
1751
1752/**
1753 * @brief clear all transports and close the log file
1754 */
1755void ISOTPMockReset(void);
1756
1757#endif
1758
1759
1760#ifdef __cplusplus
1761}
1762#endif
1763
1764#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