Обновление
This commit is contained in:
parent
a2b34302c2
commit
0161dd96c5
182
CanUds.c
182
CanUds.c
|
|
@ -66,7 +66,7 @@ static void PrintfDebug(uint8_t *data, uint8_t dlc) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSecurityAccessDenied(tCanUds *env, tPermissionSession isPermissionSession) {
|
static bool isSecurityAccessDenied(tCanUds *env, tPermissionSession isPermissionSession) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
switch (isPermissionSession) {
|
switch (isPermissionSession) {
|
||||||
|
|
@ -234,6 +234,12 @@ static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
|
||||||
return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_programmingSession) &&
|
||||||
|
(com->sub_function == UDS_session_extendedDiagnosticSession)) {
|
||||||
|
return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (env->currentSession != com->sub_function) {
|
if (env->currentSession != com->sub_function) {
|
||||||
|
|
||||||
env->currentSession = com->sub_function;
|
env->currentSession = com->sub_function;
|
||||||
|
|
@ -279,10 +285,14 @@ static uint16_t ReadDataByIdentifier_22(tCanUds *env) {
|
||||||
if (uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].data != NULL) {
|
if (uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
|
||||||
// if (uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].isPermissionSession != NULL) {
|
if (!isSecurityAccessDenied(env,
|
||||||
//
|
uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].isPermissionSession)) {
|
||||||
// }
|
return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t response_size = uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].size;
|
uint16_t response_size = uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].size;
|
||||||
|
|
@ -293,6 +303,7 @@ static uint16_t ReadDataByIdentifier_22(tCanUds *env) {
|
||||||
memcpy(&env->dataResponse[3], uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].data, response_size);
|
memcpy(&env->dataResponse[3], uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].data, response_size);
|
||||||
|
|
||||||
return response_size + 3;
|
return response_size + 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -300,6 +311,16 @@ static uint16_t ReadDataByIdentifier_22(tCanUds *env) {
|
||||||
if (dataIdentifier_hi == 0xF1) {
|
if (dataIdentifier_hi == 0xF1) {
|
||||||
|
|
||||||
if (uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].data != NULL) {
|
if (uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
if (!isSecurityAccessDenied(env,
|
||||||
|
uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].isPermissionSession)) {
|
||||||
|
return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t response_size = uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].size;
|
uint16_t response_size = uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].size;
|
||||||
|
|
||||||
env->dataResponse[0] = UDS_ReadDataByIdentifier | 0b1000000;
|
env->dataResponse[0] = UDS_ReadDataByIdentifier | 0b1000000;
|
||||||
|
|
@ -335,6 +356,18 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
|
||||||
if (dataIdentifier_hi == 0xCF) {
|
if (dataIdentifier_hi == 0xCF) {
|
||||||
|
|
||||||
if (uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].data != NULL) {
|
if (uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
|
||||||
|
if (!isSecurityAccessDenied(env,
|
||||||
|
uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].isPermissionSession)) {
|
||||||
|
return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t size = uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].size;
|
uint16_t size = uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].size;
|
||||||
|
|
||||||
if (env->data.len != size + 3) {
|
if (env->data.len != size + 3) {
|
||||||
|
|
@ -356,6 +389,17 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
|
||||||
if (dataIdentifier_hi == 0xF1) {
|
if (dataIdentifier_hi == 0xF1) {
|
||||||
|
|
||||||
if (uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].data != NULL) {
|
if (uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
if (!isSecurityAccessDenied(env,
|
||||||
|
uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].isPermissionSession)) {
|
||||||
|
return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t size = uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].size;
|
uint16_t size = uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].size;
|
||||||
|
|
||||||
if (env->data.len != size + 3) {
|
if (env->data.len != size + 3) {
|
||||||
|
|
@ -400,12 +444,21 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
|
||||||
|
|
||||||
if ((env->data.data[3] != UDS_io_returnControlToECU) &&
|
if ((env->data.data[3] != UDS_io_returnControlToECU) &&
|
||||||
(env->data.data[3] != UDS_io_shortTermAdjustment)) {
|
(env->data.data[3] != UDS_io_shortTermAdjustment)) {
|
||||||
return setResponseError(env, UDS_ECUResetService, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataIdentifier_hi == 0xCF) {
|
if (dataIdentifier_hi == 0xCF) {
|
||||||
|
|
||||||
if (uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data != NULL) {
|
if (uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
if (!isSecurityAccessDenied(env, uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].isPermissionSession)) {
|
||||||
|
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t size = uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].size;
|
uint16_t size = uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].size;
|
||||||
|
|
||||||
if ((env->data.data[3] == UDS_io_shortTermAdjustment) && (env->data.len != size + 4)) {
|
if ((env->data.data[3] == UDS_io_shortTermAdjustment) && (env->data.len != size + 4)) {
|
||||||
|
|
@ -427,6 +480,16 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
|
||||||
if (dataIdentifier_hi == 0xF1) {
|
if (dataIdentifier_hi == 0xF1) {
|
||||||
|
|
||||||
if (uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].data != NULL) {
|
if (uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].data != NULL) {
|
||||||
|
|
||||||
|
|
||||||
|
if (!isSecurityAccessDenied(env, uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].isPermissionSession)) {
|
||||||
|
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].isSecurity) && (!env->SA.stateSecurityAccess)) {
|
||||||
|
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t size = uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].size;
|
uint16_t size = uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].size;
|
||||||
|
|
||||||
if (env->data.len != size + 4) {
|
if (env->data.len != size + 4) {
|
||||||
|
|
@ -465,10 +528,16 @@ static uint16_t ECUReset_11(tCanUds *env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((com->sub_function != UDS_reset_hardReset) &&
|
if ((com->sub_function != UDS_reset_hardReset) &&
|
||||||
(com->sub_function != UDS_reset_softReset)) {
|
(com->sub_function != UDS_reset_softReset) &&
|
||||||
|
(com->sub_function != UDS_reset_rapidReset)) {
|
||||||
return setResponseError(env, UDS_ECUResetService, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_ECUResetService, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_programmingSession) &&
|
||||||
|
((com->sub_function == UDS_reset_softReset) || (com->sub_function == UDS_reset_rapidReset))) {
|
||||||
|
return setResponseError(env, UDS_ECUResetService, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
env->dataResponse[0] = UDS_ECUResetService | 0b1000000;;
|
env->dataResponse[0] = UDS_ECUResetService | 0b1000000;;
|
||||||
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function
|
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function
|
||||||
|
|
||||||
|
|
@ -490,6 +559,10 @@ static uint16_t UDS_ClearDiagnosticInformation_14(tCanUds *env) {
|
||||||
UDS_error_incorrectMessageLengthOrInvalidFormat);
|
UDS_error_incorrectMessageLengthOrInvalidFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->currentSession == UDS_session_programmingSession) {
|
||||||
|
return setResponseError(env, UDS_ClearDiagnosticInformation, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ClearDiagnosticInformation_14, NULL);
|
SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ClearDiagnosticInformation_14, NULL);
|
||||||
|
|
||||||
env->dataResponse[0] = UDS_ClearDiagnosticInformation | 0b1000000;
|
env->dataResponse[0] = UDS_ClearDiagnosticInformation | 0b1000000;
|
||||||
|
|
@ -517,6 +590,10 @@ static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
|
||||||
return setResponseError(env, UDS_ReadDTCInformation, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_ReadDTCInformation, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->currentSession == UDS_session_programmingSession) {
|
||||||
|
return setResponseError(env, UDS_ReadDTCInformation, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t response_size = 0;
|
uint16_t response_size = 0;
|
||||||
|
|
||||||
env->dataResponse[0] = UDS_ReadDTCInformation | 0b1000000;
|
env->dataResponse[0] = UDS_ReadDTCInformation | 0b1000000;
|
||||||
|
|
@ -577,6 +654,13 @@ static uint16_t CommunicationControl_28(tCanUds *env) {
|
||||||
return setResponseError(env, UDS_Communication_Control, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_Communication_Control, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_programmingSession)) {
|
||||||
|
return setResponseError(env, UDS_Communication_Control, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (com->sub_function == UDS_sub_enableRxAndTx) {
|
if (com->sub_function == UDS_sub_enableRxAndTx) {
|
||||||
set_CCU_Mute(env->canSpamTransmitter, false);
|
set_CCU_Mute(env->canSpamTransmitter, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -612,6 +696,11 @@ static uint16_t ControlDTCSetting_85(tCanUds *env) {
|
||||||
return setResponseError(env, UDS_ControlDTCSetting, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_ControlDTCSetting, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_programmingSession)) {
|
||||||
|
return setResponseError(env, UDS_ControlDTCSetting, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
if (com->sub_function == UDS_sub_dtc_on) {
|
if (com->sub_function == UDS_sub_dtc_on) {
|
||||||
setNoBitsDTC(env->Diagnostic, false);
|
setNoBitsDTC(env->Diagnostic, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -756,18 +845,83 @@ static uint16_t Routine_Control_31(tCanUds *env) {
|
||||||
env->dataResponse[3] = routineIdentifier_lo;
|
env->dataResponse[3] = routineIdentifier_lo;
|
||||||
|
|
||||||
switch (routineIdentifier) {
|
switch (routineIdentifier) {
|
||||||
case Check_Programming_Preconditions:
|
case Check_Programming_Preconditions: {
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_programmingSession)) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_check_Programming_Preconditions(env, udsRoutineControlType);
|
return vUDS_check_Programming_Preconditions(env, udsRoutineControlType);
|
||||||
case UDS_routine_VIN_learn:
|
}
|
||||||
|
case UDS_routine_VIN_learn: {
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_programmingSession)) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_routine_VIN_learn(env, udsRoutineControlType);
|
return vUDS_routine_VIN_learn(env, udsRoutineControlType);
|
||||||
case UDS_routine_Compare_Checksum:
|
}
|
||||||
|
case UDS_routine_Compare_Checksum: {
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_extendedDiagnosticSession)) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_routine_Compare_Checksum(env, udsRoutineControlType);
|
return vUDS_routine_Compare_Checksum(env, udsRoutineControlType);
|
||||||
case UDS_routine_Erase_Memory:
|
}
|
||||||
|
case UDS_routine_Erase_Memory: {
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_extendedDiagnosticSession)) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_routine_Erase_Memory(env, udsRoutineControlType);
|
return vUDS_routine_Erase_Memory(env, udsRoutineControlType);
|
||||||
case UDS_routine_Check_Programming_Dependancies:
|
}
|
||||||
|
case UDS_routine_Check_Programming_Dependancies: {
|
||||||
|
|
||||||
|
if (env->currentSession == UDS_session_extendedDiagnosticSession) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_routine_Check_Programming_Dependancies(env, udsRoutineControlType);
|
return vUDS_routine_Check_Programming_Dependancies(env, udsRoutineControlType);
|
||||||
case UDS_routine_eComp_Initialize:
|
}
|
||||||
|
case UDS_routine_eComp_Initialize: {
|
||||||
|
|
||||||
|
if ((env->currentSession == UDS_session_defaultSession) ||
|
||||||
|
(env->currentSession == UDS_session_programmingSession)) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env->SA.stateSecurityAccess) {
|
||||||
|
return setResponseError(env, UDS_RoutineControl, UDS_error_securityAccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
return vUDS_routine_eComp_Initialize(env, udsRoutineControlType);
|
return vUDS_routine_eComp_Initialize(env, udsRoutineControlType);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return setResponseError(env, UDS_RoutineControl, UDS_error_requestOutOfRange);
|
return setResponseError(env, UDS_RoutineControl, UDS_error_requestOutOfRange);
|
||||||
}
|
}
|
||||||
|
|
@ -795,6 +949,10 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
|
||||||
return setResponseError(env, UDS_SecurityAccess, UDS_error_sub_functionNotSupported);
|
return setResponseError(env, UDS_SecurityAccess, UDS_error_sub_functionNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->currentSession == UDS_session_defaultSession) {
|
||||||
|
return setResponseError(env, UDS_SecurityAccess, UDS_error_conditionsNotCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
// Отправляется, если таймер задержки активен и получен запрос
|
// Отправляется, если таймер задержки активен и получен запрос
|
||||||
if ((env->SA.time_counter_max_attempts_default > 0) &&
|
if ((env->SA.time_counter_max_attempts_default > 0) &&
|
||||||
(SystemGetMs() - env->SA.time_counter_max_attempts_default) < BLOCK_TIME_DEFAULT) {
|
(SystemGetMs() - env->SA.time_counter_max_attempts_default) < BLOCK_TIME_DEFAULT) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue