From e11d6b7343e467a3de5bd09a81e339432fd0fbec Mon Sep 17 00:00:00 2001 From: Nick James Kirkby <20824939+driftregion@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:46:41 -0700 Subject: [PATCH] fix most static analysis defects in src/ --- .CodeChecker/run.sh | 17 ++- .CodeChecker/skipfile.txt | 1 - .gitignore | 6 + BUILD | 4 + Makefile | 2 +- README.md | 12 +- src/client.c | 192 +++++++++++++------------ src/client.h | 35 ++--- src/log.c | 3 + src/server.c | 236 ++++++++++++++++--------------- src/server.h | 10 +- src/tp/isotp_sock.c | 2 +- src/tp/isotp_sock.h | 3 +- src/uds.h | 107 ++++++-------- src/util.c | 290 +++++++++++++++++++++++++++----------- test/test_client.c | 22 +-- test/test_server.c | 6 +- 17 files changed, 548 insertions(+), 400 deletions(-) delete mode 100644 .CodeChecker/skipfile.txt diff --git a/.CodeChecker/run.sh b/.CodeChecker/run.sh index c6115eb..1b83e66 100755 --- a/.CodeChecker/run.sh +++ b/.CodeChecker/run.sh @@ -1,8 +1,15 @@ #!/bin/bash -# --enable sensitive \ -# --analyzers cppcheck \ CodeChecker analyze compile_commands.json \ - --ignore .CodeChecker/skipfile.txt \ - --analyzer-config cppcheck:addons=.cppcheck/misra.json \ - -o reports \ No newline at end of file + --ignore .CodeChecker/skipfile_bazel.txt \ + -o reports + + +# Make the MISRA report +# CodeChecker analyze compile_commands.json \ +# --ignore .CodeChecker/skipfile_bazel.txt \ +# --ignore .CodeChecker/skipfile_thirdparty.txt \ +# --cppcheckargs .CodeChecker/cppcheckargs.txt \ +# --analyzer-config cppcheck:addons=.cppcheck/misra.json \ +# --analyzer-config cppcheck:platform=unix64 \ +# -o misra_reports \ No newline at end of file diff --git a/.CodeChecker/skipfile.txt b/.CodeChecker/skipfile.txt deleted file mode 100644 index 2d0b9df..0000000 --- a/.CodeChecker/skipfile.txt +++ /dev/null @@ -1 +0,0 @@ --*/launcher_maker.cc \ No newline at end of file diff --git a/.gitignore b/.gitignore index f437a0c..a0da106 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,9 @@ compile_commands.json MODULE.bazel.lock iso14229.c iso14229.h +html_report +misra_reports +**/*.ctu-info +**/*.dump +report.txt +json_report.json \ No newline at end of file diff --git a/BUILD b/BUILD index 0a8f1e2..42c59cb 100644 --- a/BUILD +++ b/BUILD @@ -27,6 +27,10 @@ cc_library( name = "iso14229", srcs=glob(["src/**/*.c", "src/**/*.h"]), includes=["src"], + copts = [ + # gcc adds system headers by default. However, the compile_commands.json used for static analysis needs this include path to be explicit. + "-I/usr/include" + ], ) py_binary( diff --git a/Makefile b/Makefile index 6239509..f06c332 100644 --- a/Makefile +++ b/Makefile @@ -12,4 +12,4 @@ compile_commands.json: static_analysis: compile_commands.json $(MISRA_RULES_TXT) .CodeChecker/run.sh -.phony: static_analysis +.phony: static_analysis compile_commands.json diff --git a/README.md b/README.md index fb61d4c..22d0cab 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ see `enum UDSEvent` in [src/uds.h](src/uds.h) ```c typedef struct { - const enum UDSDiagnosticSessionType type; /**< requested session type */ + const uint8_t type; /**< requested session type */ uint16_t p2_ms; /**< optional return value: p2 timing override */ uint32_t p2_star_ms; /**< optional return value: p2* timing override */ } UDSDiagSessCtrlArgs_t; @@ -114,7 +114,7 @@ typedef struct { ```c typedef struct { - const enum UDSECUResetType type; /**< reset type requested by client */ + const uint8_t type; /**< reset type requested by client */ uint8_t powerDownTime; /**< Optional response: notify client of time until shutdown (0-254) 255 indicates that a time is not available. */ } UDSECUResetArgs_t; @@ -189,8 +189,8 @@ typedef struct { ```c typedef struct { - enum UDSCommunicationControlType ctrlType; - enum UDSCommunicationType commType; + uint8_t ctrlType; + uint8_t commType; } UDSCommCtrlArgs_t; ``` #### Supported Responses @@ -393,6 +393,10 @@ bazel build //:release # Changelog +## 0.9.0 +- breaking API changes: + - converted subfunction enums to #defines with standard-consistent naming + ## 0.8.0 - breaking API changes: - event enum consolidated `UDS_SRV_EVT_...` -> `UDS_EVT` diff --git a/src/client.c b/src/client.c index f89466f..45e30d6 100644 --- a/src/client.c +++ b/src/client.c @@ -4,50 +4,49 @@ #include "util.h" #include "log.h" -enum UDSClientRequestState { - kRequestStateIdle = 0, - kRequestStateSending, - kRequestStateAwaitSendComplete, - kRequestStateAwaitResponse, - kRequestStateProcessResponse, -}; +// Client request states +#define STATE_IDLE 0 +#define STATE_SENDING 1 +#define STATE_AWAIT_SEND_COMPLETE 2 +#define STATE_AWAIT_RESPONSE 3 +#define STATE_PROCESS_RESPONSE 4 UDSErr_t UDSClientInit(UDSClient_t *client) { if (NULL == client) { return UDS_ERR_INVALID_ARG; } memset(client, 0, sizeof(*client)); - client->state = kRequestStateIdle; + client->state = STATE_IDLE; client->p2_ms = UDS_CLIENT_DEFAULT_P2_MS; client->p2_star_ms = UDS_CLIENT_DEFAULT_P2_STAR_MS; if (client->p2_star_ms < client->p2_ms) { - fprintf(stderr, "p2_star_ms must be >= p2_ms"); + UDS_LOGE(__FILE__, "p2_star_ms must be >= p2_ms"); client->p2_star_ms = client->p2_ms; } return UDS_OK; } -static const char *ClientStateName(enum UDSClientRequestState state) { +static const char *ClientStateName(uint8_t state) { switch (state) { - case kRequestStateIdle: + case STATE_IDLE: return "Idle"; - case kRequestStateSending: + case STATE_SENDING: return "Sending"; - case kRequestStateAwaitSendComplete: + case STATE_AWAIT_SEND_COMPLETE: return "AwaitSendComplete"; - case kRequestStateAwaitResponse: + case STATE_AWAIT_RESPONSE: return "AwaitResponse"; - case kRequestStateProcessResponse: + case STATE_PROCESS_RESPONSE: return "ProcessResponse"; default: return "Unknown"; } } -static void changeState(UDSClient_t *client, enum UDSClientRequestState state) { +static void changeState(UDSClient_t *client, uint8_t state) { if (state != client->state) { UDS_LOGI(__FILE__, "client state: %s (%d) -> %s (%d)", ClientStateName(client->state), client->state, ClientStateName(state), state); @@ -55,10 +54,19 @@ static void changeState(UDSClient_t *client, enum UDSClientRequestState state) { client->state = state; switch (state) { - case kRequestStateIdle: + case STATE_IDLE: client->fn(client, UDS_EVT_Idle, NULL); break; + case STATE_SENDING: + break; + case STATE_AWAIT_SEND_COMPLETE: + break; + case STATE_AWAIT_RESPONSE: + break; + case STATE_PROCESS_RESPONSE: + break; default: + UDS_ASSERT(0); break; } } @@ -90,8 +98,7 @@ static UDSErr_t ValidateServerResponse(const UDSClient_t *client) { if (UDS_RESPONSE_SID_OF(client->send_buf[0]) != client->recv_buf[0]) { return UDS_ERR_SID_MISMATCH; } - switch (client->send_buf[0]) { - case kSID_ECU_RESET: + if (client->send_buf[0] == kSID_ECU_RESET) { if (client->recv_size < 2) { return UDS_ERR_RESP_TOO_SHORT; } else if (client->send_buf[1] != client->recv_buf[1]) { @@ -99,7 +106,6 @@ static UDSErr_t ValidateServerResponse(const UDSClient_t *client) { } else { ; } - break; } } @@ -118,7 +124,7 @@ static UDSErr_t HandleServerResponse(UDSClient_t *client) { memset(client->recv_buf, 0, client->recv_buf_size); client->recv_size = 0; UDSTpAckRecv(client->tp); - changeState(client, kRequestStateAwaitResponse); + changeState(client, STATE_AWAIT_RESPONSE); return UDS_NRC_RequestCorrectlyReceived_ResponsePending; } else { ; @@ -131,17 +137,18 @@ static UDSErr_t HandleServerResponse(UDSClient_t *client) { UDS_LOGI(__FILE__, "Error: SID %x response too short", kSID_DIAGNOSTIC_SESSION_CONTROL); UDSTpAckRecv(client->tp); - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); return UDS_ERR_RESP_TOO_SHORT; } if (client->_options_copy & UDS_IGNORE_SRV_TIMINGS) { UDSTpAckRecv(client->tp); - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); return UDS_OK; } - uint16_t p2 = (client->recv_buf[2] << 8) + client->recv_buf[3]; + uint16_t p2 = + (uint16_t)(((uint16_t)client->recv_buf[2] << 8) | (uint16_t)client->recv_buf[3]); uint32_t p2_star = ((client->recv_buf[4] << 8) + client->recv_buf[5]) * 10; UDS_LOGI(__FILE__, "received new timings: p2: %" PRIu16 ", p2*: %" PRIu32, p2, p2_star); client->p2_ms = p2; @@ -170,11 +177,11 @@ static UDSErr_t PollLowLevel(UDSClient_t *client) { UDSTpStatus_t tp_status = UDSTpPoll(client->tp); switch (client->state) { - case kRequestStateIdle: { + case STATE_IDLE: { client->options = client->defaultOptions; break; } - case kRequestStateSending: { + case STATE_SENDING: { UDSTpAddr_t ta_type = client->_options_copy & UDS_FUNCTIONAL ? UDS_A_TA_TYPE_FUNCTIONAL : UDS_A_TA_TYPE_PHYSICAL; UDSSDU_t info = { @@ -189,32 +196,32 @@ static UDSErr_t PollLowLevel(UDSClient_t *client) { UDS_LOGI(__FILE__, "send in progress..."); ; // 等待发送成功 } else if (client->send_size == ret) { - changeState(client, kRequestStateAwaitSendComplete); + changeState(client, STATE_AWAIT_SEND_COMPLETE); } else { err = UDS_ERR_BUFSIZ; } break; } - case kRequestStateAwaitSendComplete: { + case STATE_AWAIT_SEND_COMPLETE: { if (client->_options_copy & UDS_FUNCTIONAL) { // "The Functional addressing is applied only to single frame transmission" // Specification of Diagnostic Communication (Diagnostic on CAN - Network Layer) - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); } if (tp_status & UDS_TP_SEND_IN_PROGRESS) { ; // await send complete } else { client->fn(client, UDS_EVT_SendComplete, NULL); if (client->_options_copy & UDS_SUPPRESS_POS_RESP) { - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); } else { - changeState(client, kRequestStateAwaitResponse); + changeState(client, STATE_AWAIT_RESPONSE); client->p2_timer = UDSMillis() + client->p2_ms; } } break; } - case kRequestStateAwaitResponse: { + case STATE_AWAIT_RESPONSE: { UDSSDU_t info = {0}; ssize_t len = UDSTpPeek(client->tp, &client->recv_buf, &info); @@ -224,16 +231,20 @@ static UDSErr_t PollLowLevel(UDSClient_t *client) { } if (len < 0) { err = UDS_ERR_TPORT; - changeState(client, kRequestStateIdle); - } else if (0 == len) { + changeState(client, STATE_IDLE); + break; + } + if (0 == len) { if (UDSTimeAfter(UDSMillis(), client->p2_timer)) { UDS_LOGI(__FILE__, "p2 timeout"); err = UDS_ERR_TIMEOUT; - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); + break; } } else { UDS_LOGI(__FILE__, "received %zd bytes. Processing...", len); - client->recv_size = len; + UDS_ASSERT(len <= (ssize_t)UINT16_MAX); + client->recv_size = (uint16_t)len; err = ValidateServerResponse(client); if (UDS_OK == err) { @@ -242,7 +253,7 @@ static UDSErr_t PollLowLevel(UDSClient_t *client) { if (UDS_OK == err) { client->fn(client, UDS_EVT_ResponseReceived, NULL); - changeState(client, kRequestStateIdle); + changeState(client, STATE_IDLE); } UDSTpAckRecv(client->tp); @@ -252,6 +263,7 @@ static UDSErr_t PollLowLevel(UDSClient_t *client) { default: UDS_ASSERT(0); + break; } return err; } @@ -264,7 +276,7 @@ static UDSErr_t SendRequest(UDSClient_t *client) { client->send_buf[1] |= 0x80U; } - changeState(client, kRequestStateSending); + changeState(client, STATE_SENDING); UDSErr_t err = PollLowLevel(client); // poll once to begin sending immediately return err; } @@ -273,7 +285,7 @@ static UDSErr_t PreRequestCheck(UDSClient_t *client) { if (NULL == client) { return UDS_ERR_INVALID_ARG; } - if (kRequestStateIdle != client->state) { + if (STATE_IDLE != client->state) { return UDS_ERR_BUSY; } @@ -287,7 +299,8 @@ static UDSErr_t PreRequestCheck(UDSClient_t *client) { if (ret < 0) { return UDS_ERR_TPORT; } - client->send_buf_size = ret; + UDS_ASSERT(ret <= (ssize_t)UINT16_MAX); + client->send_buf_size = (uint16_t)ret; return UDS_OK; } @@ -304,7 +317,7 @@ UDSErr_t UDSSendBytes(UDSClient_t *client, const uint8_t *data, uint16_t size) { return SendRequest(client); } -UDSErr_t UDSSendECUReset(UDSClient_t *client, UDSECUReset_t type) { +UDSErr_t UDSSendECUReset(UDSClient_t *client, uint8_t type) { UDSErr_t err = PreRequestCheck(client); if (err) { return err; @@ -315,7 +328,7 @@ UDSErr_t UDSSendECUReset(UDSClient_t *client, UDSECUReset_t type) { return SendRequest(client); } -UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, enum UDSDiagnosticSessionType mode) { +UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, uint8_t mode) { UDSErr_t err = PreRequestCheck(client); if (err) { return err; @@ -326,8 +339,7 @@ UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, enum UDSDiagnosticSessionType return SendRequest(client); } -UDSErr_t UDSSendCommCtrl(UDSClient_t *client, enum UDSCommunicationControlType ctrl, - enum UDSCommunicationType comm) { +UDSErr_t UDSSendCommCtrl(UDSClient_t *client, uint8_t ctrl, uint8_t comm) { UDSErr_t err = PreRequestCheck(client); if (err) { return err; @@ -352,6 +364,7 @@ UDSErr_t UDSSendTesterPresent(UDSClient_t *client) { UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList, const uint16_t numDataIdentifiers) { + const uint16_t DID_LEN_BYTES = 2; UDSErr_t err = PreRequestCheck(client); if (err) { return err; @@ -361,14 +374,14 @@ UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList, } client->send_buf[0] = kSID_READ_DATA_BY_IDENTIFIER; for (int i = 0; i < numDataIdentifiers; i++) { - uint16_t offset = 1 + sizeof(uint16_t) * i; + uint16_t offset = (uint16_t)(1 + DID_LEN_BYTES * i); if (offset + 2 > client->send_buf_size) { return UDS_ERR_INVALID_ARG; } (client->send_buf + offset)[0] = (didList[i] & 0xFF00) >> 8; (client->send_buf + offset)[1] = (didList[i] & 0xFF); } - client->send_size = 1 + (numDataIdentifiers * sizeof(uint16_t)); + client->send_size = 1 + (numDataIdentifiers * DID_LEN_BYTES); return SendRequest(client); } @@ -403,8 +416,8 @@ UDSErr_t UDSSendWDBI(UDSClient_t *client, uint16_t dataIdentifier, const uint8_t * @return UDSErr_t * @addtogroup routineControl_0x31 */ -UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, enum RoutineControlType type, - uint16_t routineIdentifier, const uint8_t *data, uint16_t size) { +UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, uint8_t type, uint16_t routineIdentifier, + const uint8_t *data, uint16_t size) { UDSErr_t err = PreRequestCheck(client); if (err) { return err; @@ -412,7 +425,7 @@ UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, enum RoutineControlType type, client->send_buf[0] = kSID_ROUTINE_CONTROL; client->send_buf[1] = type; client->send_buf[2] = routineIdentifier >> 8; - client->send_buf[3] = routineIdentifier; + client->send_buf[3] = routineIdentifier & 0xFF; if (size) { if (NULL == data) { return UDS_ERR_INVALID_ARG; @@ -458,12 +471,12 @@ UDSErr_t UDSSendRequestDownload(UDSClient_t *client, uint8_t dataFormatIdentifie uint8_t *ptr = &client->send_buf[UDS_0X34_REQ_BASE_LEN]; for (int i = numMemoryAddressBytes - 1; i >= 0; i--) { - *ptr = (memoryAddress & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((memoryAddress >> (8 * i)) & 0xFF); ptr++; } for (int i = numMemorySizeBytes - 1; i >= 0; i--) { - *ptr = (memorySize & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((memorySize >> (8 * i)) & 0xFF); ptr++; } @@ -499,12 +512,12 @@ UDSErr_t UDSSendRequestUpload(UDSClient_t *client, uint8_t dataFormatIdentifier, uint8_t *ptr = &client->send_buf[UDS_0X35_REQ_BASE_LEN]; for (int i = numMemoryAddressBytes - 1; i >= 0; i--) { - *ptr = (memoryAddress & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((memoryAddress >> (8 * i)) & 0xFF); ptr++; } for (int i = numMemorySizeBytes - 1; i >= 0; i--) { - *ptr = (memorySize & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((memorySize >> (8 * i)) & 0xFF); ptr++; } @@ -559,7 +572,9 @@ UDSErr_t UDSSendTransferDataStream(UDSClient_t *client, uint8_t blockSequenceCou client->send_buf[0] = kSID_TRANSFER_DATA; client->send_buf[1] = blockSequenceCounter; - uint16_t size = fread(&client->send_buf[2], 1, blockLength - 2, fd); + unsigned long _size = fread(&client->send_buf[2], 1, blockLength - 2, fd); + UDS_ASSERT(_size < UINT16_MAX); + uint16_t size = (uint16_t)_size; UDS_LOGI(__FILE__, "size: %d, blocklength: %d", size, blockLength); client->send_size = UDS_0X36_REQ_BASE_LEN + size; return SendRequest(client); @@ -582,24 +597,23 @@ UDSErr_t UDSSendRequestTransferExit(UDSClient_t *client) { return SendRequest(client); } -UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, enum FileOperationMode mode, - const char *filePath, uint8_t dataFormatIdentifier, - uint8_t fileSizeParameterLength, size_t fileSizeUncompressed, - size_t fileSizeCompressed) { +UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, uint8_t mode, const char *filePath, + uint8_t dataFormatIdentifier, uint8_t fileSizeParameterLength, + size_t fileSizeUncompressed, size_t fileSizeCompressed) { UDSErr_t err = PreRequestCheck(client); if (err) { return err; } - uint16_t filePathLen = strlen(filePath); + uint16_t filePathLen = (uint16_t)strlen(filePath); if (filePathLen < 1) return UDS_FAIL; uint8_t fileSizeBytes = 0; - if ((mode == kAddFile) || (mode == kReplaceFile)) { + if ((mode == UDS_MOOP_ADDFILE) || (mode == UDS_MOOP_REPLFILE)) { fileSizeBytes = fileSizeParameterLength; } size_t bufSize = 5 + filePathLen + fileSizeBytes + fileSizeBytes; - if ((mode == kAddFile) || (mode == kReplaceFile) || (mode == kReadFile)) { + if ((mode == UDS_MOOP_ADDFILE) || (mode == UDS_MOOP_REPLFILE) || (mode == UDS_MOOP_RDFILE)) { bufSize += 1; } if (client->send_buf_size < bufSize) @@ -610,24 +624,24 @@ UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, enum FileOperationMode client->send_buf[2] = (filePathLen >> 8) & 0xFF; client->send_buf[3] = filePathLen & 0xFF; memcpy(&client->send_buf[4], filePath, filePathLen); - if ((mode == kAddFile) || (mode == kReplaceFile) || (mode == kReadFile)) { + if ((mode == UDS_MOOP_ADDFILE) || (mode == UDS_MOOP_REPLFILE) || (mode == UDS_MOOP_RDFILE)) { client->send_buf[4 + filePathLen] = dataFormatIdentifier; } - if ((mode == kAddFile) || (mode == kReplaceFile)) { + if ((mode == UDS_MOOP_ADDFILE) || (mode == UDS_MOOP_REPLFILE)) { client->send_buf[5 + filePathLen] = fileSizeParameterLength; uint8_t *ptr = &client->send_buf[6 + filePathLen]; for (int i = fileSizeParameterLength - 1; i >= 0; i--) { - *ptr = (fileSizeUncompressed & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((fileSizeUncompressed >> (8 * i)) & 0xFF); ptr++; } for (int i = fileSizeParameterLength - 1; i >= 0; i--) { - *ptr = (fileSizeCompressed & (0xFF << (8 * i))) >> (8 * i); + *ptr = (uint8_t)((fileSizeCompressed >> (8 * i)) & 0xFF); ptr++; } } - client->send_size = bufSize; + client->send_size = (uint16_t)bufSize; return SendRequest(client); } @@ -694,20 +708,21 @@ UDSErr_t UDSSendSecurityAccess(UDSClient_t *client, uint8_t level, uint8_t *data } client->send_buf[0] = kSID_SECURITY_ACCESS; client->send_buf[1] = level; - if (size) { - if (NULL == data) { - return UDS_ERR_INVALID_ARG; - } - if (size > client->send_buf_size - UDS_0X27_REQ_BASE_LEN) { - return UDS_ERR_BUFSIZ; - } - } else { - if (NULL != data) { - UDS_LOGI(__FILE__, "warning: size == 0 and data is non-null"); - } + + if (NULL == data) { + return UDS_ERR_INVALID_ARG; + } + if (size > client->send_buf_size - UDS_0X27_REQ_BASE_LEN) { + return UDS_ERR_BUFSIZ; + } + if (size == 0 && NULL != data) { + UDS_LOGE(__FILE__, "size == 0 and data is non-null"); + return UDS_ERR_INVALID_ARG; + } + if (size > 0) { + memmove(&client->send_buf[UDS_0X27_REQ_BASE_LEN], data, size); } - memmove(&client->send_buf[UDS_0X27_REQ_BASE_LEN], data, size); client->send_size = UDS_0X27_REQ_BASE_LEN + size; return SendRequest(client); } @@ -757,7 +772,8 @@ UDSErr_t UDSUnpackRoutineControlResponse(const UDSClient_t *client, return UDS_ERR_RESP_TOO_SHORT; } resp->routineControlType = client->recv_buf[1]; - resp->routineIdentifier = (client->recv_buf[2] << 8) + client->recv_buf[3]; + resp->routineIdentifier = + (uint16_t)((uint16_t)(client->recv_buf[2] << 8) | (uint16_t)client->recv_buf[3]); resp->routineStatusRecordLength = client->recv_size - UDS_0X31_RESP_MIN_LEN; resp->routineStatusRecord = resp->routineStatusRecordLength == 0 ? NULL : &client->recv_buf[UDS_0X31_RESP_MIN_LEN]; @@ -790,7 +806,7 @@ UDSErr_t UDSUnpackRequestDownloadResponse(const UDSClient_t *client, return UDS_FAIL; } resp->maxNumberOfBlockLength = 0; - for (int byteIdx = 0; byteIdx < maxNumberOfBlockLengthSize; byteIdx++) { + for (uint8_t byteIdx = 0; byteIdx < maxNumberOfBlockLengthSize; byteIdx++) { uint8_t byte = client->recv_buf[UDS_0X34_RESP_BASE_LEN + byteIdx]; uint8_t shiftBytes = maxNumberOfBlockLengthSize - 1 - byteIdx; resp->maxNumberOfBlockLength |= byte << (8 * shiftBytes); @@ -804,15 +820,14 @@ UDSErr_t UDSClientPoll(UDSClient_t *client) { } UDSErr_t err = PollLowLevel(client); - switch (err) { - case UDS_OK: - case UDS_NRC_RequestCorrectlyReceived_ResponsePending: - break; - default: + + if (err == UDS_OK || err == UDS_NRC_RequestCorrectlyReceived_ResponsePending) { + ; + } else { client->fn(client, UDS_EVT_Err, &err); - changeState(client, kRequestStateIdle); - break; + changeState(client, STATE_IDLE); } + client->fn(client, UDS_EVT_Poll, NULL); return err; } @@ -827,7 +842,8 @@ UDSErr_t UDSUnpackRDBIResponse(UDSClient_t *client, UDSRDBIVar_t *vars, uint16_t if (offset + sizeof(uint16_t) > client->recv_size) { return UDS_ERR_RESP_TOO_SHORT; } - uint16_t did = (client->recv_buf[offset] << 8) + client->recv_buf[offset + 1]; + uint16_t did = (uint16_t)((uint16_t)(client->recv_buf[offset] << 8) | + (uint16_t)client->recv_buf[offset + 1]); if (did != vars[i].did) { return UDS_ERR_DID_MISMATCH; } diff --git a/src/client.h b/src/client.h index 12367f4..f3dca24 100644 --- a/src/client.h +++ b/src/client.h @@ -4,12 +4,9 @@ #include "tp.h" #include "uds.h" -enum UDSClientOptions { - UDS_SUPPRESS_POS_RESP = 0x1, // 服务器不应该发送肯定响应 - UDS_FUNCTIONAL = 0x2, // 发功能请求 - UDS_NEG_RESP_IS_ERR = 0x4, // 否定响应是属于故障 - UDS_IGNORE_SRV_TIMINGS = 0x8, // 忽略服务器给的p2和p2_star -}; +#define UDS_SUPPRESS_POS_RESP 0x1 // set the suppress positive response bit +#define UDS_FUNCTIONAL 0x2 // send the request as a functional request +#define UDS_IGNORE_SRV_TIMINGS 0x8 // ignore the server-provided p2 and p2_star typedef struct UDSClient { uint16_t p2_ms; // p2 超时时间 @@ -23,12 +20,12 @@ typedef struct UDSClient { uint16_t send_buf_size; uint16_t recv_size; uint16_t send_size; - int8_t state; // request state + uint8_t state; // client request state - uint8_t options; // enum udsclientoptions - uint8_t defaultOptions; // enum udsclientoptions + uint8_t options; + uint8_t defaultOptions; // a copy of the options at the time a request is made - uint8_t _options_copy; // enum udsclientoptions + uint8_t _options_copy; // callback function int (*fn)(struct UDSClient *client, UDSEvent_t evt, void *ev_data); @@ -62,18 +59,17 @@ typedef struct { UDSErr_t UDSClientInit(UDSClient_t *client); UDSErr_t UDSClientPoll(UDSClient_t *client); UDSErr_t UDSSendBytes(UDSClient_t *client, const uint8_t *data, uint16_t size); -UDSErr_t UDSSendECUReset(UDSClient_t *client, UDSECUReset_t type); -UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, enum UDSDiagnosticSessionType mode); +UDSErr_t UDSSendECUReset(UDSClient_t *client, uint8_t type); +UDSErr_t UDSSendDiagSessCtrl(UDSClient_t *client, uint8_t mode); UDSErr_t UDSSendSecurityAccess(UDSClient_t *client, uint8_t level, uint8_t *data, uint16_t size); -UDSErr_t UDSSendCommCtrl(UDSClient_t *client, enum UDSCommunicationControlType ctrl, - enum UDSCommunicationType comm); +UDSErr_t UDSSendCommCtrl(UDSClient_t *client, uint8_t ctrl, uint8_t comm); UDSErr_t UDSSendRDBI(UDSClient_t *client, const uint16_t *didList, const uint16_t numDataIdentifiers); UDSErr_t UDSSendWDBI(UDSClient_t *client, uint16_t dataIdentifier, const uint8_t *data, uint16_t size); UDSErr_t UDSSendTesterPresent(UDSClient_t *client); -UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, enum RoutineControlType type, - uint16_t routineIdentifier, const uint8_t *data, uint16_t size); +UDSErr_t UDSSendRoutineCtrl(UDSClient_t *client, uint8_t type, uint16_t routineIdentifier, + const uint8_t *data, uint16_t size); UDSErr_t UDSSendRequestDownload(UDSClient_t *client, uint8_t dataFormatIdentifier, uint8_t addressAndLengthFormatIdentifier, size_t memoryAddress, @@ -88,10 +84,9 @@ UDSErr_t UDSSendTransferDataStream(UDSClient_t *client, uint8_t blockSequenceCou const uint16_t blockLength, FILE *fd); UDSErr_t UDSSendRequestTransferExit(UDSClient_t *client); -UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, enum FileOperationMode mode, - const char *filePath, uint8_t dataFormatIdentifier, - uint8_t fileSizeParameterLength, size_t fileSizeUncompressed, - size_t fileSizeCompressed); +UDSErr_t UDSSendRequestFileTransfer(UDSClient_t *client, uint8_t mode, const char *filePath, + uint8_t dataFormatIdentifier, uint8_t fileSizeParameterLength, + size_t fileSizeUncompressed, size_t fileSizeCompressed); UDSErr_t UDSCtrlDTCSetting(UDSClient_t *client, uint8_t dtcSettingType, uint8_t *dtcSettingControlOptionRecord, uint16_t len); diff --git a/src/log.c b/src/log.c index 6e14ae3..59b8ff1 100644 --- a/src/log.c +++ b/src/log.c @@ -5,6 +5,8 @@ void UDS_LogWrite(UDS_LogLevel_t level, const char *tag, const char *format, ...) { va_list list; + (void)level; + (void)tag; va_start(list, format); vprintf(format, list); va_end(list); @@ -12,6 +14,7 @@ void UDS_LogWrite(UDS_LogLevel_t level, const char *tag, const char *format, ... void UDS_LogSDUInternal(UDS_LogLevel_t level, const char *tag, const uint8_t *buffer, size_t buff_len, UDSSDU_t *info) { + (void)info; for (unsigned i = 0; i < buff_len; i++) { UDS_LogWrite(level, tag, "%02x ", buffer[i]); } diff --git a/src/server.c b/src/server.c index 91d7f05..aa1678c 100644 --- a/src/server.c +++ b/src/server.c @@ -3,18 +3,21 @@ #include "uds.h" #include "util.h" #include "log.h" +#include + +static inline UDSErr_t NegativeResponse(UDSReq_t *r, UDSErr_t nrc) { + UDS_ASSERT(nrc >= 0 && nrc <= 0xFF); -static inline uint8_t NegativeResponse(UDSReq_t *r, uint8_t response_code) { r->send_buf[0] = 0x7F; r->send_buf[1] = r->recv_buf[0]; - r->send_buf[2] = response_code; + r->send_buf[2] = (uint8_t)nrc; r->send_len = UDS_NEG_RESP_LEN; - return response_code; + return nrc; } static inline void NoResponse(UDSReq_t *r) { r->send_len = 0; } -static uint8_t EmitEvent(UDSServer_t *srv, UDSEvent_t evt, void *data) { +static UDSErr_t EmitEvent(UDSServer_t *srv, UDSEvent_t evt, void *data) { if (srv->fn) { return srv->fn(srv, evt, data); } else { @@ -23,7 +26,7 @@ static uint8_t EmitEvent(UDSServer_t *srv, UDSEvent_t evt, void *data) { } } -static uint8_t _0x10_DiagnosticSessionControl(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x10_DiagnosticSessionControl(UDSServer_t *srv, UDSReq_t *r) { if (r->recv_len < UDS_0X10_REQ_LEN) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } @@ -36,7 +39,7 @@ static uint8_t _0x10_DiagnosticSessionControl(UDSServer_t *srv, UDSReq_t *r) { .p2_star_ms = UDS_CLIENT_DEFAULT_P2_STAR_MS, }; - uint8_t err = EmitEvent(srv, UDS_EVT_DiagSessCtrl, &args); + UDSErr_t err = EmitEvent(srv, UDS_EVT_DiagSessCtrl, &args); if (UDS_PositiveResponse != err) { return NegativeResponse(r, err); @@ -45,10 +48,10 @@ static uint8_t _0x10_DiagnosticSessionControl(UDSServer_t *srv, UDSReq_t *r) { srv->sessionType = sessType; switch (sessType) { - case kDefaultSession: + case UDS_LEV_DS_DS: // default session break; - case kProgrammingSession: - case kExtendedDiagnostic: + case UDS_LEV_DS_PRGS: // programming session + case UDS_LEV_DS_EXTDS: // extended diagnostic session default: srv->s3_session_timeout_timer = UDSMillis() + srv->s3_ms; break; @@ -60,17 +63,17 @@ static uint8_t _0x10_DiagnosticSessionControl(UDSServer_t *srv, UDSReq_t *r) { // UDS-1-2013: Table 29 // resolution: 1ms r->send_buf[2] = args.p2_ms >> 8; - r->send_buf[3] = args.p2_ms; + r->send_buf[3] = args.p2_ms & 0xFF; // resolution: 10ms - r->send_buf[4] = (args.p2_star_ms / 10) >> 8; - r->send_buf[5] = args.p2_star_ms / 10; + r->send_buf[4] = (uint8_t)((args.p2_star_ms / 10) >> 8); + r->send_buf[5] = (uint8_t)(args.p2_star_ms / 10); r->send_len = UDS_0X10_RESP_LEN; return UDS_PositiveResponse; } -static uint8_t _0x11_ECUReset(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x11_ECUReset(UDSServer_t *srv, UDSReq_t *r) { uint8_t resetType = r->recv_buf[1] & 0x3F; if (r->recv_len < UDS_0X11_REQ_MIN_LEN) { @@ -82,7 +85,7 @@ static uint8_t _0x11_ECUReset(UDSServer_t *srv, UDSReq_t *r) { .powerDownTimeMillis = UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS, }; - uint8_t err = EmitEvent(srv, UDS_EVT_EcuReset, &args); + UDSErr_t err = EmitEvent(srv, UDS_EVT_EcuReset, &args); if (UDS_PositiveResponse == err) { srv->notReadyToReceive = true; @@ -95,12 +98,12 @@ static uint8_t _0x11_ECUReset(UDSServer_t *srv, UDSReq_t *r) { r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_ECU_RESET); r->send_buf[1] = resetType; - if (kEnableRapidPowerShutDown == resetType) { + if (UDS_LEV_RT_ERPSD == resetType) { uint32_t powerDownTime = args.powerDownTimeMillis / 1000; if (powerDownTime > 255) { powerDownTime = 255; } - r->send_buf[2] = powerDownTime; + r->send_buf[2] = powerDownTime & 0xFF; r->send_len = UDS_0X11_RESP_BASE_LEN + 1; } else { r->send_len = UDS_0X11_RESP_BASE_LEN; @@ -121,10 +124,10 @@ static uint8_t safe_copy(UDSServer_t *srv, const void *src, uint16_t count) { return UDS_NRC_ResponseTooLong; } -static uint8_t _0x22_ReadDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x22_ReadDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { uint8_t numDIDs; uint16_t dataId = 0; - uint8_t ret = UDS_PositiveResponse; + UDSErr_t ret = UDS_PositiveResponse; r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_READ_DATA_BY_IDENTIFIER); r->send_len = 1; @@ -132,22 +135,22 @@ static uint8_t _0x22_ReadDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } - numDIDs = r->recv_len / sizeof(uint16_t); + numDIDs = (uint8_t)(r->recv_len / sizeof(uint16_t)); if (0 == numDIDs) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } - for (int did = 0; did < numDIDs; did++) { - uint16_t idx = 1 + did * 2; - dataId = (r->recv_buf[idx] << 8) + r->recv_buf[idx + 1]; + for (uint16_t did = 0; did < numDIDs; did++) { + uint16_t idx = (uint16_t)(1 + did * 2); + dataId = (uint16_t)((uint16_t)(r->recv_buf[idx] << 8) | (uint16_t)r->recv_buf[idx + 1]); if (r->send_len + 3 > r->send_buf_size) { return NegativeResponse(r, UDS_NRC_ResponseTooLong); } uint8_t *copylocation = r->send_buf + r->send_len; copylocation[0] = dataId >> 8; - copylocation[1] = dataId; + copylocation[1] = dataId & 0xFF; r->send_len += 2; UDSRDBIArgs_t args = { @@ -179,8 +182,8 @@ static uint8_t _0x22_ReadDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { * @param memorySize the decoded memory size * @return uint8_t */ -static uint8_t decodeAddressAndLength(UDSReq_t *r, uint8_t *const buf, void **memoryAddress, - size_t *memorySize) { +static UDSErr_t decodeAddressAndLength(UDSReq_t *r, uint8_t *const buf, void **memoryAddress, + size_t *memorySize) { UDS_ASSERT(r); UDS_ASSERT(memoryAddress); UDS_ASSERT(memorySize); @@ -211,21 +214,21 @@ static uint8_t decodeAddressAndLength(UDSReq_t *r, uint8_t *const buf, void **me for (int byteIdx = 0; byteIdx < memoryAddressLength; byteIdx++) { long long unsigned int byte = buf[1 + byteIdx]; - uint8_t shiftBytes = memoryAddressLength - 1 - byteIdx; + uint8_t shiftBytes = (uint8_t)(memoryAddressLength - 1 - byteIdx); tmp |= byte << (8 * shiftBytes); } *memoryAddress = (void *)tmp; for (int byteIdx = 0; byteIdx < memorySizeLength; byteIdx++) { uint8_t byte = buf[1 + memoryAddressLength + byteIdx]; - uint8_t shiftBytes = memorySizeLength - 1 - byteIdx; + uint8_t shiftBytes = (uint8_t)(memorySizeLength - 1 - byteIdx); *memorySize |= (size_t)byte << (8 * shiftBytes); } return UDS_PositiveResponse; } -static uint8_t _0x23_ReadMemoryByAddress(UDSServer_t *srv, UDSReq_t *r) { - uint8_t ret = UDS_PositiveResponse; +static UDSErr_t Handle_0x23_ReadMemoryByAddress(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t ret = UDS_PositiveResponse; void *address = 0; size_t length = 0; @@ -256,9 +259,9 @@ static uint8_t _0x23_ReadMemoryByAddress(UDSServer_t *srv, UDSReq_t *r) { return UDS_PositiveResponse; } -static uint8_t _0x27_SecurityAccess(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x27_SecurityAccess(UDSServer_t *srv, UDSReq_t *r) { uint8_t subFunction = r->recv_buf[1]; - uint8_t response = UDS_PositiveResponse; + UDSErr_t response = UDS_PositiveResponse; if (UDSSecurityAccessLevelIsReserved(subFunction)) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); @@ -282,7 +285,7 @@ static uint8_t _0x27_SecurityAccess(UDSServer_t *srv, UDSReq_t *r) { UDSSecAccessValidateKeyArgs_t args = { .level = requestedLevel, .key = &r->recv_buf[UDS_0X27_REQ_BASE_LEN], - .len = r->recv_len - UDS_0X27_REQ_BASE_LEN, + .len = (uint16_t)(r->recv_len - UDS_0X27_REQ_BASE_LEN), }; response = EmitEvent(srv, UDS_EVT_SecAccessValidateKey, &args); @@ -320,7 +323,7 @@ static uint8_t _0x27_SecurityAccess(UDSServer_t *srv, UDSReq_t *r) { UDSSecAccessRequestSeedArgs_t args = { .level = subFunction, .dataRecord = &r->recv_buf[UDS_0X27_REQ_BASE_LEN], - .len = r->recv_len - UDS_0X27_REQ_BASE_LEN, + .len = (uint16_t)(r->recv_len - UDS_0X27_REQ_BASE_LEN), .copySeed = safe_copy, }; @@ -339,7 +342,7 @@ static uint8_t _0x27_SecurityAccess(UDSServer_t *srv, UDSReq_t *r) { return NegativeResponse(r, UDS_NRC_GeneralProgrammingFailure); } -static uint8_t _0x28_CommunicationControl(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x28_CommunicationControl(UDSServer_t *srv, UDSReq_t *r) { uint8_t controlType = r->recv_buf[1] & 0x7F; uint8_t communicationType = r->recv_buf[2]; @@ -352,7 +355,7 @@ static uint8_t _0x28_CommunicationControl(UDSServer_t *srv, UDSReq_t *r) { .commType = communicationType, }; - uint8_t err = EmitEvent(srv, UDS_EVT_CommCtrl, &args); + UDSErr_t err = EmitEvent(srv, UDS_EVT_CommCtrl, &args); if (UDS_PositiveResponse != err) { return NegativeResponse(r, err); } @@ -363,18 +366,18 @@ static uint8_t _0x28_CommunicationControl(UDSServer_t *srv, UDSReq_t *r) { return UDS_PositiveResponse; } -static uint8_t _0x2E_WriteDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x2E_WriteDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { uint16_t dataLen = 0; uint16_t dataId = 0; - uint8_t err = UDS_PositiveResponse; + UDSErr_t err = UDS_PositiveResponse; /* UDS-1 2013 Figure 21 Key 1 */ if (r->recv_len < UDS_0X2E_REQ_MIN_LEN) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } - dataId = (r->recv_buf[1] << 8) + r->recv_buf[2]; - dataLen = r->recv_len - UDS_0X2E_REQ_BASE_LEN; + dataId = (uint16_t)((uint16_t)(r->recv_buf[1] << 8) | (uint16_t)r->recv_buf[2]); + dataLen = (uint16_t)(r->recv_len - UDS_0X2E_REQ_BASE_LEN); UDSWDBIArgs_t args = { .dataId = dataId, @@ -389,38 +392,39 @@ static uint8_t _0x2E_WriteDataByIdentifier(UDSServer_t *srv, UDSReq_t *r) { r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_WRITE_DATA_BY_IDENTIFIER); r->send_buf[1] = dataId >> 8; - r->send_buf[2] = dataId; + r->send_buf[2] = dataId & 0xFF; r->send_len = UDS_0X2E_RESP_LEN; return UDS_PositiveResponse; } -static uint8_t _0x31_RoutineControl(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err = UDS_PositiveResponse; +static UDSErr_t Handle_0x31_RoutineControl(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; if (r->recv_len < UDS_0X31_REQ_MIN_LEN) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } uint8_t routineControlType = r->recv_buf[1] & 0x7F; - uint16_t routineIdentifier = (r->recv_buf[2] << 8) + r->recv_buf[3]; + uint16_t routineIdentifier = + (uint16_t)((uint16_t)(r->recv_buf[2] << 8) | (uint16_t)r->recv_buf[3]); UDSRoutineCtrlArgs_t args = { .ctrlType = routineControlType, .id = routineIdentifier, .optionRecord = &r->recv_buf[UDS_0X31_REQ_MIN_LEN], - .len = r->recv_len - UDS_0X31_REQ_MIN_LEN, + .len = (uint16_t)(r->recv_len - UDS_0X31_REQ_MIN_LEN), .copyStatusRecord = safe_copy, }; r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_ROUTINE_CONTROL); r->send_buf[1] = routineControlType; r->send_buf[2] = routineIdentifier >> 8; - r->send_buf[3] = routineIdentifier; + r->send_buf[3] = routineIdentifier & 0xFF; r->send_len = UDS_0X31_RESP_MIN_LEN; switch (routineControlType) { - case kStartRoutine: - case kStopRoutine: - case kRequestRoutineResults: + case UDS_LEV_RCTP_STR: // start routine + case UDS_LEV_RCTP_STPR: // stop routine + case UDS_LEV_RCTP_RRR: // request routine results err = EmitEvent(srv, UDS_EVT_RoutineCtrl, &args); if (UDS_PositiveResponse != err) { return NegativeResponse(r, err); @@ -440,8 +444,8 @@ static void ResetTransfer(UDSServer_t *srv) { srv->xferIsActive = false; } -static uint8_t _0x34_RequestDownload(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err; +static UDSErr_t Handle_0x34_RequestDownload(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; void *memoryAddress = 0; size_t memorySize = 0; @@ -497,17 +501,17 @@ static uint8_t _0x34_RequestDownload(UDSServer_t *srv, UDSReq_t *r) { r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_REQUEST_DOWNLOAD); r->send_buf[1] = lengthFormatIdentifier; - for (uint8_t idx = 0; idx < sizeof(args.maxNumberOfBlockLength); idx++) { + for (uint8_t idx = 0; idx < (uint8_t)sizeof(args.maxNumberOfBlockLength); idx++) { uint8_t shiftBytes = sizeof(args.maxNumberOfBlockLength) - 1 - idx; - uint8_t byte = args.maxNumberOfBlockLength >> (shiftBytes * 8); + uint8_t byte = (args.maxNumberOfBlockLength >> (shiftBytes * 8)) & 0xFF; r->send_buf[UDS_0X34_RESP_BASE_LEN + idx] = byte; } r->send_len = UDS_0X34_RESP_BASE_LEN + sizeof(args.maxNumberOfBlockLength); return UDS_PositiveResponse; } -static uint8_t _0x35_RequestUpload(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err; +static UDSErr_t Handle_0x35_RequestUpload(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; void *memoryAddress = 0; size_t memorySize = 0; @@ -551,18 +555,18 @@ static uint8_t _0x35_RequestUpload(UDSServer_t *srv, UDSReq_t *r) { r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_REQUEST_UPLOAD); r->send_buf[1] = lengthFormatIdentifier; - for (uint8_t idx = 0; idx < sizeof(args.maxNumberOfBlockLength); idx++) { - uint8_t shiftBytes = sizeof(args.maxNumberOfBlockLength) - 1 - idx; - uint8_t byte = args.maxNumberOfBlockLength >> (shiftBytes * 8); + for (uint8_t idx = 0; idx < (uint8_t)sizeof(args.maxNumberOfBlockLength); idx++) { + uint8_t shiftBytes = (sizeof(args.maxNumberOfBlockLength) - 1 - idx) & 0xFF; + uint8_t byte = (args.maxNumberOfBlockLength >> (shiftBytes * 8)) & 0xFF; r->send_buf[UDS_0X35_RESP_BASE_LEN + idx] = byte; } r->send_len = UDS_0X35_RESP_BASE_LEN + sizeof(args.maxNumberOfBlockLength); return UDS_PositiveResponse; } -static uint8_t _0x36_TransferData(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err = UDS_PositiveResponse; - uint16_t request_data_len = r->recv_len - UDS_0X36_REQ_BASE_LEN; +static UDSErr_t Handle_0x36_TransferData(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; + uint16_t request_data_len = (uint16_t)(r->recv_len - UDS_0X36_REQ_BASE_LEN); uint8_t blockSequenceCounter = 0; if (!srv->xferIsActive) { @@ -593,8 +597,8 @@ static uint8_t _0x36_TransferData(UDSServer_t *srv, UDSReq_t *r) { { UDSTransferDataArgs_t args = { .data = &r->recv_buf[UDS_0X36_REQ_BASE_LEN], - .len = r->recv_len - UDS_0X36_REQ_BASE_LEN, - .maxRespLen = srv->xferBlockLength - UDS_0X36_RESP_BASE_LEN, + .len = (uint16_t)(r->recv_len - UDS_0X36_REQ_BASE_LEN), + .maxRespLen = (uint16_t)(srv->xferBlockLength - UDS_0X36_RESP_BASE_LEN), .copyResponse = safe_copy, }; @@ -604,13 +608,12 @@ static uint8_t _0x36_TransferData(UDSServer_t *srv, UDSReq_t *r) { err = EmitEvent(srv, UDS_EVT_TransferData, &args); - switch (err) { - case UDS_PositiveResponse: + if (err == UDS_PositiveResponse) { srv->xferByteCounter += request_data_len; return UDS_PositiveResponse; - case UDS_NRC_RequestCorrectlyReceived_ResponsePending: + } else if (err == UDS_NRC_RequestCorrectlyReceived_ResponsePending) { return NegativeResponse(r, UDS_NRC_RequestCorrectlyReceived_ResponsePending); - default: + } else { goto fail; } } @@ -620,8 +623,8 @@ static uint8_t _0x36_TransferData(UDSServer_t *srv, UDSReq_t *r) { return NegativeResponse(r, err); } -static uint8_t _0x37_RequestTransferExit(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err = UDS_PositiveResponse; +static UDSErr_t Handle_0x37_RequestTransferExit(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; if (!srv->xferIsActive) { return NegativeResponse(r, UDS_NRC_UploadDownloadNotAccepted); @@ -632,25 +635,25 @@ static uint8_t _0x37_RequestTransferExit(UDSServer_t *srv, UDSReq_t *r) { UDSRequestTransferExitArgs_t args = { .data = &r->recv_buf[UDS_0X37_REQ_BASE_LEN], - .len = r->recv_len - UDS_0X37_REQ_BASE_LEN, + .len = (uint16_t)(r->recv_len - UDS_0X37_REQ_BASE_LEN), .copyResponse = safe_copy, }; err = EmitEvent(srv, UDS_EVT_RequestTransferExit, &args); - switch (err) { - case UDS_PositiveResponse: + if (err == UDS_PositiveResponse) { ResetTransfer(srv); return UDS_PositiveResponse; - case UDS_NRC_RequestCorrectlyReceived_ResponsePending: + } else if (err == UDS_NRC_RequestCorrectlyReceived_ResponsePending) { return NegativeResponse(r, UDS_NRC_RequestCorrectlyReceived_ResponsePending); - default: + } else { ResetTransfer(srv); return NegativeResponse(r, err); } } -static uint8_t _0x38_RequestFileTransfer(UDSServer_t *srv, UDSReq_t *r) { - uint8_t err = UDS_PositiveResponse; + +static UDSErr_t Handle_0x38_RequestFileTransfer(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t err = UDS_PositiveResponse; if (srv->xferIsActive) { return NegativeResponse(r, UDS_NRC_ConditionsNotCorrect); @@ -660,26 +663,27 @@ static uint8_t _0x38_RequestFileTransfer(UDSServer_t *srv, UDSReq_t *r) { } uint8_t operation = r->recv_buf[1]; - uint16_t file_path_len = ((uint16_t)r->recv_buf[2] << 8) + r->recv_buf[3]; + uint16_t file_path_len = (uint16_t)(((uint16_t)r->recv_buf[2] << 8) + (uint16_t)r->recv_buf[3]); uint8_t file_mode = 0; - if ((operation == kAddFile) || (operation == kReplaceFile) || (operation == kReadFile)) { + if ((operation == UDS_MOOP_ADDFILE) || (operation == UDS_MOOP_REPLFILE) || + (operation == UDS_MOOP_RDFILE)) { file_mode = r->recv_buf[UDS_0X38_REQ_BASE_LEN + file_path_len]; } size_t file_size_uncompressed = 0; size_t file_size_compressed = 0; - if ((operation == kAddFile) || (operation == kReplaceFile)) { + if ((operation == UDS_MOOP_ADDFILE) || (operation == UDS_MOOP_REPLFILE)) { size_t size = r->recv_buf[UDS_0X38_REQ_BASE_LEN + file_path_len + 1]; if (size > sizeof(size_t)) { return NegativeResponse(r, UDS_NRC_RequestOutOfRange); } for (size_t byteIdx = 0; byteIdx < size; byteIdx++) { size_t byte = r->recv_buf[UDS_0X38_REQ_BASE_LEN + file_path_len + 2 + byteIdx]; - uint8_t shiftBytes = size - 1 - byteIdx; + uint8_t shiftBytes = (uint8_t)(size - 1 - byteIdx); file_size_uncompressed |= byte << (8 * shiftBytes); } for (size_t byteIdx = 0; byteIdx < size; byteIdx++) { size_t byte = r->recv_buf[UDS_0X38_REQ_BASE_LEN + file_path_len + 2 + size + byteIdx]; - uint8_t shiftBytes = size - 1 - byteIdx; + uint8_t shiftBytes = (uint8_t)(size - 1 - byteIdx); file_size_compressed |= byte << (8 * shiftBytes); } } @@ -710,9 +714,9 @@ static uint8_t _0x38_RequestFileTransfer(UDSServer_t *srv, UDSReq_t *r) { r->send_buf[0] = UDS_RESPONSE_SID_OF(kSID_REQUEST_FILE_TRANSFER); r->send_buf[1] = args.modeOfOperation; r->send_buf[2] = sizeof(args.maxNumberOfBlockLength); - for (uint8_t idx = 0; idx < sizeof(args.maxNumberOfBlockLength); idx++) { + for (uint8_t idx = 0; idx < (uint8_t)sizeof(args.maxNumberOfBlockLength); idx++) { uint8_t shiftBytes = sizeof(args.maxNumberOfBlockLength) - 1 - idx; - uint8_t byte = args.maxNumberOfBlockLength >> (shiftBytes * 8); + uint8_t byte = (uint8_t)(args.maxNumberOfBlockLength >> (shiftBytes * 8)); r->send_buf[UDS_0X38_RESP_BASE_LEN + idx] = byte; } r->send_buf[UDS_0X38_RESP_BASE_LEN + sizeof(args.maxNumberOfBlockLength)] = @@ -722,7 +726,7 @@ static uint8_t _0x38_RequestFileTransfer(UDSServer_t *srv, UDSReq_t *r) { return UDS_PositiveResponse; } -static uint8_t _0x3E_TesterPresent(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x3E_TesterPresent(UDSServer_t *srv, UDSReq_t *r) { if ((r->recv_len < UDS_0X3E_REQ_MIN_LEN) || (r->recv_len > UDS_0X3E_REQ_MAX_LEN)) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } @@ -741,7 +745,8 @@ static uint8_t _0x3E_TesterPresent(UDSServer_t *srv, UDSReq_t *r) { } } -static uint8_t _0x85_ControlDTCSetting(UDSServer_t *srv, UDSReq_t *r) { +static UDSErr_t Handle_0x85_ControlDTCSetting(UDSServer_t *srv, UDSReq_t *r) { + (void)srv; if (r->recv_len < UDS_0X85_REQ_BASE_LEN) { return NegativeResponse(r, UDS_NRC_IncorrectMessageLengthOrInvalidFormat); } @@ -753,7 +758,7 @@ static uint8_t _0x85_ControlDTCSetting(UDSServer_t *srv, UDSReq_t *r) { return UDS_PositiveResponse; } -typedef uint8_t (*UDSService)(UDSServer_t *srv, UDSReq_t *r); +typedef UDSErr_t (*UDSService)(UDSServer_t *srv, UDSReq_t *r); /** * @brief Get the internal service handler matching the given SID. @@ -763,53 +768,53 @@ typedef uint8_t (*UDSService)(UDSServer_t *srv, UDSReq_t *r); static UDSService getServiceForSID(uint8_t sid) { switch (sid) { case kSID_DIAGNOSTIC_SESSION_CONTROL: - return _0x10_DiagnosticSessionControl; + return Handle_0x10_DiagnosticSessionControl; case kSID_ECU_RESET: - return _0x11_ECUReset; + return Handle_0x11_ECUReset; case kSID_CLEAR_DIAGNOSTIC_INFORMATION: return NULL; case kSID_READ_DTC_INFORMATION: return NULL; case kSID_READ_DATA_BY_IDENTIFIER: - return _0x22_ReadDataByIdentifier; + return Handle_0x22_ReadDataByIdentifier; case kSID_READ_MEMORY_BY_ADDRESS: - return _0x23_ReadMemoryByAddress; + return Handle_0x23_ReadMemoryByAddress; case kSID_READ_SCALING_DATA_BY_IDENTIFIER: return NULL; case kSID_SECURITY_ACCESS: - return _0x27_SecurityAccess; + return Handle_0x27_SecurityAccess; case kSID_COMMUNICATION_CONTROL: - return _0x28_CommunicationControl; + return Handle_0x28_CommunicationControl; case kSID_READ_PERIODIC_DATA_BY_IDENTIFIER: return NULL; case kSID_DYNAMICALLY_DEFINE_DATA_IDENTIFIER: return NULL; case kSID_WRITE_DATA_BY_IDENTIFIER: - return _0x2E_WriteDataByIdentifier; + return Handle_0x2E_WriteDataByIdentifier; case kSID_INPUT_CONTROL_BY_IDENTIFIER: return NULL; case kSID_ROUTINE_CONTROL: - return _0x31_RoutineControl; + return Handle_0x31_RoutineControl; case kSID_REQUEST_DOWNLOAD: - return _0x34_RequestDownload; + return Handle_0x34_RequestDownload; case kSID_REQUEST_UPLOAD: - return _0x35_RequestUpload; + return Handle_0x35_RequestUpload; case kSID_TRANSFER_DATA: - return _0x36_TransferData; + return Handle_0x36_TransferData; case kSID_REQUEST_TRANSFER_EXIT: - return _0x37_RequestTransferExit; + return Handle_0x37_RequestTransferExit; case kSID_REQUEST_FILE_TRANSFER: - return _0x38_RequestFileTransfer; + return Handle_0x38_RequestFileTransfer; case kSID_WRITE_MEMORY_BY_ADDRESS: return NULL; case kSID_TESTER_PRESENT: - return _0x3E_TesterPresent; + return Handle_0x3E_TesterPresent; case kSID_ACCESS_TIMING_PARAMETER: return NULL; case kSID_SECURED_DATA_TRANSMISSION: return NULL; case kSID_CONTROL_DTC_SETTING: - return _0x85_ControlDTCSetting; + return Handle_0x85_ControlDTCSetting; case kSID_RESPONSE_ON_EVENT: return NULL; default: @@ -825,8 +830,8 @@ static UDSService getServiceForSID(uint8_t sid) { * @param srv * @param addressingScheme */ -static uint8_t evaluateServiceResponse(UDSServer_t *srv, UDSReq_t *r) { - uint8_t response = UDS_PositiveResponse; +static UDSErr_t evaluateServiceResponse(UDSServer_t *srv, UDSReq_t *r) { + UDSErr_t response = UDS_PositiveResponse; bool suppressResponse = false; uint8_t sid = r->recv_buf[0]; UDSService service = getServiceForSID(sid); @@ -895,14 +900,14 @@ static uint8_t evaluateServiceResponse(UDSServer_t *srv, UDSReq_t *r) { UDSCustomArgs_t args = { .sid = sid, .optionRecord = &r->recv_buf[1], - .len = r->recv_len - 1, + .len = (uint16_t)(r->recv_len - 1), .copyResponse = safe_copy, }; r->send_buf[0] = UDS_RESPONSE_SID_OF(sid); r->send_len = 1; - response = EmitEvent(srv, UDS_EVT_CUSTOM, &args); + response = EmitEvent(srv, UDS_EVT_Custom, &args); if (UDS_PositiveResponse != response) return NegativeResponse(r, response); } @@ -919,15 +924,16 @@ static uint8_t evaluateServiceResponse(UDSServer_t *srv, UDSReq_t *r) { ( // TODO: *not yet a NRC 0x78 response sent* true)) { - suppressResponse = true; /* Suppress negative response message */ + /* Suppress negative response message */ + suppressResponse = true; + } + + if (suppressResponse) { NoResponse(r); - } else { - if (suppressResponse) { /* Suppress positive response message */ - NoResponse(r); - } else { /* send negative or positive response */ - ; - } + } else { /* send negative or positive response */ + ; } + return response; } @@ -943,7 +949,7 @@ UDSErr_t UDSServerInit(UDSServer_t *srv) { srv->p2_ms = UDS_SERVER_DEFAULT_P2_MS; srv->p2_star_ms = UDS_SERVER_DEFAULT_P2_STAR_MS; srv->s3_ms = UDS_SERVER_DEFAULT_S3_MS; - srv->sessionType = kDefaultSession; + srv->sessionType = UDS_LEV_DS_DS; srv->p2_timer = UDSMillis() + srv->p2_ms; srv->s3_session_timeout_timer = UDSMillis() + srv->s3_ms; srv->sec_access_boot_delay_timer = @@ -954,7 +960,7 @@ UDSErr_t UDSServerInit(UDSServer_t *srv) { void UDSServerPoll(UDSServer_t *srv) { // UDS-1-2013 Figure 38: Session Timeout (S3) - if (kDefaultSession != srv->sessionType && + if (UDS_LEV_DS_DS != srv->sessionType && UDSTimeAfter(UDSMillis(), srv->s3_session_timeout_timer)) { EmitEvent(srv, UDS_EVT_SessionTimeout, NULL); } @@ -972,7 +978,7 @@ void UDSServerPoll(UDSServer_t *srv) { // responds only if // 1. changed (no longer RCRRP), or // 2. p2_timer has elapsed - uint8_t response = evaluateServiceResponse(srv, r); + UDSErr_t response = evaluateServiceResponse(srv, r); if (UDS_NRC_RequestCorrectlyReceived_ResponsePending == response) { // it's the second time the service has responded with RCRRP srv->notReadyToReceive = true; @@ -1030,7 +1036,7 @@ void UDSServerPoll(UDSServer_t *srv) { UDS_LOGI(__FILE__, "bad tport\n"); return; } - uint8_t response = evaluateServiceResponse(srv, r); + UDSErr_t response = evaluateServiceResponse(srv, r); srv->requestInProgress = true; if (UDS_NRC_RequestCorrectlyReceived_ResponsePending == response) { srv->RCRRP = true; diff --git a/src/server.h b/src/server.h index 752c3e4..5d056c8 100644 --- a/src/server.h +++ b/src/server.h @@ -18,7 +18,7 @@ typedef struct { typedef struct UDSServer { UDSTp_t *tp; - int (*fn)(struct UDSServer *srv, UDSEvent_t event, void *arg); + UDSErr_t (*fn)(struct UDSServer *srv, UDSEvent_t event, void *arg); void *fn_data; // user-specified function data /** @@ -72,14 +72,14 @@ typedef struct UDSServer { } UDSServer_t; typedef struct { - const uint8_t type; /*! requested diagnostic session type (enum UDSDiagnosticSessionType) */ + const uint8_t type; /*! requested diagnostic session type */ uint16_t p2_ms; /*! optional: p2 timing override */ uint32_t p2_star_ms; /*! optional: p2* timing override */ } UDSDiagSessCtrlArgs_t; typedef struct { const uint8_t type; /**< \~chinese 客户端请求的复位类型 \~english reset type requested by client - (enum UDSECUResetType) */ + (uint8_t) */ uint32_t powerDownTimeMillis; /**< when this much time has elapsed after a UDS_PositiveResponse, a UDS_EVT_DoScheduledReset will be issued */ } UDSECUResetArgs_t; @@ -98,8 +98,8 @@ typedef struct { } UDSReadMemByAddrArgs_t; typedef struct { - uint8_t ctrlType; /* enum UDSCommunicationControlType */ - uint8_t commType; /* enum UDSCommunicationType */ + uint8_t ctrlType; /* uint8_t */ + uint8_t commType; /* uint8_t */ } UDSCommCtrlArgs_t; typedef struct { diff --git a/src/tp/isotp_sock.c b/src/tp/isotp_sock.c index eae77aa..42bef9d 100644 --- a/src/tp/isotp_sock.c +++ b/src/tp/isotp_sock.c @@ -1,7 +1,7 @@ #if defined(UDS_TP_ISOTP_SOCK) #include "tp/isotp_sock.h" -#include "iso14229.h" +#include "uds.h" #include #include #include diff --git a/src/tp/isotp_sock.h b/src/tp/isotp_sock.h index 50ec6f0..590686e 100644 --- a/src/tp/isotp_sock.h +++ b/src/tp/isotp_sock.h @@ -1,7 +1,8 @@ #if defined(UDS_TP_ISOTP_SOCK) #pragma once -#include "iso14229.h" +#include "tp.h" +#include "uds.h" typedef struct { UDSTp_t hdl; diff --git a/src/uds.h b/src/uds.h index 2d65469..1d34cca 100644 --- a/src/uds.h +++ b/src/uds.h @@ -19,9 +19,9 @@ typedef enum UDSEvent { UDS_EVT_TransferData, // UDSTransferDataArgs_t * UDS_EVT_RequestTransferExit, // UDSRequestTransferExitArgs_t * UDS_EVT_SessionTimeout, // NULL - UDS_EVT_DoScheduledReset, // enum UDSEcuResetType * + UDS_EVT_DoScheduledReset, // uint8_t * UDS_EVT_RequestFileTransfer, // UDSRequestFileTransferArgs_t * - UDS_EVT_CUSTOM, // UDSCustomArgs_t * + UDS_EVT_Custom, // UDSCustomArgs_t * // Client Event UDS_EVT_Poll, // NULL @@ -36,7 +36,8 @@ typedef enum { UDS_FAIL = -1, // 通用错误 UDS_OK = 0, // 成功 - // Negative Response Codes (NRCs) as defined in ISO14229-1:2020 + // Negative Response Codes (NRCs) as defined in ISO14229-1:2020 Table A.1 - Negative Response + // Code (NRC) definition and values UDS_PositiveResponse = 0, // 0x01 to 0x0F are reserved by ISO14229-1:2020 UDS_NRC_GeneralReject = 0x10, @@ -125,81 +126,67 @@ typedef enum { UDS_ERR_MISUSE, // The library is used incorrectly } UDSErr_t; -enum UDSDiagnosticSessionType { - kDefaultSession = 0x01, - kProgrammingSession = 0x02, - kExtendedDiagnostic = 0x03, - kSafetySystemDiagnostic = 0x04, -}; - -/** - * @brief LEV_RT_ - * @addtogroup ecuReset_0x11 - */ -enum UDSECUResetType { - kHardReset = 1, - kKeyOffOnReset = 2, - kSoftReset = 3, - kEnableRapidPowerShutDown = 4, - kDisableRapidPowerShutDown = 5, -}; - -typedef uint8_t UDSECUReset_t; +// ISO14229-1:2020 Table 25 +// UDS Level Diagnostic Session +#define UDS_LEV_DS_DS 01 // Default Session +#define UDS_LEV_DS_PRGS 02 // Programming Session +#define UDS_LEV_DS_EXTDS 03 // Extended Diagnostic Session +#define UDS_LEV_DS_SSDS 04 // Safety System Diagnostic Session /** - * @addtogroup securityAccess_0x27 + * @brief 0x11 ECU Reset SubFunction = [resetType] + * ISO14229-1:2020 Table 34 + * UDS Level Reset Type */ -enum UDSSecurityAccessType { - kRequestSeed = 0x01, - kSendKey = 0x02, -}; +#define UDS_LEV_RT_HR 01 // Hard Reset +#define UDS_LEV_RT_KOFFONR 02 // Key Off On Reset +#define UDS_LEV_RT_SR 03 // Soft Reset +#define UDS_LEV_RT_ERPSD 04 // Enable Rapid Power Shut Down +#define UDS_LEV_RT_DRPSD 05 // Disable Rapid Power Shut Down /** - * @addtogroup communicationControl_0x28 + * @brief 0x28 Communication Control SubFunction = [controlType] + * ISO14229-1:2020 Table 54 + * UDS Level Control Type */ -enum UDSCommunicationControlType { - kEnableRxAndTx = 0, - kEnableRxAndDisableTx = 1, - kDisableRxAndEnableTx = 2, - kDisableRxAndTx = 3, -}; +#define UDS_LEV_CTRLTP_ERXTX 0 // EnableRxAndTx +#define UDS_LEV_CTRLTP_ERXDTX 1 // EnableRxAndDisableTx +#define UDS_LEV_CTRLTP_DRXETX 2 // DisableRxAndEnableTx +#define UDS_LEV_CTRLTP_DRXTX 3 // DisableRxAndTx /** - * @addtogroup communicationControl_0x28 + * @brief 0x28 Communication Control communicationType + * ISO14229-1:2020 Table B.1 */ -enum UDSCommunicationType { - kNormalCommunicationMessages = 0x1, - kNetworkManagementCommunicationMessages = 0x2, - kNetworkManagementCommunicationMessagesAndNormalCommunicationMessages = 0x3, -}; +#define UDS_CTP_NCM 1 // NormalCommunicationMessages +#define UDS_CTP_NWMCM 2 // NetworkManagementCommunicationMessages +#define UDS_CTP_NWMCM_NCM 3 // NetworkManagementCommunicationMessagesAndNormalCommunicationMessages /** - * @addtogroup routineControl_0x31 + * @brief 0x31 RoutineControl SubFunction = [routineControlType] + * ISO14229-1:2020 Table 426 */ -enum RoutineControlType { - kStartRoutine = 1, - kStopRoutine = 2, - kRequestRoutineResults = 3, -}; +#define UDS_LEV_RCTP_STR 1 // StartRoutine +#define UDS_LEV_RCTP_STPR 2 // StopRoutine +#define UDS_LEV_RCTP_RRR 3 // RequestRoutineResults /** - * @addtogroup requestFileTransfer_0x38 + * @brief modeOfOperation parameter used in 0x38 RequestFileTransfer + * ISO14229-1:2020 Table G.1 */ -enum FileOperationMode { - kAddFile = 1, - kDeleteFile = 2, - kReplaceFile = 3, - kReadFile = 4, - kReadDir = 5, -}; +#define UDS_MOOP_ADDFILE 1 // AddFile +#define UDS_MOOP_DELFILE 2 // DeleteFile +#define UDS_MOOP_REPLFILE 3 // ReplaceFile +#define UDS_MOOP_RDFILE 4 // ReadFile +#define UDS_MOOP_RDDIR 5 // ReadDirectory +#define UDS_MOOP_RSFILE 6 // ResumeFile /** - * @addtogroup controlDTCSetting_0x85 + * @brief 0x85 ControlDTCSetting SubFunction = [dtcSettingType] + * ISO14229-1:2020 Table 128 */ -enum DTCSettingType { - kDTCSettingON = 0x01, - kDTCSettingOFF = 0x02, -}; +#define LEV_DTCSTP_ON 1 +#define LEV_DTCSTP_OFF 2 // ISO-14229-1:2013 Table 2 #define UDS_MAX_DIAGNOSTIC_SERVICES 0x7F diff --git a/src/util.c b/src/util.c index 47db7f6..5916c84 100644 --- a/src/util.c +++ b/src/util.c @@ -26,106 +26,226 @@ uint32_t UDSMillis(void) { } #endif +/** + * @brief Check if a security level is reserved per ISO14229-1:2020 Table 42 + * + * @param securityLevel + * @return true + * @return false + */ bool UDSSecurityAccessLevelIsReserved(uint8_t securityLevel) { securityLevel &= 0x3f; - return (0 == securityLevel || (0x43 <= securityLevel && securityLevel >= 0x5E) || - 0x7F == securityLevel); + if (0 == securityLevel) { + return true; + } + if (securityLevel >= 0x43 && securityLevel <= 0x5E) { + return true; + } + if (securityLevel == 0x7F) { + return true; + } + return false; } const char *UDSErrToStr(UDSErr_t err) { -#define MAKE_CASE(x) \ - case x: \ - return #x; - switch (err) { - MAKE_CASE(UDS_FAIL) - MAKE_CASE(UDS_OK) - MAKE_CASE(UDS_NRC_GeneralReject) - MAKE_CASE(UDS_NRC_ServiceNotSupported) - MAKE_CASE(UDS_NRC_SubFunctionNotSupported) - MAKE_CASE(UDS_NRC_IncorrectMessageLengthOrInvalidFormat) - MAKE_CASE(UDS_NRC_ResponseTooLong) - MAKE_CASE(UDS_NRC_BusyRepeatRequest) - MAKE_CASE(UDS_NRC_ConditionsNotCorrect) - MAKE_CASE(UDS_NRC_RequestSequenceError) - MAKE_CASE(UDS_NRC_NoResponseFromSubnetComponent) - MAKE_CASE(UDS_NRC_FailurePreventsExecutionOfRequestedAction) - MAKE_CASE(UDS_NRC_RequestOutOfRange) - MAKE_CASE(UDS_NRC_SecurityAccessDenied) - MAKE_CASE(UDS_NRC_InvalidKey) - MAKE_CASE(UDS_NRC_ExceedNumberOfAttempts) - MAKE_CASE(UDS_NRC_RequiredTimeDelayNotExpired) - MAKE_CASE(UDS_NRC_UploadDownloadNotAccepted) - MAKE_CASE(UDS_NRC_TransferDataSuspended) - MAKE_CASE(UDS_NRC_GeneralProgrammingFailure) - MAKE_CASE(UDS_NRC_WrongBlockSequenceCounter) - MAKE_CASE(UDS_NRC_RequestCorrectlyReceived_ResponsePending) - MAKE_CASE(UDS_NRC_SubFunctionNotSupportedInActiveSession) - MAKE_CASE(UDS_NRC_ServiceNotSupportedInActiveSession) - MAKE_CASE(UDS_NRC_RpmTooHigh) - MAKE_CASE(UDS_NRC_RpmTooLow) - MAKE_CASE(UDS_NRC_EngineIsRunning) - MAKE_CASE(UDS_NRC_EngineIsNotRunning) - MAKE_CASE(UDS_NRC_EngineRunTimeTooLow) - MAKE_CASE(UDS_NRC_TemperatureTooHigh) - MAKE_CASE(UDS_NRC_TemperatureTooLow) - MAKE_CASE(UDS_NRC_VehicleSpeedTooHigh) - MAKE_CASE(UDS_NRC_VehicleSpeedTooLow) - MAKE_CASE(UDS_NRC_ThrottlePedalTooHigh) - MAKE_CASE(UDS_NRC_ThrottlePedalTooLow) - MAKE_CASE(UDS_NRC_TransmissionRangeNotInNeutral) - MAKE_CASE(UDS_NRC_TransmissionRangeNotInGear) - MAKE_CASE(UDS_NRC_BrakeSwitchNotClosed) - MAKE_CASE(UDS_NRC_ShifterLeverNotInPark) - MAKE_CASE(UDS_NRC_TorqueConverterClutchLocked) - MAKE_CASE(UDS_NRC_VoltageTooHigh) - MAKE_CASE(UDS_NRC_VoltageTooLow) - MAKE_CASE(UDS_ERR_TIMEOUT) - MAKE_CASE(UDS_ERR_DID_MISMATCH) - MAKE_CASE(UDS_ERR_SID_MISMATCH) - MAKE_CASE(UDS_ERR_SUBFUNCTION_MISMATCH) - MAKE_CASE(UDS_ERR_TPORT) - MAKE_CASE(UDS_ERR_RESP_TOO_SHORT) - MAKE_CASE(UDS_ERR_BUFSIZ) - MAKE_CASE(UDS_ERR_INVALID_ARG) - MAKE_CASE(UDS_ERR_BUSY) + case UDS_OK: + return "UDS_OK"; + case UDS_FAIL: + return "UDS_FAIL"; + case UDS_NRC_GeneralReject: + return "UDS_NRC_GeneralReject"; + case UDS_NRC_ServiceNotSupported: + return "UDS_NRC_ServiceNotSupported"; + case UDS_NRC_SubFunctionNotSupported: + return "UDS_NRC_SubFunctionNotSupported"; + case UDS_NRC_IncorrectMessageLengthOrInvalidFormat: + return "UDS_NRC_IncorrectMessageLengthOrInvalidFormat"; + case UDS_NRC_ResponseTooLong: + return "UDS_NRC_ResponseTooLong"; + case UDS_NRC_BusyRepeatRequest: + return "UDS_NRC_BusyRepeatRequest"; + case UDS_NRC_ConditionsNotCorrect: + return "UDS_NRC_ConditionsNotCorrect"; + case UDS_NRC_RequestSequenceError: + return "UDS_NRC_RequestSequenceError"; + case UDS_NRC_NoResponseFromSubnetComponent: + return "UDS_NRC_NoResponseFromSubnetComponent"; + case UDS_NRC_FailurePreventsExecutionOfRequestedAction: + return "UDS_NRC_FailurePreventsExecutionOfRequestedAction"; + case UDS_NRC_RequestOutOfRange: + return "UDS_NRC_RequestOutOfRange"; + case UDS_NRC_SecurityAccessDenied: + return "UDS_NRC_SecurityAccessDenied"; + case UDS_NRC_AuthenticationRequired: + return "UDS_NRC_AuthenticationRequired"; + case UDS_NRC_InvalidKey: + return "UDS_NRC_InvalidKey"; + case UDS_NRC_ExceedNumberOfAttempts: + return "UDS_NRC_ExceedNumberOfAttempts"; + case UDS_NRC_RequiredTimeDelayNotExpired: + return "UDS_NRC_RequiredTimeDelayNotExpired"; + case UDS_NRC_SecureDataTransmissionRequired: + return "UDS_NRC_SecureDataTransmissionRequired"; + case UDS_NRC_SecureDataTransmissionNotAllowed: + return "UDS_NRC_SecureDataTransmissionNotAllowed"; + case UDS_NRC_SecureDataVerificationFailed: + return "UDS_NRC_SecureDataVerificationFailed"; + case UDS_NRC_CertficateVerificationFailedInvalidTimePeriod: + return "UDS_NRC_CertficateVerificationFailedInvalidTimePeriod"; + case UDS_NRC_CertficateVerificationFailedInvalidSignature: + return "UDS_NRC_CertficateVerificationFailedInvalidSignature"; + case UDS_NRC_CertficateVerificationFailedInvalidChainOfTrust: + return "UDS_NRC_CertficateVerificationFailedInvalidChainOfTrust"; + case UDS_NRC_CertficateVerificationFailedInvalidType: + return "UDS_NRC_CertficateVerificationFailedInvalidType"; + case UDS_NRC_CertficateVerificationFailedInvalidFormat: + return "UDS_NRC_CertficateVerificationFailedInvalidFormat"; + case UDS_NRC_CertficateVerificationFailedInvalidContent: + return "UDS_NRC_CertficateVerificationFailedInvalidContent"; + case UDS_NRC_CertficateVerificationFailedInvalidScope: + return "UDS_NRC_CertficateVerificationFailedInvalidScope"; + case UDS_NRC_CertficateVerificationFailedInvalidCertificate: + return "UDS_NRC_CertficateVerificationFailedInvalidCertificate"; + case UDS_NRC_OwnershipVerificationFailed: + return "UDS_NRC_OwnershipVerificationFailed"; + case UDS_NRC_ChallengeCalculationFailed: + return "UDS_NRC_ChallengeCalculationFailed"; + case UDS_NRC_SettingAccessRightsFailed: + return "UDS_NRC_SettingAccessRightsFailed"; + case UDS_NRC_SessionKeyCreationOrDerivationFailed: + return "UDS_NRC_SessionKeyCreationOrDerivationFailed"; + case UDS_NRC_ConfigurationDataUsageFailed: + return "UDS_NRC_ConfigurationDataUsageFailed"; + case UDS_NRC_DeAuthenticationFailed: + return "UDS_NRC_DeAuthenticationFailed"; + case UDS_NRC_UploadDownloadNotAccepted: + return "UDS_NRC_UploadDownloadNotAccepted"; + case UDS_NRC_TransferDataSuspended: + return "UDS_NRC_TransferDataSuspended"; + case UDS_NRC_GeneralProgrammingFailure: + return "UDS_NRC_GeneralProgrammingFailure"; + case UDS_NRC_WrongBlockSequenceCounter: + return "UDS_NRC_WrongBlockSequenceCounter"; + case UDS_NRC_RequestCorrectlyReceived_ResponsePending: + return "UDS_NRC_RequestCorrectlyReceived_ResponsePending"; + case UDS_NRC_SubFunctionNotSupportedInActiveSession: + return "UDS_NRC_SubFunctionNotSupportedInActiveSession"; + case UDS_NRC_ServiceNotSupportedInActiveSession: + return "UDS_NRC_ServiceNotSupportedInActiveSession"; + case UDS_NRC_RpmTooHigh: + return "UDS_NRC_RpmTooHigh"; + case UDS_NRC_RpmTooLow: + return "UDS_NRC_RpmTooLow"; + case UDS_NRC_EngineIsRunning: + return "UDS_NRC_EngineIsRunning"; + case UDS_NRC_EngineIsNotRunning: + return "UDS_NRC_EngineIsNotRunning"; + case UDS_NRC_EngineRunTimeTooLow: + return "UDS_NRC_EngineRunTimeTooLow"; + case UDS_NRC_TemperatureTooHigh: + return "UDS_NRC_TemperatureTooHigh"; + case UDS_NRC_TemperatureTooLow: + return "UDS_NRC_TemperatureTooLow"; + case UDS_NRC_VehicleSpeedTooHigh: + return "UDS_NRC_VehicleSpeedTooHigh"; + case UDS_NRC_VehicleSpeedTooLow: + return "UDS_NRC_VehicleSpeedTooLow"; + case UDS_NRC_ThrottlePedalTooHigh: + return "UDS_NRC_ThrottlePedalTooHigh"; + case UDS_NRC_ThrottlePedalTooLow: + return "UDS_NRC_ThrottlePedalTooLow"; + case UDS_NRC_TransmissionRangeNotInNeutral: + return "UDS_NRC_TransmissionRangeNotInNeutral"; + case UDS_NRC_TransmissionRangeNotInGear: + return "UDS_NRC_TransmissionRangeNotInGear"; + case UDS_NRC_BrakeSwitchNotClosed: + return "UDS_NRC_BrakeSwitchNotClosed"; + case UDS_NRC_ShifterLeverNotInPark: + return "UDS_NRC_ShifterLeverNotInPark"; + case UDS_NRC_TorqueConverterClutchLocked: + return "UDS_NRC_TorqueConverterClutchLocked"; + case UDS_NRC_VoltageTooHigh: + return "UDS_NRC_VoltageTooHigh"; + case UDS_NRC_VoltageTooLow: + return "UDS_NRC_VoltageTooLow"; + case UDS_NRC_ResourceTemporarilyNotAvailable: + return "UDS_NRC_ResourceTemporarilyNotAvailable"; + case UDS_ERR_TIMEOUT: + return "UDS_ERR_TIMEOUT"; + case UDS_ERR_DID_MISMATCH: + return "UDS_ERR_DID_MISMATCH"; + case UDS_ERR_SID_MISMATCH: + return "UDS_ERR_SID_MISMATCH"; + case UDS_ERR_SUBFUNCTION_MISMATCH: + return "UDS_ERR_SUBFUNCTION_MISMATCH"; + case UDS_ERR_TPORT: + return "UDS_ERR_TPORT"; + case UDS_ERR_RESP_TOO_SHORT: + return "UDS_ERR_RESP_TOO_SHORT"; + case UDS_ERR_BUFSIZ: + return "UDS_ERR_BUFSIZ"; + case UDS_ERR_INVALID_ARG: + return "UDS_ERR_INVALID_ARG"; + case UDS_ERR_BUSY: + return "UDS_ERR_BUSY"; + case UDS_ERR_MISUSE: + return "UDS_ERR_MISUSE"; default: return "unknown"; } -#undef MAKE_CASE } const char *UDSEvtToStr(UDSEvent_t evt) { -#define MAKE_CASE(x) \ - case x: \ - return #x; switch (evt) { - MAKE_CASE(UDS_EVT_Err) - MAKE_CASE(UDS_EVT_DiagSessCtrl) - MAKE_CASE(UDS_EVT_EcuReset) - MAKE_CASE(UDS_EVT_ReadDataByIdent) - MAKE_CASE(UDS_EVT_ReadMemByAddr) - MAKE_CASE(UDS_EVT_CommCtrl) - MAKE_CASE(UDS_EVT_SecAccessRequestSeed) - MAKE_CASE(UDS_EVT_SecAccessValidateKey) - MAKE_CASE(UDS_EVT_WriteDataByIdent) - MAKE_CASE(UDS_EVT_RoutineCtrl) - MAKE_CASE(UDS_EVT_RequestDownload) - MAKE_CASE(UDS_EVT_RequestUpload) - MAKE_CASE(UDS_EVT_TransferData) - MAKE_CASE(UDS_EVT_RequestTransferExit) - MAKE_CASE(UDS_EVT_SessionTimeout) - MAKE_CASE(UDS_EVT_DoScheduledReset) - MAKE_CASE(UDS_EVT_RequestFileTransfer) - - MAKE_CASE(UDS_EVT_Poll) - MAKE_CASE(UDS_EVT_SendComplete) - MAKE_CASE(UDS_EVT_ResponseReceived) - MAKE_CASE(UDS_EVT_Idle) - + case UDS_EVT_Custom: + return "UDS_EVT_Custom"; + case UDS_EVT_Err: + return "UDS_EVT_Err"; + case UDS_EVT_DiagSessCtrl: + return "UDS_EVT_DiagSessCtrl"; + case UDS_EVT_EcuReset: + return "UDS_EVT_EcuReset"; + case UDS_EVT_ReadDataByIdent: + return "UDS_EVT_ReadDataByIdent"; + case UDS_EVT_ReadMemByAddr: + return "UDS_EVT_ReadMemByAddr"; + case UDS_EVT_CommCtrl: + return "UDS_EVT_CommCtrl"; + case UDS_EVT_SecAccessRequestSeed: + return "UDS_EVT_SecAccessRequestSeed"; + case UDS_EVT_SecAccessValidateKey: + return "UDS_EVT_SecAccessValidateKey"; + case UDS_EVT_WriteDataByIdent: + return "UDS_EVT_WriteDataByIdent"; + case UDS_EVT_RoutineCtrl: + return "UDS_EVT_RoutineCtrl"; + case UDS_EVT_RequestDownload: + return "UDS_EVT_RequestDownload"; + case UDS_EVT_RequestUpload: + return "UDS_EVT_RequestUpload"; + case UDS_EVT_TransferData: + return "UDS_EVT_TransferData"; + case UDS_EVT_RequestTransferExit: + return "UDS_EVT_RequestTransferExit"; + case UDS_EVT_SessionTimeout: + return "UDS_EVT_SessionTimeout"; + case UDS_EVT_DoScheduledReset: + return "UDS_EVT_DoScheduledReset"; + case UDS_EVT_RequestFileTransfer: + return "UDS_EVT_RequestFileTransfer"; + case UDS_EVT_Poll: + return "UDS_EVT_Poll"; + case UDS_EVT_SendComplete: + return "UDS_EVT_SendComplete"; + case UDS_EVT_ResponseReceived: + return "UDS_EVT_ResponseReceived"; + case UDS_EVT_Idle: + return "UDS_EVT_Idle"; + case UDS_EVT_MAX: + return "UDS_EVT_MAX"; default: return "unknown"; } -#undef MAKE_CASE } diff --git a/test/test_client.c b/test/test_client.c index 54376df..ecfb413 100644 --- a/test/test_client.c +++ b/test/test_client.c @@ -52,11 +52,11 @@ void test_duplicate_request(void **state) { Env_t *e = *state; // sending a request should succeed - UDSErr_t err = UDSSendECUReset(e->client, kHardReset); + UDSErr_t err = UDSSendECUReset(e->client, UDS_LEV_RT_HR); TEST_ERR_EQUAL(UDS_OK, err); // immediately sending another request should fail - err = UDSSendECUReset(e->client, kHardReset); + err = UDSSendECUReset(e->client, UDS_LEV_RT_HR); TEST_INT_EQUAL(UDS_ERR_BUSY, err); } @@ -90,7 +90,7 @@ void test_0x11_good_response(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_ResponseReceived], 1); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 0); @@ -108,7 +108,7 @@ void test_0x11_timeout(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 1); } @@ -125,7 +125,7 @@ void test_0x11_sid_mismatch(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 1); } @@ -142,7 +142,7 @@ void test_0x11_short_response(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 1); } @@ -159,7 +159,7 @@ void test_0x11_inconsistent_subfunc(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 1); } @@ -176,7 +176,7 @@ void test_0x11_neg_resp(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 1); } @@ -193,7 +193,7 @@ void test_0x11_rcrrp_timeout(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, e->client->p2_star_ms - 10); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 0); @@ -213,7 +213,7 @@ void test_0x11_rcrrp_ok(void **state) { int call_count[UDS_EVT_MAX] = {0}; e->client->fn = fn_log_call_count; e->client->fn_data = call_count; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, e->client->p2_star_ms - 10); TEST_INT_EQUAL(call_count[UDS_EVT_Err], 0); @@ -232,7 +232,7 @@ void test_0x11_suppress_pos_resp(void **state) { // when the suppressPositiveResponse flag is set e->client->options |= UDS_SUPPRESS_POS_RESP; - UDSSendECUReset(e->client, kHardReset); + UDSSendECUReset(e->client, UDS_LEV_RT_HR); EnvRunMillis(e, 1000); // Sending will succeed but there should be no response diff --git a/test/test_server.c b/test/test_server.c index a33591d..cd56190 100644 --- a/test/test_server.c +++ b/test/test_server.c @@ -41,7 +41,7 @@ void test_default_session_does_not_timeout(void **state) { // When a server is initialized with a default session e->server->fn = fn_test_session_timeout; e->server->fn_data = &call_count; - e->server->sessionType = kDefaultSession; + e->server->sessionType = UDS_LEV_DS_DS; // and the server is run for a long time with no communication EnvRunMillis(e, 10000); @@ -57,7 +57,7 @@ void test_programming_session_times_out(void **state) { // When a server is initialized with a programming session e->server->fn = fn_test_session_timeout; e->server->fn_data = &call_count; - e->server->sessionType = kProgrammingSession; + e->server->sessionType = UDS_LEV_DS_PRGS; // and the server is run for a long time with no communication EnvRunMillis(e, 10000); @@ -114,7 +114,7 @@ void test_0x10_suppress_pos_resp(void **state) { TEST_INT_EQUAL(UDSTpGetRecvLen(e->client_tp), 0); // however, the server sessionType should have changed - TEST_INT_EQUAL(e->server->sessionType, kExtendedDiagnostic); + TEST_INT_EQUAL(e->server->sessionType, UDS_LEV_DS_EXTDS); }