Обновление

This commit is contained in:
cfif 2026-01-28 14:48:17 +03:00
parent 42742bdc11
commit ab72ce1271
2 changed files with 93 additions and 97 deletions

183
CanUds.c
View File

@ -9,110 +9,97 @@
#include "DiagnosticSessionControl_10.h" #include "DiagnosticSessionControl_10.h"
#include "StatusError.h" #include "StatusError.h"
#include "SystemDelayInterface.h" #include "SystemDelayInterface.h"
#include "candb.h"
#include "stdio.h"
#define LOG_SIGN "CAN_UDS" #define LOG_SIGN "CAN_UDS"
#define LOGGER env->logger #define LOGGER env->logger
uint32_t randomSecuritySeed = 0x11223344; uint32_t randomSecuritySeed = 0x853A08FB;
// Определение операций инверсии бит extern uint32_t generate_key(uint32_t seed);
#define INV_OP_A_MASK ((1UL << 6) | (1UL << 15) | (1UL << 17) | (1UL << 11) | \
(1UL << 9) | (1UL << 16) | (1UL << 7) | (1UL << 10) | \
(1UL << 13) | (1UL << 4))
#define INV_OP_B_MASK ((1UL << 14) | (1UL << 16) | (1UL << 11) | (1UL << 9) | \
(1UL << 15) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \
(1UL << 4) | (1UL << 1))
#define INV_OP_C_MASK ((1UL << 1) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \ static char strPrintfDebug_UDS[80];
(1UL << 4) | (1UL << 14) | (1UL << 16) | (1UL << 11) | \
(1UL << 9) | (1UL << 15))
/** static void PrintfDebug(uint8_t *data, uint8_t dlc) {
* @brief Генерация ключа по сиду согласно алгоритму CCU
* @param seed Входное 32-битное значение сида
* @return 32-битный ключ
*/
static uint32_t generate_key_from_seed(uint32_t seed) {
// Шаг 1: Извлечение коэффициентов из сида
// Коэффициенты извлекаются из определенных битовых позиций (0 - LSB)
// Коэффициент 1 (бит 20): направление сдвига (0=влево, 1=вправо) switch (dlc) {
uint8_t shift_direction = (seed >> 20) & 0x01;
// Коэффициенты 2-5 (биты 7,11,5,8): количество сдвигов (4-битное число) case 0:
uint8_t shift_count = 0; sprintf(strPrintfDebug_UDS, " ");
shift_count |= ((seed >> 7) & 0x01) << 3; // coefficient2 (MSB) break;
shift_count |= ((seed >> 11) & 0x01) << 2; // coefficient3 case 1:
shift_count |= ((seed >> 5) & 0x01) << 1; // coefficient4 sprintf(strPrintfDebug_UDS, "%02X", data[0]);
shift_count |= ((seed >> 8) & 0x01) << 0; // coefficient5 (LSB) break;
case 2:
sprintf(strPrintfDebug_UDS, "%02X:%02X", data[0], data[1]);
break;
case 3:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X", data[0], data[1], data[2]);
break;
case 4:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X:%02X", data[0], data[1], data[2], data[3]);
break;
case 5:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X:%02X:%02X", data[0], data[1], data[2], data[3],
data[4]);
break;
case 6:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X:%02X:%02X:%02X", data[0], data[1], data[2], data[3],
data[4], data[5]);
break;
case 7:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X:%02X:%02X:%02X:%02X", data[0], data[1], data[2],
data[3], data[4],
data[5], data[6]);
break;
case 8:
sprintf(strPrintfDebug_UDS, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X ", data[0], data[1],
data[2], data[3], data[4],
data[5], data[6], data[7]);
break;
default:
sprintf(strPrintfDebug_UDS, " ");
}
// Коэффициенты 6-7 (биты 22,1): выбор операции инверсии (2 бита) }
uint8_t inversion_operation = 0;
inversion_operation |= ((seed >> 22) & 0x01) << 1; // coefficient6 (MSB)
inversion_operation |= ((seed >> 1) & 0x01) << 0; // coefficient7 (LSB)
// Коэффициенты 8-9 (биты 21,6): выбор битовой операции (2 бита)
uint8_t bitwise_operation = 0;
bitwise_operation |= ((seed >> 21) & 0x01) << 1; // coefficient8 (MSB)
bitwise_operation |= ((seed >> 6) & 0x01) << 0; // coefficient9 (LSB)
// Шаг 2: Операция вращения (циклический сдвиг) char *sendLogCanUdsHex(tCanUds *env, uint8_t *data, size_t size) {
uint32_t intermediate1; memset(env->hexString, 0, sizeof(env->hexString));
size_t len = 0;
if (shift_direction == 0) {
// Вращение влево uint8_t full = size / 8;
intermediate1 = (seed << shift_count) | (seed >> (32 - shift_count)); uint8_t tail = size % 8;
for (uint8_t i = 0; i < full; ++i) {
PrintfDebug(&data[i * 8], 8);
if ((len + strlen(strPrintfDebug_UDS)) < LEN_DEBUG_TP_BUFF) {
len += strlen(strPrintfDebug_UDS);
memcpy(env->hexString, strPrintfDebug_UDS, strlen(strPrintfDebug_UDS));
} else { } else {
// Вращение вправо return env->hexString;
intermediate1 = (seed >> shift_count) | (seed << (32 - shift_count));
} }
// Шаг 3: Операция инверсии бит
uint32_t intermediate2 = intermediate1;
switch (inversion_operation) {
case 0x00: // Нет инверсии
// Ничего не делаем
break;
case 0x01: // Операция инверсии A
intermediate2 = intermediate1 ^ INV_OP_A_MASK;
break;
case 0x02: // Операция инверсии B
intermediate2 = intermediate1 ^ INV_OP_B_MASK;
break;
case 0x03: // Операция инверсии C
intermediate2 = intermediate1 ^ INV_OP_C_MASK;
break;
default:
// Недопустимая операция - оставляем как есть
break;
} }
// Шаг 4: Финальная битовая операция if (tail > 0) {
uint32_t key; PrintfDebug(&data[full * 8], tail);
switch (bitwise_operation) { if ((len + strlen(strPrintfDebug_UDS)) < LEN_DEBUG_TP_BUFF) {
case 0x00: // Key = intermediate2 len += strlen(strPrintfDebug_UDS);
key = intermediate2; memcpy(env->hexString, strPrintfDebug_UDS, strlen(strPrintfDebug_UDS));
break; } else {
case 0x01: // Key = seed AND intermediate2 return env->hexString;
key = seed & intermediate2;
break;
case 0x02: // Key = seed XOR intermediate2
key = seed ^ intermediate2;
break;
case 0x03: // Key = seed OR intermediate2
key = seed | intermediate2;
break;
default:
// Недопустимая операция - возвращаем intermediate2
key = intermediate2;
break;
} }
return key; }
return env->hexString;
} }
bool ReceivedCan_func(void *arg, can_rx_message_type *canFrame) { bool ReceivedCan_func(void *arg, can_rx_message_type *canFrame) {
@ -156,7 +143,7 @@ static uint16_t TesterPresent_3E(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data;
if (com->service < 2) { if (env->data.len < 2) {
return setResponseError(env, UDS_TesterPresent, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_TesterPresent, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -176,7 +163,7 @@ static uint16_t TesterPresent_3E(tCanUds *env) {
static uint16_t DiagnosticSessionControl_10(tCanUds *env) { static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data;
if (com->service < 2) { if (env->data.len < 2) {
return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -203,7 +190,7 @@ static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
diagnosticSessionsType->sessionParameterRecord[2] = 0x01; diagnosticSessionsType->sessionParameterRecord[2] = 0x01;
diagnosticSessionsType->sessionParameterRecord[3] = 0xF4; diagnosticSessionsType->sessionParameterRecord[3] = 0xF4;
return 4; return 6;
} }
// конец ----------------------------- Сессия -------------------------------------------------------------- // конец ----------------------------- Сессия --------------------------------------------------------------
// конец ----------------------------- Сессия -------------------------------------------------------------- // конец ----------------------------- Сессия --------------------------------------------------------------
@ -676,7 +663,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
} }
// Отправляется, если активирован таймер задержки из-за превышения максимального числа неудачных попыток доступа // Отправляется, если активирован таймер задержки из-за превышения максимального числа неудачных попыток доступа
if (env->SA.counter_max_attempts_default > MAX_ATTEMPTS_DEFAULT) { if (env->SA.counter_max_attempts_default >= MAX_ATTEMPTS_DEFAULT) {
env->SA.time_counter_max_attempts_default = SystemGetMs(); env->SA.time_counter_max_attempts_default = SystemGetMs();
return setResponseError(env, UDS_SecurityAccess, UDS_error_exceededNumberOfAttempts); return setResponseError(env, UDS_SecurityAccess, UDS_error_exceededNumberOfAttempts);
} }
@ -684,7 +671,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
uint32_t securitySeedFromServer = uint32_t securitySeedFromServer =
(env->data.data[2] << 24) | (env->data.data[3] << 16) | (env->data.data[4] << 8) | env->data.data[5]; (env->data.data[2] << 24) | (env->data.data[3] << 16) | (env->data.data[4] << 8) | env->data.data[5];
uint32_t securitySeedMy = generate_key_from_seed(randomSecuritySeed); uint32_t securitySeedMy = generate_key(randomSecuritySeed);
if (securitySeedMy != securitySeedFromServer) { if (securitySeedMy != securitySeedFromServer) {
++env->SA.counter_max_attempts_default; ++env->SA.counter_max_attempts_default;
@ -716,13 +703,13 @@ const eUds_com uds_com[256] = {
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{DiagnosticSessionControl_10, "DiagnosticSessionControl_10"}, {DiagnosticSessionControl_10, "DiagnosticSessionControl_10"},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{NULL, ""},
{ECUReset_11, "ECUReset_11"}, {ECUReset_11, "ECUReset_11"},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
@ -976,10 +963,16 @@ void CanUds(tCanUds *env) {
if (uds_com[com].func != NULL) { if (uds_com[com].func != NULL) {
sendLogCanUdsHex(env, env->data.data, env->data.len);
LoggerFormatInfo(LOGGER, LOG_SIGN, "> %s [%d] %s", uds_com[com].desc, env->data.len, env->hexString)
uint8_t response_size = uds_com[com].func(env); uint8_t response_size = uds_com[com].func(env);
if (response_size) { if (response_size) {
sendLogCanUdsHex(env,env->dataResponse, response_size);
LoggerFormatInfo(LOGGER, LOG_SIGN, "< %s [%d] %s", uds_com[com].desc, response_size, env->hexString)
CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, env->dataResponse, CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, env->dataResponse,
response_size, PROTOCOL_CAN_ADR_UDS, WAIT_FRAME_WRITE); response_size, PROTOCOL_CAN_ADR_UDS, WAIT_FRAME_WRITE);
} }
@ -1013,12 +1006,12 @@ void CanUds_Init(
env->CanIO = CanIO; env->CanIO = CanIO;
env->deviceStorage = deviceStorage; env->deviceStorage = deviceStorage;
env->Diagnostic = Diagnostic; env->Diagnostic = Diagnostic;
env->filterIdCount = 0; env->filterIdCount = 2;
env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL); env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL);
env->filterReqId[0] = 0; env->filterReqId[0] = Diag_To_CCU_CANID;
env->filterReqId[1] = 0; env->filterReqId[1] = Diag_Functional_CANID;
env->filterReqId[2] = 0; env->filterReqId[2] = 0;
env->filterReqId[3] = 0; env->filterReqId[3] = 0;
env->filterReqId[4] = 0; env->filterReqId[4] = 0;

View File

@ -14,6 +14,8 @@
#define MAX_ATTEMPTS_DEFAULT 3 #define MAX_ATTEMPTS_DEFAULT 3
#define BLOCK_TIME_DEFAULT 60000 #define BLOCK_TIME_DEFAULT 60000
#define LEN_DEBUG_UDS_BUFF 128
// Время (логарифмическая шкала) // Время (логарифмическая шкала)
// │ // │
// ├── StMin (0.1-127 мс) ← Между КАДРАМИ // ├── StMin (0.1-127 мс) ← Между КАДРАМИ
@ -136,6 +138,7 @@ typedef struct {
uint32_t filterRespId[16]; uint32_t filterRespId[16];
uint8_t filterDirReq[16]; uint8_t filterDirReq[16];
char hexString[LEN_DEBUG_UDS_BUFF];
eUdsSession currentSession; eUdsSession currentSession;