From 19e6260ed378543adad4e0f0f81c81938a177eb5 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 2 Jun 2025 14:32:56 +0300 Subject: [PATCH] Init --- CarPositionUpdate.c | 99 ++ CarPositionUpdate.h | 21 + EgtsEbu.c | 721 ++++++++++++++ EgtsEbu.h | 28 + EgtsFirmware.c | 163 ++++ EgtsFirmware.h | 9 + EgtsInputCommands.c | 502 ++++++++++ EgtsInputCommands.h | 60 ++ EgtsOutputCommands.c | 797 ++++++++++++++++ EgtsOutputCommands.h | 188 ++++ EgtsProcessing.c | 1807 ++++++++++++++++++++++++++++++++++++ EgtsProcessing.h | 357 +++++++ EgtsTeledataPoint.c | 828 +++++++++++++++++ EgtsTeledataPoint.h | 16 + EgtsTeledataStoragePoint.c | 313 +++++++ EgtsTeledataStoragePoint.h | 17 + EgtsTelesataTypes.h | 258 +++++ EgtsUpdateFirmware.c | 320 +++++++ EgtsUpdateFirmware.h | 27 + Network.c | 119 +++ Network.h | 11 + modular.json | 18 + 22 files changed, 6679 insertions(+) create mode 100644 CarPositionUpdate.c create mode 100644 CarPositionUpdate.h create mode 100644 EgtsEbu.c create mode 100644 EgtsEbu.h create mode 100644 EgtsFirmware.c create mode 100644 EgtsFirmware.h create mode 100644 EgtsInputCommands.c create mode 100644 EgtsInputCommands.h create mode 100644 EgtsOutputCommands.c create mode 100644 EgtsOutputCommands.h create mode 100644 EgtsProcessing.c create mode 100644 EgtsProcessing.h create mode 100644 EgtsTeledataPoint.c create mode 100644 EgtsTeledataPoint.h create mode 100644 EgtsTeledataStoragePoint.c create mode 100644 EgtsTeledataStoragePoint.h create mode 100644 EgtsTelesataTypes.h create mode 100644 EgtsUpdateFirmware.c create mode 100644 EgtsUpdateFirmware.h create mode 100644 Network.c create mode 100644 Network.h create mode 100644 modular.json diff --git a/CarPositionUpdate.c b/CarPositionUpdate.c new file mode 100644 index 0000000..c27f443 --- /dev/null +++ b/CarPositionUpdate.c @@ -0,0 +1,99 @@ +// +// Created by cfif on 16.05.2024. +// +#include "CarPositionUpdate.h" +#include "math.h" +#include "stdlib.h" +#include "SystemDelayInterface.h" +#include "EgtsOutputCommands.h" + +#define LOG_SIGN "EGTS MOVE" +#define LOGGER &env->slog->logger + +static double nmeaLocationToDeg(double dec) { + double _dec = dec; + int deg = (int) (_dec / 100); + int min = (int) (_dec) - (deg * 100); + + double sec = (double) (_dec - min - 100 * deg) * 60.0; + + return deg + min / 60.0 + sec / 3600.0; +} + +void CarEventResetPosition(tEgtsProcessing *env) { + env->carEventPosition.carPosition = CAR_POSITION_FIX; +} + +void CarEventMovingPosition(tEgtsProcessing *env) { + env->carEventPosition.carPosition = CAR_POSITION_MOVE; + + env->carEventPosition.timerMoving = CAR_EVENT_TIME_MOVING; + env->carEventPosition.isTimerMoving = true; +} + +bool isMovingSpeed(tEgtsProcessing *env, uint16_t speed) { + + for (uint8_t i = 0; i < CAR_POINT_COUNT_SPEED; ++i) { + if (env->carEventPosition.dataSpeed[i] < speed) + return false; + } + + return true; +} + +void CarEventPosition(tEgtsProcessing *env, tNmeaRmc *position, uint16_t totalSpeed) { + + if (env->carEventPosition.isTimerMoving) { + if (env->carEventPosition.timerMoving < SystemGetMs()) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс признака движения") + env->carEventPosition.isTimerMoving = false; + CarEventResetPosition(env); + } + } + + if (position->status != 'A') + return; + + if (env->egtsPointEnv.timeOutCheckTeledata_TimeSpeedUpdate < SystemGetMs()) { + + env->egtsPointEnv.timeOutCheckTeledata_TimeSpeedUpdate = SystemGetMs() + CAR_EVENT_TIME_SPEED; + + env->carEventPosition.dataSpeed[env->carEventPosition.dataSpeedStep] = totalSpeed; + ++env->carEventPosition.dataSpeedStep; + + if (env->carEventPosition.dataSpeedStep >= CAR_POINT_COUNT_SPEED) { + env->carEventPosition.dataSpeedStep = 0; + } + } + + if (isMovingSpeed(env, CAR_TRESHOLD_DETECT_SPEED)) { + CarEventMovingPosition(env); + } + + + // Установка точки отсчета + if (env->carEventPosition.stopPositionLimitTime < SystemGetMs()) { + + env->carEventPosition.beginPosition.location.latitude = nmeaLocationToDeg(position->location.latitude); + env->carEventPosition.beginPosition.location.longitude = nmeaLocationToDeg(position->location.longitude); + + env->carEventPosition.stopPositionLimitTime = SystemGetMs() + CAR_EVENT_TIME_DISTANCE; + } + + env->carEventPosition.movePosition.location.latitude = nmeaLocationToDeg(position->location.latitude); + env->carEventPosition.movePosition.location.longitude = nmeaLocationToDeg(position->location.longitude); + + double latDistance = fabs(env->carEventPosition.movePosition.location.latitude - + env->carEventPosition.beginPosition.location.latitude); + double lonDistance = fabs(env->carEventPosition.movePosition.location.longitude - + env->carEventPosition.beginPosition.location.longitude); + + double x = latDistance * 0.1; + double y = lonDistance * 0.1; + double move = sqrt(x * x + y * y); + + if ((uint32_t) move > CAR_EVENT_DISTANCE) { + CarEventMovingPosition(env); + } + +} \ No newline at end of file diff --git a/CarPositionUpdate.h b/CarPositionUpdate.h new file mode 100644 index 0000000..76f24a9 --- /dev/null +++ b/CarPositionUpdate.h @@ -0,0 +1,21 @@ +// +// Created by cfif on 16.05.2024. +// + +#ifndef SMART_COMPONENTS_CARPOSITIONUPDATE_H +#define SMART_COMPONENTS_CARPOSITIONUPDATE_H +#include "EgtsProcessing.h" + +#define CAR_EVENT_TIME_DISTANCE 40000 +#define CAR_EVENT_TIME_MOVING 10000 +#define CAR_EVENT_DISTANCE 25 + + +#define CAR_EVENT_TIME_SPEED 1100 +#define CAR_TRESHOLD_DETECT_SPEED 10 +#define CAR_POINT_COUNT_SPEED 3 + +void CarEventPosition(tEgtsProcessing *env, tNmeaRmc *position, uint16_t totalSpeed); +void CarEventResetPosition(tEgtsProcessing *env); + +#endif //SMART_COMPONENTS_CARPOSITIONUPDATE_H diff --git a/EgtsEbu.c b/EgtsEbu.c new file mode 100644 index 0000000..cb6afca --- /dev/null +++ b/EgtsEbu.c @@ -0,0 +1,721 @@ +// +// Created by cfif on 13.06.2024. +// +#include "EgtsEbu.h" +#include "string.h" +#include "lfs_file_utils.h" +#include "EgtsOutputCommands.h" +#include "ext_telematica.h" +#include "SystemDelayInterface.h" +#include "Rtc.h" +#include "FirmwareMetadataSection.h" +#include "ld_adr.h" + +#define LOG_SIGN "EGTS_EBU" +#define LOGGER &env->slog->logger + +#define ADD_TO_DATA_CHAR_SHORT(DATA) *(uint8_t *) (out + offset) = DATA; *(uint8_t *) (out + offset + 1) = 0; offset+=2; +#define ADD_TO_DATA_SHORT(DATA) *(uint8_t *) (out + offset) = (uint8_t)DATA; *(uint8_t *) (out + offset + 1) = (uint8_t)(DATA >> 8); offset+=2; +#define ADD_TO_DATA_BYTE(DATA) *(uint8_t *) (out + offset) = (uint8_t)DATA; offset+=1; +#define ADD_TO_DATA(DATA, LEN) memcpy(out + offset, (uint8_t * ) & DATA, LEN); offset+=LEN; + +extern tFirmwareLoader FIRMWARE_TELE_LOADER; +extern tFirmwareLoader FIRMWARE_LOADER; + + +const tEgtsEbuName egtsEbuName[EBU_COUNT_TABLE_ITEMS] = { + {EBU_GNSS, "GNSS~UAZ", 0x0000, 0x0000, 0x0000, {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + + {EBU_ABS, "ABS~UAZ1APG", TESTER_REQUEST_ABS_ESP, TESTER_RESPONSE_ABS_ESP, 0x4000, {0xF187, 0xF18A, 0xF18C, 0xF190, 0xF193, 0xF195, 0xF197, 0xF199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + {EBU_ABS, "ABS~UAZ1TRINOVA", TESTER_REQUEST_ABS_ESP, TESTER_RESPONSE_ABS_ESP, 0x0200, {0xF112, 0xF180, 0xF183, 0xF187, 0xF189, 0xF18A, 0xF18B, 0xF18C, 0xF190, 0xF192, 0xF193, 0xF194, 0xF195, 0xF197, 0xF198, 0xF199, 0xF19D, 0x0000}}, + + {EBU_ECM, "ECM~UAZ1ITL", TESTER_REQUEST_ECM, TESTER_RESPONSE_ECM, 0x0090, {0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x00A1, 0x00A2, 0x00A3, 0x0000, 0x0000, 0x0000, 0x0000}}, + {EBU_ECM, "ECM~UAZ1DPLUS", TESTER_REQUEST_ECM, TESTER_RESPONSE_ECM, 0xF187, {0xF187, 0xF189, 0xF18A, 0xF18B, 0xF18C, 0xF190, 0xF192, 0xF193, 0xF194, 0xF195, 0xF197, 0xF198, 0xF199, 0xF19D, 0xF1F9, 0x0000, 0x0000, 0x0000}}, + + {EBU_HVAC, "HVAC~UAZ1", TESTER_REQUEST_HVAC, TESTER_RESPONSE_HVAC, 0xF112, {0xF112, 0xF122, 0xF132, 0xF150, 0xF151, 0xF153, 0xF18C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + + {EBU_IMMO, "IMMO~UAZ1ITL", TESTER_REQUEST_ITELMA_IMMO_D, TESTER_RESPONSE_ITELMA_IMMO_D, 0x0000, {0x0007, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + {EBU_IMMO, "IMMO~UAZ1DPLUS", TESTER_REQUEST_IMMO_D, TESTER_RESPONSE_IMMO_D, 0x0000, {0xF190, 0xF193, 0xF195, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}}, + + {EBU_PTS, "PTS~UAZ1ABIX", TESTER_REQUEST_PTS, TESTER_RESPONSE_PTS, 0xF183, {0xF183, 0xF184, 0xF18E, 0xF190, 0xF191, 0xF199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}} + +}; + +const tEgtsEbuTestName egtsEbuTestName[EBU_COUNT_TEST_ITEMS] = { + {TEST_FIRMWARE, "FIRMWARE"}, + {TEST_IGNITION, "IGNITION"}, + {TEST_BAT_CONNECT, "BAT_CONNECT"}, + {TEST_BAT_CHARGE, "BAT_CHARGE"}, + {TEST_BAT_VOLTAGE, "BAT_VOLTAGE"}, + {TEST_GNSS_ANT, "GNSS_ANT"}, + {TEST_SPEAKER_CONNECT, "SPEAKER_CONNECT"}, + {TEST_BIP_CONNECT, "BIP_CONNECT"}, + {TEST_ACCEL, "ACCEL"}, + {TEST_GSM, "GSM"}, + {TEST_AUDIO_CODEC, "AUDIO_CODEC"}, + {TEST_VIN, "VIN"}, + {TEST_ACCEL_CALIB, "ACCEL_CALIB"}, + {TEST_EOL, "EOL"}, + {TEST_MODEM_SOFT_REV, "MODEM_SOFT_REV"}, + {TEST_CERT_REV, "MODEM_CERT_REV"}, + {TEST_AUDIO_FILE, "MODEM_AUDIO_FILE"}, + {TEST_AMPLIFIER, "AMPLIFIER"}, + {TEST_SIM_ERA, "SIM_ERA"}, + {TEST_SIM_COMERS, "SIM_COMERS"} +}; + +bool addEbuTableItem(tEgtsProcessing *env, tEgtsEbuState *ebuState, tEgtsEbuItemState *ebuItemState) { + + if (ebuState->count >= EBU_COUNT_FS_ITEMS) + return false; + + ebuState->ebuItemState[ebuState->count].ebu = ebuItemState->ebu; + ebuState->ebuItemState[ebuState->count].timestamp = ebuItemState->timestamp; + ++ebuState->count; + + return true; +} + +void setUpdateEbuAll(tEgtsProcessing *env, tEgtsEbuState *ebuState) { + if (osMutexAcquire(env->accessEbu, 2000) == osOK) { + + for (uint16_t i = 0; i < ebuState->count; ++i) { + if (ebuState->ebuItemState[i].ebu == i) { + ebuState->ebuItemState[i].timestamp = 0; + } + } + + dumpEbuTable(env); + + osMutexRelease(env->accessEbu); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа setUpdateEbu") + } +} + +void setUpdateEbu(tEgtsProcessing *env, tEgtsEbuState *ebuState, eEgtsEbu egtsEbu, uint32_t state) { + if (osMutexAcquire(env->accessEbu, 2000) == osOK) { + + for (uint16_t i = 0; i < ebuState->count; ++i) { + if (ebuState->ebuItemState[i].ebu == egtsEbu) { + ebuState->ebuItemState[i].timestamp = state; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Состояние ЭБУ найдено") + dumpEbuTable(env); + break; + } + } + + osMutexRelease(env->accessEbu); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа setUpdateEbu") + } +} + +void setUpdateEbuClearDTC(tEgtsProcessing *env, tEgtsEbuState *ebuState, eEgtsEbu egtsEbu, bool clearDTC) { + if (osMutexAcquire(env->accessEbu, 2000) == osOK) { + + for (uint16_t i = 0; i < ebuState->count; ++i) { + if (ebuState->ebuItemState[i].ebu == egtsEbu) { + ebuState->ebuItemState[i].clearDTC = clearDTC; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Состояние ЭБУ найдено") + break; + } + } + + osMutexRelease(env->accessEbu); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа setUpdateEbuClearDTC") + } +} + +bool dumpEbuTable(tEgtsProcessing *env) { + bool isMain = true; + + env->ebuState.version = VERSION_EBU; + uint32_t crc = lfs_crc(0, &env->ebuState, sizeof(env->ebuState) - sizeof(env->ebuState.crc)); + env->ebuState.crc = crc; + + int lfs_err = dumpEbuFile(&env->fs->lfs, "ebu.bin", &env->ebuState, sizeof(tEgtsEbuState)); + + if (lfs_err != LFS_ERR_OK) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Сохранение состояния ЭБУ - ошибка"); + isMain = false; + } + + if (!isMain) + return false; + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Сохранение состояния ЭБУ - успешно"); + return true; +} + +bool loadEbuTable(tEgtsProcessing *env) { + + bool crc_main = false; + + int lfs_err = loadEbuFile(&env->fs->lfs, "ebu.bin", &env->ebuState, sizeof(tEgtsEbuState)); + + if (lfs_err == LFS_ERR_OK) { + uint32_t crc = lfs_crc(0, &env->ebuState, sizeof(tEgtsEbuState) - sizeof(env->ebuState.crc)); + + if (crc == env->ebuState.crc) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Загрузка состояния ЭБУ - успешно"); + crc_main = true; + } else { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Загрузка состояния ЭБУ - ошибка контрольной суммы"); + } + } + + if ((!crc_main) || (env->ebuState.count == 0) || (env->ebuState.version != VERSION_EBU)) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Загрузка состояния ЭБУ - восстановление значений по умолчанию"); + + tEgtsEbuItemState egtsEbuItemState; + egtsEbuItemState.timestamp = 0; + + for (uint16_t i = 0; i < EBU_COUNT_FS_ITEMS; ++i) { + egtsEbuItemState.ebu = i; + addEbuTableItem(env, &env->ebuState, &egtsEbuItemState); + } + + dumpEbuTable(env); + } + + return true; +} + +bool setEgtsNameEbu(tEgtsProcessing *env, uint8_t ebu) { + + if (ebu >= EBU_COUNT_TABLE_ITEMS) + return false; + + env->egtsFirmwareDataArgs.module[0] = '\0'; + strcat(env->egtsFirmwareDataArgs.module, egtsEbuName[ebu].ebuName); + + return true; +/* + for (uint8_t i = 0; i < EBU_COUNT_TABLE_ITEMS; ++i) { + if (egtsEbuName[i].ebu == ebu) { + env->egtsFirmwareDataArgs.module[0] = '\0'; + strcat(env->egtsFirmwareDataArgs.module, egtsEbuName[i].ebuName); + return true; + } + } + + return false; +*/ +} + +void clearResultTest() { + + for (uint16_t i = 0; i < EXT_ENV_TELE.testsTable->count; ++i) { + EXT_ENV_TELE.testsTable->items[i].resultFix = 0; + } + +} + +bool isCertTest() { + for (uint16_t i = 0; i < EXT_ENV_TELE.testsTable->count; ++i) { + if (memcmp(EXT_ENV_TELE.testsTable->items[i].name.str, "MODEM_CERT_REV", + EXT_ENV_TELE.testsTable->items[i].name.length) == 0) { + + if (EXT_ENV_TELE.testsTable->items[i].resultFix == DEVICE_TESTING_CODE_PASSED) { + return true; + } else { + return false; + } + + } + } + + return false; +} + +eEgtsTestEbu getResultTest(uint8_t indexTest, eDeviceTestingCode *deviceTestingCode) { + + /** + * todo: Есть риск коллизии + * Потенциальная ситуация (пример) + * memcmp("ACCEL", "ACCEL_CALIB",5(длинна "ACCEL") ) вернет 0 + */ + for (uint16_t i = 0; i < EBU_COUNT_TEST_ITEMS; ++i) { + if (memcmp(EXT_ENV_TELE.testsTable->items[indexTest].name.str, egtsEbuTestName[i].ebuTestName, + EXT_ENV_TELE.testsTable->items[indexTest].name.length) == 0) { + *deviceTestingCode = EXT_ENV_TELE.testsTable->items[indexTest].resultFix; + return egtsEbuTestName[i].ebu; + } + + } + + return 0xFF; +} + +uint16_t SetEbuDTCerror(tEgtsProcessing *env, uint8_t *out, uint16_t offset, eUdsErrorDTC codeError) { + ADD_TO_DATA_BYTE(UDS_DTC_Error[codeError].DTCHighByte) + ADD_TO_DATA_BYTE(UDS_DTC_Error[codeError].DTCMiddleByte) + ADD_TO_DATA_BYTE(UDS_DTC_Error[codeError].DTCLowByte) + ADD_TO_DATA_BYTE(0x01) + + return offset; +} + + +void getMetaDataUveos(tString32 *FW_NAME, tString32 *HW_NAME, tString32 *FW_INTERFACE) { + memset(FW_NAME, 0, sizeof(tString32)); + memset(HW_NAME, 0, sizeof(tString32)); + memset(FW_INTERFACE, 0, sizeof(tString32)); + + uint32_t offsetMeta = 0x08000000 + BOOT_AREA_LENGTH + FIRMWARE_MAIN_AREA_LENGTH - 256; + + uint32_t pos = offsetMeta; + uint32_t offsetMetaCrc = (*(uint32_t *) pos); + pos += 4; + uint32_t offsetMetaSize = (*(uint32_t *) (pos)); + pos += 4; + + // FW + FW_NAME->length = (*(uint8_t *) (pos)); + pos += 1; + + if (FW_NAME->length > 32) { + FW_NAME->length = 0; + return; + } + + memcpy(FW_NAME->data, (uint8_t *) (pos), FW_NAME->length); + pos += FW_NAME->length; + + // HW + HW_NAME->length = (*(uint8_t *) (pos)); + pos += 1; + + if (HW_NAME->length > 32) { + HW_NAME->length = 0; + return; + } + + memcpy(HW_NAME->data, (uint8_t *) (pos), HW_NAME->length); + pos += HW_NAME->length; + + // FW_INTERFACE + FW_INTERFACE->length = (*(uint8_t *) (pos)); + pos += 1; + + if (FW_INTERFACE->length > 32) { + FW_INTERFACE->length = 0; + return; + } + + memcpy(FW_INTERFACE->data, (uint8_t *) (pos), FW_INTERFACE->length); + pos += FW_INTERFACE->length; + +} + +void setBufEbu(tEgtsProcessing *env) { + uint16_t offset = 0; + uint8_t *out = env->egtsFirmwareDataArgs.bufEbu; + + // начало------------------------------------------Ошибки----------------------------------------------------------- + ADD_TO_DATA_SHORT(0x1902) + ADD_TO_DATA_SHORT(0x0004) + ADD_TO_DATA_BYTE(0xFF) + ADD_TO_DATA_BYTE(0x00) + ADD_TO_DATA_BYTE(0x00) + ADD_TO_DATA_BYTE(0xE0) + + for (uint16_t i = 0; i < EXT_ENV_TELE.testsTable->count; ++i) { + + eDeviceTestingCode deviceTestingCode; + eEgtsTestEbu egtsTestEbu = getResultTest(i, &deviceTestingCode); + + if (egtsTestEbu == TEST_FIRMWARE) { + // DEVICE_TESTING_CODE_ERROR + } + + if (egtsTestEbu == TEST_IGNITION) { + // DEVICE_TESTING_CODE_ERROR + } + + if (egtsTestEbu == TEST_BAT_CONNECT) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_BAT_CONNECT); + } + + if (egtsTestEbu == TEST_BAT_CHARGE) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_BAT_CHARGE); + } + + if (egtsTestEbu == TEST_BAT_VOLTAGE) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_BAT_VOLTAGE); + } + + if (egtsTestEbu == TEST_GNSS_ANT) { + // DEVICE_TESTING_CODE_ERROR + // DEVICE_TESTING_CODE_NOT_CONNECTED + // DEVICE_TESTING_CODE_SHORT_CIRCUIT + if ((deviceTestingCode == DEVICE_TESTING_CODE_ERROR) || + (deviceTestingCode == DEVICE_TESTING_CODE_NOT_CONNECTED) || + (deviceTestingCode == DEVICE_TESTING_CODE_SHORT_CIRCUIT)) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_GNSS_ANT); + } + + if (egtsTestEbu == TEST_SPEAKER_CONNECT) { + // DEVICE_TESTING_CODE_ERROR + // DEVICE_TESTING_CODE_NOT_CONNECTED + if ((deviceTestingCode == DEVICE_TESTING_CODE_ERROR) || + (deviceTestingCode == DEVICE_TESTING_CODE_NOT_CONNECTED)) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_SPEAKER_CONNECT); + + } + + if (egtsTestEbu == TEST_BIP_CONNECT) { + if (deviceTestingCode == DEVICE_TESTING_CODE_NOT_CONNECTED) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_MICROPHONE_CONNECT); + } + + if (egtsTestEbu == TEST_ACCEL) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_ACCEL); + } + + if (egtsTestEbu == TEST_GSM) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_GSM); + } + + + if (egtsTestEbu == TEST_AUDIO_CODEC) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_GSM_AUDIO_CODEC); + } + + if (egtsTestEbu == TEST_VIN) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_VIN); + } + + if (egtsTestEbu == TEST_ACCEL_CALIB) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_ACCEL_CALIB); + } + + if (egtsTestEbu == TEST_EOL) { + // DEVICE_TESTING_CODE_ERROR +// if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) +// offset = SetEbuDTCerror(env, out, offset, UDS_TEST_EOL); + } + + if (egtsTestEbu == TEST_MODEM_SOFT_REV) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_MODEM_SOFT_REV); + } + + if (egtsTestEbu == TEST_CERT_REV) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_CERT_REV); + } + + if (egtsTestEbu == TEST_AUDIO_FILE) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_AUDIO_FILE); + } + + + if (egtsTestEbu == TEST_AMPLIFIER) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_AMPLIFIER); + } + + + if (egtsTestEbu == TEST_SIM_ERA) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_SIM_ERA); + } + + if (egtsTestEbu == TEST_SIM_COMERS) { + // DEVICE_TESTING_CODE_ERROR + if (deviceTestingCode == DEVICE_TESTING_CODE_ERROR) + offset = SetEbuDTCerror(env, out, offset, UDS_TEST_SIM_COMERS); + } + + } + + if (offset > 8) { + uint16_t *len = (uint16_t *) &out[2]; + uint8_t *err = (uint8_t *) &out[7]; + *len = offset - 4; + *err = 0; + asm("nop"); + } + + // конец-------------------------------------------Ошибки----------------------------------------------------------- + + + // IMEI + uint8_t IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length; + if (EXT_ENV_TELE.store.device->cgsmid.length >= 2) { + if ((EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 1] == '\n') && + (EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 2] == '\r')) { + IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length - 2; + } + } + + + uint8_t dataBuf[50]; + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, EXT_ENV_TELE.store.device->cgsmid.data, IMEI_len); + ADD_TO_DATA_SHORT(0x0411); + ADD_TO_DATA_CHAR_SHORT(15); + ADD_TO_DATA(dataBuf, 15) + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, EXT_ENV_TELE.store.gost->VIN.data, EXT_ENV_TELE.store.gost->VIN.length); + ADD_TO_DATA_SHORT(0x0190); + ADD_TO_DATA_CHAR_SHORT(17); + ADD_TO_DATA(dataBuf, 17) + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, EXT_ENV_TELE.store.device->ccidComers.data, EXT_ENV_TELE.store.device->ccidComers.length); + ADD_TO_DATA_SHORT(0x001E); + ADD_TO_DATA_CHAR_SHORT(20); + ADD_TO_DATA(dataBuf, 20) + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, EXT_ENV_TELE.store.device->ccid.data, EXT_ENV_TELE.store.device->ccid.length); + ADD_TO_DATA_SHORT(0x001D); + ADD_TO_DATA_CHAR_SHORT(19); + ADD_TO_DATA(dataBuf, 19) +/* + tString32 FW_NAME; + FW_NAME.length = *FIRMWARE_LOADER.main.metadata.nameLength; + + if (FW_NAME.length > 32) { + FW_NAME.length = 0; + } else { + memcpy(FW_NAME.data, FIRMWARE_LOADER.main.metadata.name, FW_NAME.length); + } +*/ + tString32 FW_NAME; + tString32 HW_NAME; + tString32 FW_INTERFACE; + + getMetaDataUveos(&FW_NAME, &HW_NAME, &FW_INTERFACE); + + uint8_t posDel = findDelimiter(&FW_INTERFACE, ' '); + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, FIRMWARE_TELE_LOADER.main.metadata.name, *FIRMWARE_TELE_LOADER.main.metadata.nameLength); + memcpy(&dataBuf[*FIRMWARE_TELE_LOADER.main.metadata.nameLength], &FW_INTERFACE.data[posDel], FW_INTERFACE.length - posDel); + + ADD_TO_DATA_SHORT(0x0600); + ADD_TO_DATA_CHAR_SHORT(32); + ADD_TO_DATA(dataBuf, 32) + + memset(dataBuf, 0, sizeof(dataBuf)); + memcpy(dataBuf, &EXT_ENV_TELE.store.device->telematicaIsActive, 1); + ADD_TO_DATA_SHORT(0x0604); + ADD_TO_DATA_CHAR_SHORT(1); + ADD_TO_DATA(dataBuf, 1) + +/* + // Serial Number + +// ADD_TO_DATA_SHORT(0xF18C); +// ADD_TO_DATA_CHAR_SHORT(env->storage->nvm.device.serialNumber.value.length); +// ADD_TO_DATA(env->storage->nvm.device.serialNumber.value.data, env->storage->nvm.device.serialNumber.value.length) + + // IMEI + uint8_t IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length; + if (EXT_ENV_TELE.store.device->cgsmid.length >= 2) { + if ((EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 1] == '\n') && + (EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 2] == '\r')) { + IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length - 2; + } + } + + ADD_TO_DATA_SHORT(0xF101); + ADD_TO_DATA_CHAR_SHORT(IMEI_len); + ADD_TO_DATA(EXT_ENV_TELE.store.device->cgsmid.data, IMEI_len) + + // Phone Number + + // Hardware Version + tString32 fw; + fw.length = META_FW_NAME_SIZE; + memcpy(&fw.data, (uint8_t *) META_FW_NAME, fw.length); + + tString32 hw; + hw.length = META_HW_NAME_SIZE; + memcpy(&hw.data, (uint8_t *) META_HW_NAME, hw.length); + + // Hardware Version + ADD_TO_DATA_SHORT(0xF193); + ADD_TO_DATA_CHAR_SHORT(hw.length); + ADD_TO_DATA(hw.data, hw.length) + + // Vehicle VIN Number + ADD_TO_DATA_SHORT(0xF190); + ADD_TO_DATA_CHAR_SHORT(EXT_ENV_TELE.store.gost->VIN.length); + ADD_TO_DATA(EXT_ENV_TELE.store.gost->VIN.data, EXT_ENV_TELE.store.gost->VIN.length) + + // Main Server + ADD_TO_DATA_SHORT(0xF104); + ADD_TO_DATA_CHAR_SHORT(env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.length); + ADD_TO_DATA(env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.data, + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.length) + + // Second Server + ADD_TO_DATA_SHORT(0xF105); + ADD_TO_DATA_CHAR_SHORT(env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.length); + ADD_TO_DATA(env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.data, + env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.length) + +*/ + + env->egtsFirmwareDataArgs.bufLen = offset; +} + +void _Noreturn EgtsProcessing_TransmitterTaskEbu(tEgtsProcessing *env) { + + time_t timestamp = 0; + uint8_t egtsEbuIndex = 0; + + uint32_t timeTeleOff = 0; + + bool isTimestamp = true; + + bool oneOn = true; + bool oneOff = true; + + for (;;) { + + if (onOffTelematica(env, &oneOn, &oneOff, "Задача ЭБУ")) + continue; + + + //начало ---------------------------------Отправка прошивки ЭБУ------------------------------------------------- + //начало ---------------------------------Отправка прошивки ЭБУ------------------------------------------------- + //начало ---------------------------------Отправка прошивки ЭБУ------------------------------------------------- + + if (!isAuth(env)) { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание аутентификации на сервере") + SystemDelayMs(1000); + continue; + } + + if (!env->isEnableTelematicaSendPoints) { + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание разрешения телематики") + } + SystemDelayMs(1000); + continue; + } + + + RtcGet(env->gsm->Rtc, ×tamp); + + if (timestamp < 1718359909) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание получения временной метки") + SystemDelayMs(1000); + continue; + } else { + if (isTimestamp) { + isTimestamp = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Временная метка получена") + } + } + + // Передача прошивки через ВРЕМЯ + if ((env->fl_firstStartTimeUpdateEBU) && (env->firstStartTimeUpdateEBU < SystemGetMs())) { + EXT_ENV_TELE.store.runtime->telematicaWaitConnect = true; + + egtsEbuIndex = EBU_GNSS; + setEgtsNameEbu(env, egtsEbuIndex); + setBufEbu(env); + + if (EgtsProcessing_SendFirmware(env) == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача данных ЭБУ (автоматическая) не удалась") + } else { + env->fl_firstStartTimeUpdateEBU = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача данных ЭБУ (автоматическая) завершена успешно") + } + } + + if (!env->ebuReady) { + + if (env->ebuState.ebuItemState[EBU_GNSS].timestamp == 0) { + + egtsEbuIndex = EBU_GNSS; + setEgtsNameEbu(env, egtsEbuIndex); + setBufEbu(env); + + env->ebuReady = true; + } else { + + if (env->CanMainAdditional.egtsEbuUdsReady.isUdsBufReady) { + + egtsEbuIndex = env->CanMainAdditional.egtsEbuUdsReady.ebuIndex; + setEgtsNameEbu(env, egtsEbuIndex); + + env->egtsFirmwareDataArgs.bufLen = env->CanMainAdditional.egtsEbuUdsReady.bufLen; + memcpy(env->egtsFirmwareDataArgs.bufEbu, + (uint8_t *) env->CanMainAdditional.egtsEbuUdsReady.buf, + env->CanMainAdditional.egtsEbuUdsReady.bufLen); + + env->ebuReady = true; + } + + + } + + } + + if (env->ebuReady) { + + env->ebuReady = false; +/* + setUpdateEbu(env, &env->ebuState, egtsEbuName[egtsEbuIndex].ebu, timestamp + 86400); // !!!!!!!!! + env->CanMainAdditional.egtsEbuUdsReady.ebuIndex = 0; // !!!!!!!!! + env->CanMainAdditional.egtsEbuUdsReady.isUdsBufReady = false; // !!!!!!!!!!!! +*/ + + + // Передача прошивки + if (EgtsProcessing_SendFirmware(env) == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача данных ЭБУ не удалась") + } else { + setUpdateEbu(env, &env->ebuState, egtsEbuName[egtsEbuIndex].ebu, timestamp + 86400); + + if (egtsEbuIndex != EBU_GNSS) { + env->CanMainAdditional.egtsEbuUdsReady.ebuIndex = 0; + env->CanMainAdditional.egtsEbuUdsReady.isUdsBufReady = false; + } + + } + + } + + + //конец ---------------------------------Отправка прошивки ЭБУ-------------------------------------------------- + //конец ---------------------------------Отправка прошивки ЭБУ-------------------------------------------------- + //конец ---------------------------------Отправка прошивки ЭБУ-------------------------------------------------- + + SystemDelayMs(1000); + } +} \ No newline at end of file diff --git a/EgtsEbu.h b/EgtsEbu.h new file mode 100644 index 0000000..70c3a2b --- /dev/null +++ b/EgtsEbu.h @@ -0,0 +1,28 @@ +// +// Created by cfif on 13.06.2024. +// + +#ifndef SMART_COMPONENTS_EGTSEBU_H +#define SMART_COMPONENTS_EGTSEBU_H +#include "EgtsProcessing.h" + +bool addEbuTableItem(tEgtsProcessing *env, tEgtsEbuState *ebuState, tEgtsEbuItemState *ebuItemState); +bool pushEbuTable(tEgtsProcessing *env, tEgtsEbuState *ebuState); +bool dumpEbuTable(tEgtsProcessing *env); +bool loadEbuTable(tEgtsProcessing *env); +void setUpdateEbu(tEgtsProcessing *env, tEgtsEbuState *ebuState, eEgtsEbu egtsEbu, uint32_t state); +void setBufEbu(tEgtsProcessing *env); +bool isCertTest(); + +void setUpdateEbu(tEgtsProcessing *env, tEgtsEbuState *ebuState, eEgtsEbu egtsEbu, uint32_t state); +void setUpdateEbuAll(tEgtsProcessing *env, tEgtsEbuState *ebuState); +void setUpdateEbuClearDTC(tEgtsProcessing *env, tEgtsEbuState *ebuState, eEgtsEbu egtsEbu, bool clearDTC); +eEgtsTestEbu getResultTest(uint8_t indexTest, eDeviceTestingCode *deviceTestingCode); +bool setEgtsNameEbu(tEgtsProcessing *env, uint8_t ebu); +void clearResultTest(); + +void getMetaDataUveos(tString32 *FW_NAME, tString32 *HW_NAME, tString32 *FW_INTERFACE); + +_Noreturn void EgtsProcessing_TransmitterTaskEbu(tEgtsProcessing *env); + +#endif //SMART_COMPONENTS_EGTSEBU_H diff --git a/EgtsFirmware.c b/EgtsFirmware.c new file mode 100644 index 0000000..bfcbe1d --- /dev/null +++ b/EgtsFirmware.c @@ -0,0 +1,163 @@ +// +// Created by cfif on 05.07.2024. +// +#include "EgtsFirmware.h" +#include "AtGsmSimComA7600_SSL_LOAD_CA.h" +#include "aes.h" +/* +#define LOG_SIGN "EGTS_UPDATE" +#define LOGGER &env->slog->logger + +void receivedUpdateFirmware(tEgtsProcessing *env) { + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет прошивки, %d из %d (%d байт данных)", + env->egtsEnv.firmware->PartNumber, + env->egtsEnv.firmware->ExpectedPartsQuantity, + env->egtsEnv.firmware->dataLength); + + + if (env->egtsEnv.firmware->PartNumber == 1) { + env->firmwareOffset = 0; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Подготовка ОЗУ"); + env->firmwareBufCrc = env->egtsEnv.firmware->WholeObjectSignature; + } + + memcpy(&env->firmwareBuf[env->firmwareOffset], env->egtsEnv.firmware->dataPointer, + env->egtsEnv.firmware->dataLength); + env->firmwareOffset += env->egtsEnv.firmware->dataLength; + + if (env->firmwareOffset > sizeof(env->firmwareBuf) - 1024) { + env->firmwareOffset = 0; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Переполнение буфера ОЗУ"); + } + + uint8_t rst; + if (env->egtsEnv.firmware->PartNumber == env->egtsEnv.firmware->ExpectedPartsQuantity) { + + uint32_t pos = env->firmwareOffset - 256; + + uint32_t offsetMetaCrc = *(uint32_t *) &env->firmwareBuf[pos]; + pos += 4; + uint32_t offsetMetaSize = *(uint32_t *) &env->firmwareBuf[pos]; + pos += 4; + + tString32 FW_NAME; + + FW_NAME.length = (*(uint8_t *) &env->firmwareBuf[pos]); + pos += 1; + + if (FW_NAME.length > 32) { + FW_NAME.length = 0; + } else { + memcpy(FW_NAME.data, &env->firmwareBuf[pos], FW_NAME.length); + } + + uint8_t posDel = findDelimiter(FW_NAME, '_') + 1; + + if (memcmp(&FW_NAME.data[posDel], "TELE", 4) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка телематики"); + } else if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка ключей"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена не известная прошивка"); + } + + uint32_t crc32 = 0; + for (uint32_t i = 0; i < offsetMetaSize; ++i) { + crc32 += env->firmwareBuf[i]; + } + + if (crc32 != offsetMetaCrc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы"); + } else { + + if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Загрузка ключей"); + + tIsFind check; + memset(&check, 0, sizeof(check)); + + if (osMutexAcquire(env->gsm->gsmAt->access, 5000) == osOK) { + + tEgtsCertInfo *egtsCertInfo = (tEgtsCertInfo *) env->firmwareBuf; + + AtGsmSimComA7600_SSL_DEL_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + file_crt, strlen(file_crt), + file_key, strlen(file_key)); + + check = AtGsmSimComA7600_SSL_CHECK_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + file_crt, strlen(file_crt), + file_key, strlen(file_key), 2000); + + if (egtsCertInfo->ENC) { + uint32_t lenEnc = offsetMetaSize - sizeof(tEgtsCertInfo); + + struct AES_ctx ctx; + uint8_t key[16]; + + uint8_t iv[16]; + + memset(iv, '3', sizeof(key)); + memset(key, '0', sizeof(key)); + + uint8_t offsetKey = 0; + if (env->storage->nvm.device.ccid.length < 16) + offsetKey = 16 - env->storage->nvm.device.ccid.length; + + memcpy(&key[offsetKey], env->storage->nvm.device.ccid.data, + env->storage->nvm.device.ccid.length); + + AES_init_ctx_iv(&ctx, key, iv); + AES_CBC_decrypt_buffer(&ctx, &env->firmwareBuf[sizeof(tEgtsCertInfo)], + lenEnc); + + } + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + &env->firmwareBuf[sizeof(tEgtsCertInfo)], + egtsCertInfo->SIZE_ROOT_CA, + 2000); + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_key, strlen(file_key), + &env->firmwareBuf[sizeof(tEgtsCertInfo) + + egtsCertInfo->SIZE_ROOT_CA], + egtsCertInfo->SIZE_CLIENT_KEY, 2000); + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_crt, strlen(file_crt), + &env->firmwareBuf[sizeof(tEgtsCertInfo) + + egtsCertInfo->SIZE_ROOT_CA + + egtsCertInfo->SIZE_CLIENT_KEY], + egtsCertInfo->SIZE_CLIENT_CRT, 2000); + + osMutexRelease(env->gsm->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа при загрузке ключей"); + } + + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена не известная прошивка"); + } + + + } + rst = 0; + } else { + rst = 1; + } + + EgtsProcessing_SendResponse(env, EGTS_FIRMWARE_SERVICE, + EGTS_FIRMWARE_SERVICE, + EGTS_SERVICE_FLAGS_FIRMWARE, + rst, + env->egtsEnv.recordNumber); + +} +*/ \ No newline at end of file diff --git a/EgtsFirmware.h b/EgtsFirmware.h new file mode 100644 index 0000000..c822a2f --- /dev/null +++ b/EgtsFirmware.h @@ -0,0 +1,9 @@ +// +// Created by cfif on 05.07.2024. +// + +#ifndef SMART_COMPONENTS_TELEMATICA_EGTSFIRMWARE_H +#define SMART_COMPONENTS_TELEMATICA_EGTSFIRMWARE_H +#include "EgtsProcessing.h" + +#endif //SMART_COMPONENTS_TELEMATICA_EGTSFIRMWARE_H diff --git a/EgtsInputCommands.c b/EgtsInputCommands.c new file mode 100644 index 0000000..a9498ff --- /dev/null +++ b/EgtsInputCommands.c @@ -0,0 +1,502 @@ +// +// Created by cfif on 11.04.2024. +// +#include "EgtsInputCommands.h" +#include "EgtsOutputCommands.h" +#include "Rtc.h" +#include "string.h" +#include "EgtsEbu.h" +#include "ext_telematica.h" +#include "SystemDelayInterface.h" +#include "EgtsTeledataPoint.h" + +#define LOG_SIGN "EGTS_COM" +#define LOGGER &env->slog->logger + +egtsAurusCommandResult egtsAurusSetTimestamp(tEgtsProcessing *env) { + + time_t timestampServer = *((uint32_t *) env->egtsCommandSent.data); + +// LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена временная метка (1681246800): %u", timestamp) + + timestampServer = timestampServer + 1681246800 + 3600 * 3; + + time_t timestampLocal = 0; + RtcGet(EXT_ENV_TELE.rtcIO, ×tampLocal); + + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена временная метка с сервера: %u, текущая временная метка: %u", (uint32_t)timestampServer, (uint32_t)timestampLocal) + + RtcSet(EXT_ENV_TELE.rtcIO, ×tampServer); + + //1681246800 + + if (env->egtsCommandSent.dataSize >= 5) { + + uint8_t isRunTelematica = env->egtsCommandSent.data[4]; + + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен статус удаленного включения (не перманентного) телематики: %u", isRunTelematica) + + if (isRunTelematica) { + return EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_RUN_OK; + + } + + } else { + EXT_ENV_TELE.store.runtime->telematicaWaitConnect = true; + } + + return EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_STOP_OK; +} + +egtsAurusCommandResult egtsAurusGetReport(tEgtsProcessing *env) { + + uint16_t command = *((uint16_t *) (env->egtsCommandSent.data + 2)); + uint16_t block = *((uint16_t *) env->egtsCommandSent.data); + + bool isResponseCommand = false; + + if (command == 101) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда сброса ошибок, код команды: %u, код блока: %u", + command, block) + isResponseCommand = true; + + } + + if (command == 102) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда обновления отчета, код команды: %u, код блока: %u", + command, block) + isResponseCommand = true; + } + + if (!isResponseCommand) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда, код команды: %u, код блока: %u", + command, block) + } + + // GNSS + if (block == CODE_BLOCK_GNSS) { + + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок") + clearResultTest(); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока GNSS") + setUpdateEbu(env, &env->ebuState, EBU_GNSS, 0); + } + + } + + if (block == CODE_BLOCK_ALL) { + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов всех блоков") + setUpdateEbuAll(env, &env->ebuState); + } + } + + + // ABS + if (block == CODE_BLOCK_ABS) { + + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок блока ABS") + setUpdateEbuClearDTC(env, &env->ebuState, EBU_ABS, true); + setUpdateEbu(env, &env->ebuState, EBU_ABS, 0); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока ABS") + setUpdateEbu(env, &env->ebuState, EBU_ABS, 0); + } + } + + // ECM + if (block == CODE_BLOCK_ECM) { + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок блока ECM") + setUpdateEbuClearDTC(env, &env->ebuState, EBU_ECM, true); + setUpdateEbu(env, &env->ebuState, EBU_ECM, 0); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока ECM") + setUpdateEbu(env, &env->ebuState, EBU_ECM, 0); + } + } + + // HVAC + if (block == CODE_BLOCK_HVAC) { + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок блока HVAC") + setUpdateEbuClearDTC(env, &env->ebuState, EBU_HVAC, true); + setUpdateEbu(env, &env->ebuState, EBU_HVAC, 0); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока HVAC") + setUpdateEbu(env, &env->ebuState, EBU_HVAC, 0); + } + } + + // IMMO + if (block == CODE_BLOCK_IMMO) { + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок блока IMMO") + setUpdateEbuClearDTC(env, &env->ebuState, EBU_IMMO, true); + setUpdateEbu(env, &env->ebuState, EBU_IMMO, 0); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока IMMO") + setUpdateEbu(env, &env->ebuState, EBU_IMMO, 0); + } + } + + // PTS + if (block == CODE_BLOCK_PTS) { + if (command == 101) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс ошибок блока PTS") + setUpdateEbuClearDTC(env, &env->ebuState, EBU_PTS, true); + setUpdateEbu(env, &env->ebuState, EBU_PTS, 0); + } + + if (command == 102) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление отчетов блока PTS") + setUpdateEbu(env, &env->ebuState, EBU_PTS, 0); + } + } + + return EGTS_AURUS_COMMAND_RESULT_OK; +} + +egtsAurusCommandResult egtsAurusSetRestart(tEgtsProcessing *env) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена команда перезагрузки устройства") + return EGTS_AURUS_COMMAND_RESULT_RESTART_OK; +} + +egtsAurusCommandResult egtsSetEnablePermanentTelematica(tEgtsProcessing *env) { + + uint8_t isRunTelematica = env->egtsCommandSent.data[0]; + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда удаленного включения (перманентно) телематики: %u", isRunTelematica) + + // Если телематика уже включена + if (EXT_ENV_TELE.store.device->telematicaIsActive) { + if (isRunTelematica) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика включена (перманентно) удаленно") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись настроек не требуется") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика выключена (перманентно) удаленно") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись настроек") + EXT_ENV_TELE.store.device->telematicaIsActive = false; + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + } + + } else { + if (isRunTelematica) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика включена (перманентно) удаленно") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись настроек") + EXT_ENV_TELE.store.device->telematicaIsActive = true; + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика выключена (перманентно) удаленно") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись настроек не требуется") + } + + } + + + + return EGTS_AURUS_COMMAND_RESULT_OK; +} + +egtsAurusCommandResult egtsAurusGetState(tEgtsProcessing *env) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена команда запроса состояния") + + addTeledataQueueEvent(env, EVENT_RESPONSE); + + return EGTS_AURUS_COMMAND_RESULT_OK; +} + +uint8_t VariablesTable_ExGetVarTypeLength(tVariableDescriptor *var) { + + if (var->typeId == VARIABLE_TYPE_UINT8) + return 0x01; + if (var->typeId == VARIABLE_TYPE_UINT16) + return 0x02; + if (var->typeId == VARIABLE_TYPE_STRING) + return 0x00; + if (var->typeId == VARIABLE_TYPE_BOOL) + return 0x01; + if (var->typeId == VARIABLE_TYPE_FLOAT32) + return 0x04; + if (var->typeId == VARIABLE_TYPE_INT32) + return 0x04; + if (var->typeId == VARIABLE_TYPE_UINT32) + return 0x04; + if (var->typeId == VARIABLE_TYPE_INT16) + return 0x02; + if (var->typeId == VARIABLE_TYPE_INT64) + return 0x08; + if (var->typeId == VARIABLE_TYPE_ARR_U8_STATIC) + return 0x00; + + return 0; +} + +egtsAurusCommandResult egtsAurusAnalizCommands(tEgtsProcessing *env) { + + env->egtsCommandSent.commandConfirmationType = CC_OK; + + if (env->egtsCommandSent.cmd == EGTS_SET_TIME) { + return egtsAurusSetTimestamp(env); + } + + if (env->egtsCommandSent.cmd == EGTS_SET_PERMANENT_TELEMATICA) { + return egtsSetEnablePermanentTelematica(env); + } + + if (env->egtsCommandSent.cmd == EGTS_GET_REPORT) { + return egtsAurusGetReport(env); + } + + if (env->egtsCommandSent.cmd == EGTS_SET_RESTART) { + return egtsAurusSetRestart(env); + } + + if (env->egtsCommandSent.cmd == EGTS_FLEET_GET_STATE) { + return egtsAurusGetState(env); + } + +/* + tVariableDescriptor *var = VariablesTable_GetById(&env->storage->publicVariablesTable, env->egtsCommandSent.cmd); + + if (var != NULL) { + + uint8_t typeLen = VariablesTable_ExGetVarTypeLength(var); + + if (env->egtsCommandSent.act == 2) { + var->name.str[var->name.length] = '\0'; + env->egtsCommandSent.data[env->egtsCommandSent.dataSize] = '\0'; + + uint32_t data; + + if (env->egtsCommandSent.dataSize == 4) + data = *(uint32_t*)env->egtsCommandSent.data; + + if (env->egtsCommandSent.dataSize == 2) + data = *(uint16_t*)env->egtsCommandSent.data; + + if (env->egtsCommandSent.dataSize == 1) + data = *(uint8_t*)env->egtsCommandSent.data; + + if (typeLen == 0) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда установки параметров: %s = %s", var->name.str, env->egtsCommandSent.data) + } else { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда установки параметров: %s = %u", var->name.str, data) + } + + } + + if (env->egtsCommandSent.act == 1) { + var->name.str[var->name.length] = '\0'; + LoggerFormatInfo(LOGGER, LOG_SIGN, "Получена команда запроса параметров: %s", var->name.str) + } + + if (typeLen == 0) { + + + // Установка значения + if (env->egtsCommandSent.act == 2) { + + if (env->egtsCommandSent.dataSize > var->limit) + env->egtsCommandSent.dataSize = var->limit; + + if (osMutexAcquire(env->storage->publicVariablesTable.writeAccess, 2000) == osOK) { + + *(uint8_t *) var->len = env->egtsCommandSent.dataSize; + memcpy(var->addr, env->egtsCommandSent.data, env->egtsCommandSent.dataSize); + VariablesTable_VariableChanged(&env->storage->publicVariablesTable, var); + + osMutexRelease(env->storage->publicVariablesTable.writeAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (egtsAurusAnalizCommands)") + } + env->egtsCommandSent.dataSize = 0; + } + + + + // Запрос значения + if (env->egtsCommandSent.act == 1) { + env->egtsCommandSent.dataSize = *(uint8_t *) var->len; + memcpy(env->egtsCommandSent.data, var->addr, env->egtsCommandSent.dataSize); + } + + } else { + + // Установка значения + if (env->egtsCommandSent.act == 2) { + + if (osMutexAcquire(env->storage->publicVariablesTable.writeAccess, 2000) == osOK) { + + memcpy(var->addr, env->egtsCommandSent.data, typeLen); + VariablesTable_VariableChanged(&env->storage->publicVariablesTable, var); + + osMutexRelease(env->storage->publicVariablesTable.writeAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (egtsAurusAnalizCommands)") + } + + env->egtsCommandSent.dataSize = 0; + } + + // Запрос значения + if (env->egtsCommandSent.act == 1) { + memcpy(env->egtsCommandSent.data, var->addr, typeLen); + } + } + + return EGTS_AURUS_COMMAND_RESULT_OK; + } +*/ + env->egtsCommandSent.commandConfirmationType = CC_ILL; + + return EGTS_AURUS_COMMAND_RESULT_UNKNOWN; +} + +void addCommandQueue(tEgtsProcessing *env, tEgtsCommand *egtsCommand) { + + osStatus_t status = osMessageQueuePut(env->egtsCommandConfirmationAdditionalData.queue, egtsCommand, 0x0, 0U); + + if (status != osOK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addCommandQueue") + } +} + +bool extractCommandQueue(tEgtsProcessing *env, tEgtsCommand *egtsCommandSent, uint32_t timeout) { + osStatus_t status = osMessageQueueGet(env->egtsCommandConfirmationAdditionalData.queue, egtsCommandSent, 0, + timeout); + + if ((status != osOK) && (status != osErrorTimeout)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка извлечения из очереди extractCommandQueue") + } + + if (status == osOK) { + return true; + } + + return false; +} + + +_Noreturn void EgtsProcessing_TransmitterTaskInputCommand(tEgtsProcessing *env) { + + bool oneOn = true; + bool oneOff = true; + + for (;;) { + if (onOffTelematica(env, &oneOn, &oneOff, "Задача обработки команд")) + continue; + + + //начало ---------------------------------Обработка команд------------------------------------------------------ + //начало ---------------------------------Обработка команд------------------------------------------------------ + //начало ---------------------------------Обработка команд------------------------------------------------------ + + if (!isAuth(env)) { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание аутентификации на сервере") + SystemDelayMs(1000); + continue; + } + + if (extractCommandQueue(env, &env->egtsCommandSent, 1000)) { + + egtsAurusCommandResult resultCom = egtsAurusAnalizCommands(env); + + if (env->egtsCommandSent.commandConfirmationType == CC_ILL) { + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен неизвестный код команды: %d", + env->egtsCommandSent.cmd); + + } + + EgtsProcessing_SendCommandConfirmation(env, + CT_COMCONF, + env->egtsCommandSent.commandConfirmationType, + env->egtsCommandSent.cmdId, + 0, + + 0, + 0, + 0, + env->egtsCommandSent.cmd, + + env->egtsCommandSent.data, + env->egtsCommandSent.dataSize); + + +// if (resultCom == EGTS_AURUS_COMMAND_RESULT_ERROR) { +// env->egtsIdentityAdditionalData.isReceivedResultCode = false; +// LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Принудительный разрыв соединения с сервером, ИД: %d", +// env->socketId); +// EgtsProcessingCloseConnection(env); +// } + + if (resultCom == EGTS_AURUS_COMMAND_RESULT_RESTART_OK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Закрытие соединения") + EgtsProcessingCloseConnection(env); + SystemDelayMs(1000); + EXT_ENV_TELE.osFreeRTOS.nvic_system_reset(); + } + + + if (resultCom == EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_STOP_OK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика выключена (не перманентно) удаленно") + + env->isEnableTelematicaSendPoints = false; + + if (env->deviceTeledataStorageData->telematica.EGTS_SERVER_ENABLE_TELEMATICA) { + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ENABLE_TELEMATICA = false; + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + } + + env->TelematicaServerNotActiveWaitTime = SystemGetMs() + 40000; + +// if(EXT_ENV_TELE.store.device->telematicaIsActive == false){ +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Закрытие соединения") +// EgtsProcessingCloseConnection(env); +// } + +// EXT_ENV_TELE.store.runtime->telematicaServerIsActive = false; +// EXT_ENV_TELE.store.runtime->telematicaWaitConnect = true; + + } + + if (resultCom == EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_RUN_OK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика включена (не перманентно) удаленно") + + env->isEnableTelematicaSendPoints = true; + + if (!env->deviceTeledataStorageData->telematica.EGTS_SERVER_ENABLE_TELEMATICA) { + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ENABLE_TELEMATICA = true; + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + } + + + EXT_ENV_TELE.store.runtime->telematicaServerIsActive = true; + EXT_ENV_TELE.store.runtime->telematicaWaitConnect = true; + } + + + } + + + //конец ---------------------------------Обработка команд------------------------------------------------------- + //конец ---------------------------------Обработка команд------------------------------------------------------- + //конец ---------------------------------Обработка команд------------------------------------------------------- + + } +} + + diff --git a/EgtsInputCommands.h b/EgtsInputCommands.h new file mode 100644 index 0000000..b3086ea --- /dev/null +++ b/EgtsInputCommands.h @@ -0,0 +1,60 @@ +// +// Created by cfif on 11.04.2024. +// + +#ifndef SMART_COMPONENTS_EGTSINPUTCOMMANDS_H +#define SMART_COMPONENTS_EGTSINPUTCOMMANDS_H + +#include "EgtsProcessing.h" + +typedef enum { + CODE_BLOCK_ALL = 0x0000, + CODE_BLOCK_GNSS = 0x07CA, + CODE_BLOCK_ABS = 0x07E3, + CODE_BLOCK_ECM = 0x07E0, + CODE_BLOCK_HVAC = 0x07E4, + CODE_BLOCK_IMMO = 0x0723, + CODE_BLOCK_PTS = 0x07E7 +} egtsCodeBlock; + +typedef enum { + EGTS_AURUS_COMMAND_RESULT_OK = 0x00, + EGTS_AURUS_COMMAND_RESULT_ERROR = 0x01, + + EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_STOP_OK = 0xFC, + EGTS_AURUS_COMMAND_RESULT_TIMESTAMP_TELE_RUN_OK = 0xFD, + + EGTS_AURUS_COMMAND_RESULT_RESTART_OK = 0xFE, + EGTS_AURUS_COMMAND_RESULT_UNKNOWN = 0xFF, +} egtsAurusCommandResult; + +typedef enum { + EGTS_SET_RESTART = 0x0008, + EGTS_FLEET_GET_STATE = 0x0010, + EGTS_SET_TIME = 0xFAC4, + + EGTS_SET_PERMANENT_TELEMATICA = 0xFAD0, + + EGTS_GET_REPORT = 0xFAC2, + + EGTS_GPRS_APN = 0x0203, + EGTS_SERVER_ADDRESS = 0x0204, + EGTS_SIM_PIN = 0x0205, + + EGTS_GPRS_USER = 0x051A + + +} egtsAurusCommands; + + +egtsAurusCommandResult egtsAurusAnalizCommands(tEgtsProcessing *env); + +egtsAurusCommandResult egtsAurusSetTimestamp(tEgtsProcessing *env); + +void addCommandQueue(tEgtsProcessing *env, tEgtsCommand *egtsCommand); + +uint8_t VariablesTable_ExGetVarTypeLength(tVariableDescriptor *var); + +_Noreturn void EgtsProcessing_TransmitterTaskInputCommand(tEgtsProcessing *env); + +#endif //SMART_COMPONENTS_EGTSINPUTCOMMANDS_H diff --git a/EgtsOutputCommands.c b/EgtsOutputCommands.c new file mode 100644 index 0000000..731f968 --- /dev/null +++ b/EgtsOutputCommands.c @@ -0,0 +1,797 @@ +// +// Created by cfif on 12.04.2024. +// +#include "EgtsOutputCommands.h" +#include "math.h" +#include "AsciiStringAssmeblingUtils.h" +#include "stdio.h" +#include "Rtc.h" +#include "egts_commonExt.h" +#include "EgtsTimestamp.h" +#include "string.h" +#include "GsmWithGnss_Info.h" +#include "FirmwareTelematicaMetadataSection.h" +#include "FirmwareMetadataSection.h" +#include "stdlib.h" +#include "EgtsEbu.h" + +#define LOG_SIGN "EGTS" +#define LOGGER &env->slog->logger + +#define ADD_TO_RESULT(DATA, LEN) memcpy(out + offset, (uint8_t * ) & DATA, LEN); offset+=LEN; +#define ADD_TO_RESULT_P(DATA, LEN) memcpy(out + offset, DATA, LEN); offset+=LEN; + +//начало ---------------------------------Аутентификация--------------------------------------------------------------- +//начало ---------------------------------Аутентификация--------------------------------------------------------------- +//начало ---------------------------------Аутентификация--------------------------------------------------------------- + +uint16_t vEgtsPackAuth(uint8_t *out, tEgtsIdentityDataArgs *args, uint16_t step) { + uint16_t offset = 0; + + uint16_t TermIdentityBS = 1024 * 10;//1400; + uint8_t TermIdentityFlags = 0b01000010; + + ADD_TO_RESULT(args->TerminalID, 4); + ADD_TO_RESULT(TermIdentityFlags, 1); + ADD_TO_RESULT((*args->IMEI), args->IMEI_len); + ADD_TO_RESULT(TermIdentityBS, 2); + + return offset; +} + +uint16_t vEgtsPackModuleDataUveos(uint8_t *out, tEgtsIdentityModuleDataArgs *args, uint16_t step) { + uint16_t offset = 0; + + tString32 FW_NAME; + tString32 HW_NAME; + tString32 FW_INTERFACE; + + getMetaDataUveos(&FW_NAME, &HW_NAME, &FW_INTERFACE); + + uint8_t fw_h = 0; + uint8_t fw_l = 0; + uint8_t hw_h = 0; + uint8_t hw_l = 0; + + uint8_t pos = findDelimiter(&FW_INTERFACE, '.') + 1; + if (pos > 1) { + fw_h = atoi(FW_INTERFACE.data); + fw_l = atoi(&FW_INTERFACE.data[pos]); + } + + + + tString32 hw; + hw.length = META_HW_NAME_SIZE; + memcpy(&hw.data, (uint8_t *) META_HW_NAME, hw.length); + + pos = findDelimiter(&hw, '.') + 1; + if (pos > 1) { + hw_h = atoi(HARDWARE_REVISION); + hw_l = atoi(&HARDWARE_REVISION[pos]); + } + /* + pos = findDelimiter(&FW_INTERFACE, '.') + 1; + if (pos > 1) { + hw_h = atoi(FW_INTERFACE.data); + hw_l = atoi(&FW_INTERFACE.data[pos]); + } +*/ + uint8_t MT = 5; // Module Туре + uint32_t VID = 1; // Vendor Identifier + uint16_t FWV = (hw_h << 8) | hw_l; // Firmware Version + uint16_t SWV = (fw_h << 8) | fw_l; // Software Version + uint8_t MD = 0; // Modification + uint8_t ST = 1; // State + + uint8_t Delimiter = 0; + + ADD_TO_RESULT(MT, 1); + ADD_TO_RESULT(VID, 4); + ADD_TO_RESULT(FWV, 2); + ADD_TO_RESULT(SWV, 2); + ADD_TO_RESULT(MD, 1); + ADD_TO_RESULT(ST, 1); + ADD_TO_RESULT(Delimiter, 1); + + return offset; +} + +uint16_t vEgtsPackModuleDataTelematca(uint8_t *out, tEgtsIdentityModuleDataArgs *args, uint16_t step) { + uint16_t offset = 0; + + tString32 fw; + fw.length = META_FW_NAME_SIZE; + memcpy(&fw.data, (uint8_t *) META_FW_NAME, fw.length); + + uint8_t pos = findDelimiter(&fw, '.') + 1; + uint8_t fw_h = atoi(FIRMWARE_VERSION); + uint8_t fw_l = atoi(&FIRMWARE_VERSION[pos]); + + tString32 hw; + hw.length = META_HW_NAME_SIZE; + memcpy(&hw.data, (uint8_t *) META_HW_NAME, hw.length); + + pos = findDelimiter(&hw, '.') + 1; + uint8_t hw_h = atoi(HARDWARE_REVISION); + uint8_t hw_l = atoi(&HARDWARE_REVISION[pos]); + + uint8_t MT = 1; // Module Туре + uint32_t VID = 1; // Vendor Identifier + uint16_t FWV = (hw_h << 8) | hw_l; // Firmware Version + uint16_t SWV = (fw_h << 8) | fw_l; // Software Version + uint8_t MD = 0; // Modification + uint8_t ST = 1; // State + + uint8_t Delimiter = 0; + + char TAG_VIN[] = "VIN:"; + char TAG_ICCID[] = "ICCID:"; + char TAG_EICCID[] = "EICCID:"; + char TAG_VPT[] = "VPT:UAZ_GENERAL"; + + ADD_TO_RESULT(MT, 1); + ADD_TO_RESULT(VID, 4); + ADD_TO_RESULT(FWV, 2); + ADD_TO_RESULT(SWV, 2); + ADD_TO_RESULT(MD, 1); + ADD_TO_RESULT(ST, 1); + ADD_TO_RESULT(EXT_ENV_TELE.store.device->ECUSerialNumber.data, EXT_ENV_TELE.store.device->ECUSerialNumber.length); + ADD_TO_RESULT(Delimiter, 1); + ADD_TO_RESULT(TAG_VIN, sizeof(TAG_VIN) - 1); + ADD_TO_RESULT(EXT_ENV_TELE.store.gost->VIN.data, EXT_ENV_TELE.store.gost->VIN.length); + ADD_TO_RESULT(Delimiter, 1); + ADD_TO_RESULT(TAG_ICCID, sizeof(TAG_ICCID) - 1); + ADD_TO_RESULT(EXT_ENV_TELE.store.device->ccidComers.data, EXT_ENV_TELE.store.device->ccidComers.length); + ADD_TO_RESULT(Delimiter, 1); + ADD_TO_RESULT(TAG_EICCID, sizeof(TAG_EICCID) - 1); + ADD_TO_RESULT(EXT_ENV_TELE.store.device->ccid.data, EXT_ENV_TELE.store.device->ccid.length); + ADD_TO_RESULT(Delimiter, 1); + ADD_TO_RESULT(TAG_VPT, sizeof(TAG_VPT) - 1); + ADD_TO_RESULT(Delimiter, 1); + + return offset; +} + +//char auth[15] = "860384067388816"; + +bool EgtsProcessing_SendAuth(tEgtsProcessing *env) { + + uint8_t egtsRaw[256]; + memset(egtsRaw, 0, sizeof(egtsRaw)); + + uint16_t authPackLength; + + time_t timestamp; + RtcGet(env->gsm->Rtc, ×tamp); + + uint8_t IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length; + if (EXT_ENV_TELE.store.device->cgsmid.length >= 2) { + if ((EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 1] == '\n') && + (EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 2] == '\r')) { + IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length - 2; + } + } + + env->egtsIdentityDataArgs.IMEI = (uint8_t *) EXT_ENV_TELE.store.device->cgsmid.data; + env->egtsIdentityDataArgs.IMEI_len = IMEI_len; + env->egtsIdentityDataArgs.TerminalID = env->deviceTeledataStorageData->telematica.EGTS_UNIT_ID; + + ++env->egtsPacketId; + env->egtsIdentityAdditionalData.idPacked = env->egtsPacketId; + env->egtsIdentityAdditionalData.isReceivedResponse = false; + env->egtsIdentityAdditionalData.isReceivedResultCode = false; + + authPackLength = vEgtsPackTransportEx3( + 0, + env->egtsIdentityAdditionalData.idPacked, + &env->counter, + egtsRaw, + EGTS_SERVICE_FLAGS_AUTH, + EGTS_PT_APPDATA, + EGTS_AUTH_SERVICE, + EGTS_AUTH_SERVICE, + timestamp, + + 1, + EGTS_SR_TERM_IDENTITY, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackAuth, + &env->egtsIdentityDataArgs, + + 1, + EGTS_SR_MODULE_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackModuleDataUveos, + &env->egtsModuleDataArgs, + + 1, + EGTS_SR_MODULE_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackModuleDataTelematca, + &env->egtsModuleDataArgs + ); + + LoggerFormatInfo(LOGGER, LOG_SIGN, "Отправка пакета (id: %u) аутентификации:", + env->egtsIdentityAdditionalData.idPacked) + sendLogHex(env, egtsRaw, authPackLength); + + bool result = EgtsProcessingSend(env, egtsRaw, authPackLength, EGTS_WAIT_2, + &env->egtsIdentityAdditionalData.isReceivedResponse, + &env->egtsIdentityAdditionalData.isReceivedResultCode); + + if (!result) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Истекло время ожидания (EgtsProcessing_SendAuth)"); + return false; + } + + return true; +} + +//конец ---------------------------------Аутентификация--------------------------------------------------------------- +//конец ---------------------------------Аутентификация--------------------------------------------------------------- +//конец ---------------------------------Аутентификация--------------------------------------------------------------- + + +//начало ---------------------------------Теледанные-------------------------------------------------------------------- +//начало ---------------------------------Теледанные-------------------------------------------------------------------- +//начало ---------------------------------Теледанные-------------------------------------------------------------------- + +void EgtsProcessing_Default_SendSensorsDig(tEgtsProcessing *env) { + + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_BodyCanBusStatus].number = 18; + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS1].number = 101; + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS2].number = 102; + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS3].number = 103; + +/* + for (int i = 0; i < 20; ++i) { + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[i].number = i; + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[i].state = 0; + } + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[0].state = 0; // Vehicle Alarm System activate siren + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[1].state = 0; // Состояние охранной сигнализации + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[2].state = 0; // Статус заряда АКБ + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[3].state = 0; // Статус ПЛ двери + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[4].state = 0; // Статус ПП двери + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[5].state = 0; // Статус ЗЛ двери + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[6].state = 0; // Статус ЗП двери + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[7].state = 0; // Статус капота + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[8].state = 0; // Уровень омывающей жидкости + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[9].state = 0; // Уровень охлаждающей жидкости + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[10].state = 0; // Окно ПЛ + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[11].state = 0; // Окно ПП + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[12].state = 0; // Окно ЗЛ + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[13].state = 0; // Окно ЗП + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[14].state = 0; // Состояние батареи датчика давления шины ПЛ + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[15].state = 0; // Состояние батареи датчика давления шины ПП + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[16].state = 0; // Состояние батареи датчика давления шины ЗЛ + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[17].state = 0; // Состояние батареи датчика давления шины ЗП + + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[18].state = 0; // Статус шины BodyCan + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[19].state = 0; // Статус шины DiagCan +*/ +} + + +void EgtsProcessing_Default_SendSensorsAn(tEgtsProcessing *env) { + + // Время работы прибора в минутах, после последней перезагрузки/включения + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Uptime].number = 99; + // Внешняя температура, С + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ExternalTemperature].number = 104; + // Уровень топлива, л + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_FuelLevel].number = 105; + // Статус автомобиля + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].number = 106; + // Пробег поездки в 1/10000 литра + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TripMileage].number = 111; + // Минут поездки (сборная) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_MinutesOfTravel].number = 113; + // Моточасы + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineHours].number = 131; + // Напряжение АКБ 12В + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Voltage12Volts].number = 3; + // RSSI (GSM Network) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_RSSI].number = 207; + // Network type + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].number = 208; + // Количество ускорений за поездку + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberAccelerations].number = 142; + // Количество торможений за поездку + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberBraking].number = 143; + // Температура ОХ двигателя + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOXTemperature].number = 150; + // Номер поездки + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberTrip].number = 153; + // Ср. расход за поездку + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TripSpentFuel].number = 110; + + // Отладочный датчик 1 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS1].number = 11; + // Отладочный датчик 2 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS2].number = 12; + // Отладочный датчик 3 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS3].number = 13; + // Отладочный датчик 4 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS4].number = 14; + // Отладочный датчик 5 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS5].number = 15; + + +/* + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[0].number = 99; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[1].number = 104; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[2].number = 105; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[3].number = 106; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[4].number = 111; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[5].number = 112; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[6].number = 113; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[7].number = 131; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[8].number = 132; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[9].number = 133; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[10].number = 134; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[11].number = 3; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[12].number = 206; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[13].number = 207; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[14].number = 208; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[15].number = 142; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[16].number = 143; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[17].number = 144; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[18].number = 145; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[19].number = 146; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[20].number = 147; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[21].number = 148; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[22].number = 149; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[23].number = 150; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[24].number = 151; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[25].number = 11; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[26].number = 12; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[27].number = 13; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[28].number = 14; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[29].number = 15; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[30].number = 153; +*/ + +/* + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Uptime].number = 99; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ExternalTemperature].number = 104; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_FuelLevel].number = 105; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].number = 106; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TripMileage].number = 111; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_AverageSpeed].number = 112; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_MinutesOfTravel].number = 113; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineHours].number = 131; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_CarMileageAfterBCReset].number = 132; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_AverageSpeedAfterBCReset].number = 133; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TimeAfterBCReset].number = 134; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Voltage12Volts].number = 3; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberOfSatellites].number = 206; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_RSSI].number = 207; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].number = 208; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberAccelerations].number = 142; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberBraking].number = 143; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberAccelerationsAfterReset].number = 144; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberBrakingAfterReset].number = 145; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberLateralAccelerations].number = 146; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberLateralAccelerationsAfterReset].number = 147; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberSpeedViolations].number = 148; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberSpeedViolationsAfterReset].number = 149; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOXTemperature].number = 150; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOilTemperature].number = 151; + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS1].number = 11; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS2].number = 12; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS3].number = 13; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS4].number = 14; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS5].number = 15; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberTrip].number = 153; +*/ + asm("nop"); + +/* + // 0 + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[0].number = 3; + + // 43 + for (int i = 1; i <= 43; ++i) { + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[i].number = 98 + i; + } + + // 3 + for (int i = 44; i <= 46; ++i) { + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[i].number = 162 + i; + } + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[0].value = 12000; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[1].value = 0; // Время работы прибора в минутах, после последней перезагрузки/включения + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[2].value = 80 + 40; // 20 Темп. внутри салона (передняя), С + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[3].value = 80 + 60; // 30 Температура внутри салона (задняя), С + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[4].value = 50; // SoH АКБ, % + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[5].value = 60; // SoC АКБ, % + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[6].value = 90; // 5 Внешняя температура, С + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[7].value = 80; // 40 л Уровень топлива, л + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[8].value = 3; // Статус автомобиля + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[9].value = 1; // Статус замков дверей + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[10].value = 3; // Статус багажника (задняя дверь) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[11].value = 70; // 7 л Ср. расход топлива после БК + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[12].value = 60; // 6 л Ср. расход за поездку + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[13].value = 200; // 20 км Пробег поездки + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[14].value = 600; // 60 км/ч Средняя скорость + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[15].value = 20; // Минут поездки (сборная) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[16].value = 3; // Положение рычага АКПП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[17].value = 100000 + 50; // Дней до ТО + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[18].value = 100000 + 300; // Пробег до ТО + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[19].value = 80;// Уровень масла в двигателе + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[20].value = 0; // Индикатор уровня масла двигателя + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[21].value = 22;// 2 атм давление в шине ПЛ + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[22].value = 24;// 2 атм давление в шине ПП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[23].value = 26;// 2 атм давление в шине ЗЛ + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[24].value = 20;// 2 атм давление в шине ЗП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[25].value = 2;// Состояние шины ПЛ + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[26].value = 2;// Состояние шины ПП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[27].value = 2;// Состояние шины ЗЛ + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[28].value = 2;// Состояние шины ЗП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[29].value = 20;//26 = 20/10 + 16 Целевая темп. CCU водитель + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[30].value = 20;// Целевая темп. CCU П-П + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[31].value = 20;// Целевая темп. CCU ЗЛ-П + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[32].value = 20;// Целевая темп. CCU ЗП-П + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[33].value = 100;// Моточасы + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[34].value = 250;// Пробег авто после сброса БК + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[35].value = 700;// Средняя скорость после сброса БК + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[36].value = 20;// 20 мин Время после сброса БК + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[37].value = 700;// Пробег на остатке топлива + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[38].value = 50;// SoH HV АКБ, % + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[39].value = 60;// SoC HV АКБ, % + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[40].value = 1;// Занятость кресла водителя + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[41].value = 1;// Занятость кресла ПП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[42].value = 1;// Занятость кресла ЗЛ + // Нет Напряжение АКБ 12В + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[43].value = 4;// Занятость кресла ЗП + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[44].value = 3;// Кол-во спутников + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[45].value = 30;// 53 = 113- 30*2 RSSI (GSM Network) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[46].value = 44;// Network type +*/ + +} + + +uint16_t vEgtsPackSensorsDigData(uint8_t *out, tEgtsSensorsDigDataArgs *args, uint16_t step) { + uint16_t offset = 0; + ADD_TO_RESULT(args->sensorsDigState[step], 2); + return offset; +} + +uint16_t vEgtsPackSensorsAnData(uint8_t *out, tEgtsSensorsAnDataArgs *args, uint16_t step) { + uint16_t offset = 0; + ADD_TO_RESULT(args->sensorsAnState[step], 4); + return offset; +} + +uint16_t vEgtsPackPositionData(uint8_t *out, tEgtsPositionDataArgs *args, uint16_t step) { + + uint16_t offset = 0; + + ADD_TO_RESULT(args->NTM, 4); + ADD_TO_RESULT(args->LAT, 4); + ADD_TO_RESULT(args->LONG, 4); + ADD_TO_RESULT(args->FLG, 1); + ADD_TO_RESULT(args->SPD, 2); + ADD_TO_RESULT(args->DIR, 1); + ADD_TO_RESULT(args->ODM, 3); + ADD_TO_RESULT(args->DIN, 1); + ADD_TO_RESULT(args->SRC, 1); + ADD_TO_RESULT(args->ALT, 3); + + return offset; + +} + +uint16_t vEgtsExtPackPositionData(uint8_t *out, tEgtsExtPositionDataArgs *args, uint16_t step) { + + uint16_t offset = 0; + + ADD_TO_RESULT(args->FLG, 1); + ADD_TO_RESULT(args->SAT, 1); + ADD_TO_RESULT(args->NS, 2); + + return offset; + +} + + +bool EgtsProcessing_SendSensors(tEgtsProcessing *env, bool isStorage) { + + uint8_t egtsRaw[1024]; + memset(egtsRaw, 0, sizeof(egtsRaw)); + + time_t timestamp; + RtcGet(env->gsm->Rtc, ×tamp); + +// LoggerStrInfoStatic(LOGGER, LOG_SIGN, "НОВАЯ ТЕЛЕМАТИКА"); + + ++env->egtsPacketId; + env->egtsTeledataAdditionalData.idPacked = env->egtsPacketId; + env->egtsTeledataAdditionalData.isReceivedResponse = false; + + uint16_t PackLength; + + PackLength = vEgtsPackTransportEx4( + 0, + env->egtsTeledataAdditionalData.idPacked, + &env->counter, + egtsRaw, + EGTS_SERVICE_FLAGS_TELEDATA, + EGTS_PT_APPDATA, + EGTS_TELEDATA_SERVICE, + EGTS_TELEDATA_SERVICE, + timestamp, + + 1, + EGTS_SR_POS_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackPositionData, + &env->egtsTeledataSent.egtsPosDataArgs, + + 1, + EGTS_SR_EXT_POS_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsExtPackPositionData, + &env->egtsTeledataSent.egtsExtPositionDataArgs, + + //20, + 4, + EGTS_SR_ABS_DIG_SENS_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackSensorsDigData, + &env->egtsTeledataSent.egtsSensorsDigArgs, + + //47, + 20, + EGTS_SR_ABS_AN_SENS_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackSensorsAnData, + &env->egtsTeledataSent.egtsSensorsAnArgs + ); + + + LoggerFormatInfo(LOGGER, LOG_SIGN, "Отправка пакета (id: %u) теледанных (%u байт):", + env->egtsTeledataAdditionalData.idPacked, PackLength) + //sendLogHex(env, egtsRaw, PackLength); + + bool result = EgtsProcessingSend(env, egtsRaw, PackLength, EGTS_WAIT_1, + &env->egtsTeledataAdditionalData.isReceivedResponse, NULL); + + if (!result) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Истекло время ожидания (EgtsProcessing_SendSensors)"); + return false; + } + + return true; + +} + +//конец ---------------------------------Теледанные--------------------------------------------------------------------- +//конец ---------------------------------Теледанные--------------------------------------------------------------------- +//конец ---------------------------------Теледанные--------------------------------------------------------------------- + + +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ + +uint16_t vEgtsPackFirmware(uint8_t *out, tEgtsFirmwareDataArgs *args, uint16_t step) { + uint16_t offset = 0; + + ++args->partNumber; + + ADD_TO_RESULT(args->idFirmware, 2); + ADD_TO_RESULT(args->partNumber, 2); + ADD_TO_RESULT(args->countNumber, 2); + + if (args->partNumber == 1) { + + tOA OA; + OA.MT = 0; + OA.OT = 1; + OA.Reserve = 0; + ADD_TO_RESULT(OA, 1); + + uint8_t CMI = 0; + ADD_TO_RESULT(CMI, 1); + + uint16_t VER = 0x100; + ADD_TO_RESULT(VER, 2); + + uint16_t WOS = CRC16EGTS(args->bufEbu, args->bufLen); + ADD_TO_RESULT(WOS, 2); + + char FILENAME[100]; + sprintf(FILENAME, "DTC_%lu_%s", args->timestamp, args->module); + ADD_TO_RESULT(FILENAME, strlen(FILENAME) + 1); + } + + ADD_TO_RESULT(args->bufEbu, args->bufLen); + + return offset; +} + + +bool EgtsProcessing_SendFirmware(tEgtsProcessing *env) { + memset(env->egtsRawFirmware, 0, sizeof(env->egtsRawFirmware)); + + uint16_t firmwarePackLength; + + time_t timestamp; + RtcGet(env->gsm->Rtc, ×tamp); + + ++env->egtsFirmwareDataArgs.idFirmware; + env->egtsFirmwareDataArgs.countNumber = 1; + env->egtsFirmwareDataArgs.partNumber = 0; + env->egtsFirmwareDataArgs.timestamp = timestamp; + + ++env->egtsPacketId; + env->egtsIdentityAdditionalData.idPacked = env->egtsPacketId; + env->egtsIdentityAdditionalData.isReceivedResponse = false; + + firmwarePackLength = vEgtsPackTransportEx1( + 0, + env->egtsIdentityAdditionalData.idPacked, + &env->counter, + env->egtsRawFirmware, + EGTS_SERVICE_FLAGS_FIRMWARE, + EGTS_PT_APPDATA, + EGTS_FIRMWARE_SERVICE, + EGTS_FIRMWARE_SERVICE, + timestamp, + 1, + EGTS_SR_SERVICE_PART_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackFirmware, + &env->egtsFirmwareDataArgs + ); + + LoggerFormatInfo(LOGGER, LOG_SIGN, "Отправка пакета (id: %u) прошивки:", env->egtsIdentityAdditionalData.idPacked) + sendLogHex(env, env->egtsRawFirmware, firmwarePackLength); + + bool result = EgtsProcessingSend(env, env->egtsRawFirmware, firmwarePackLength, EGTS_WAIT_1, + &env->egtsIdentityAdditionalData.isReceivedResponse, NULL); + + if (!result) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Истекло время ожидания (EgtsProcessing_SendFirmware)"); + return false; + } + + return true; +} + +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ + + +//начало ---------------------------------Команды------------------------------------------------------------------ +//начало ---------------------------------Команды------------------------------------------------------------------ +//начало ---------------------------------Команды------------------------------------------------------------------ +uint16_t vEgtsPackCommandConfirmation(uint8_t *out, tEgtsCommandConfirmationDataArgs *args, uint16_t step) { + uint16_t offset = 0; + + uint8_t flag = (args->CT << 0x4) | (args->CCT & 0xF); + ADD_TO_RESULT(flag, 1); + + ADD_TO_RESULT(args->CID, 4); + ADD_TO_RESULT(args->SID, 4); + + uint8_t hasFlags = (args->ACFE << 0x1) | (args->CHSFE & 0x1); + ADD_TO_RESULT(hasFlags, 1); + + if (args->CHSFE) { + ADD_TO_RESULT(args->CHS, 1); + } + if (args->ACFE) { + ADD_TO_RESULT(args->ACL, 1); + ADD_TO_RESULT(args->AC, 4); + } + + if ((args->CT == CT_COMCONF) && (args->CCT == CC_OK)) { + ADD_TO_RESULT(args->CmdData.ADR, 2); + uint8_t flagComData = (args->CmdData.SZ << 0x4) | (args->CmdData.ACT & 0xF); + ADD_TO_RESULT(flagComData, 1); + ADD_TO_RESULT(args->CmdData.CCD, 2); + } + + if (args->CmdData.DT_SIZE) { + ADD_TO_RESULT_P(args->CmdData.DT, args->CmdData.DT_SIZE); + } + + return offset; +} + +bool EgtsProcessing_SendCommandConfirmation(tEgtsProcessing *env, + uint8_t cmdType, + uint8_t cmdConfirmationType, + uint32_t cmdId, + uint32_t srcId, + + uint16_t address, + uint8_t size, + uint8_t act, + uint16_t cmd, + + uint8_t *DT, + uint16_t DT_SIZE) { + uint8_t egtsRaw[256]; + memset(egtsRaw, 0, sizeof(egtsRaw)); + + uint16_t commandConfirmationPackLength; + + time_t timestamp; + RtcGet(env->gsm->Rtc, ×tamp); + + bool authCodeExist = false; + bool charsetExist = false; + + env->egtsCommandConfirmationDataArgs.CT = cmdType; + env->egtsCommandConfirmationDataArgs.CCT = cmdConfirmationType; + env->egtsCommandConfirmationDataArgs.CID = cmdId; + env->egtsCommandConfirmationDataArgs.SID = srcId; + env->egtsCommandConfirmationDataArgs.ACFE = authCodeExist; + env->egtsCommandConfirmationDataArgs.CHSFE = charsetExist; + + env->egtsCommandConfirmationDataArgs.CmdData.ADR = address; + env->egtsCommandConfirmationDataArgs.CmdData.SZ = size; + env->egtsCommandConfirmationDataArgs.CmdData.ACT = act; + env->egtsCommandConfirmationDataArgs.CmdData.CCD = cmd; + + env->egtsCommandConfirmationDataArgs.CmdData.DT_SIZE = DT_SIZE; + if (DT_SIZE == 0) { + env->egtsCommandConfirmationDataArgs.CmdData.DT = NULL; + } else { + env->egtsCommandConfirmationDataArgs.CmdData.DT = DT; + } + + ++env->egtsPacketId; + env->egtsCommandConfirmationAdditionalData.idPacked = env->egtsPacketId; + env->egtsCommandConfirmationAdditionalData.isReceivedResponse = false; + + commandConfirmationPackLength = vEgtsPackTransportEx1( + 0, + env->egtsCommandConfirmationAdditionalData.idPacked, + &env->counter, + egtsRaw, + +// 0x44, + EGTS_SERVICE_FLAGS_COMMAND, + EGTS_PT_APPDATA, + EGTS_COMMANDS_SERVICE, + EGTS_COMMANDS_SERVICE, + timestamp, + 1, + EGTS_SR_COMMAND_DATA, + (tEgtsServiceSubRecordGeneratorEx) vEgtsPackCommandConfirmation, + &env->egtsCommandConfirmationDataArgs + ); + +// LoggerFormatInfo(LOGGER, LOG_SIGN, "Отправка пакета (id: %u) ответа на команду:", +// env->egtsCommandConfirmationAdditionalData.idPacked) +// sendLogHex(env, egtsRaw, commandConfirmationPackLength); + + bool result = EgtsProcessingSend(env, egtsRaw, commandConfirmationPackLength, EGTS_WAIT_1, + &env->egtsCommandConfirmationAdditionalData.isReceivedResponse, NULL); + + if (!result) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Истекло время ожидания (EgtsProcessing_SendCommandConfirmation)"); + return false; + } + + return true; +} + +//конец ---------------------------------Команды------------------------------------------------------------------ +//конец ---------------------------------Команды------------------------------------------------------------------ +//конец ---------------------------------Команды------------------------------------------------------------------ \ No newline at end of file diff --git a/EgtsOutputCommands.h b/EgtsOutputCommands.h new file mode 100644 index 0000000..158f006 --- /dev/null +++ b/EgtsOutputCommands.h @@ -0,0 +1,188 @@ +// +// Created by cfif on 12.04.2024. +// + +#ifndef SMART_COMPONENTS_EGTSOUTPUTCOMMANDS_H +#define SMART_COMPONENTS_EGTSOUTPUTCOMMANDS_H + +#include "EgtsProcessing.h" + +typedef enum { + SENSORS_DIG_BodyCanBusStatus = 0, // Статус шины BodyCan + SENSORS_DIG_ANS1 = 1, // Отладочный датчик 1 + SENSORS_DIG_ANS2 = 2, // Отладочный датчик 2 + SENSORS_DIG_ANS3 = 3 // Отладочный датчик 3 +} eSensorsDig; + + +typedef enum { + SENSORS_AN_Uptime = 0, // Время работы прибора в минутах, после последней перезагрузки/включения + SENSORS_AN_ExternalTemperature = 1, // Внешняя температура, С + SENSORS_AN_FuelLevel = 2, // Уровень топлива, л + SENSORS_AN_VehicleStatus = 3, // Статус автомобиля + SENSORS_AN_TripMileage = 4,// Пробег поездки в 1/10000 литра + SENSORS_AN_MinutesOfTravel = 5,// Минут поездки (сборная) + SENSORS_AN_EngineHours = 6,// Моточасы + SENSORS_AN_Voltage12Volts = 7, // Напряжение АКБ 12В + SENSORS_AN_RSSI = 8,// RSSI (GSM Network) + SENSORS_AN_NetworkType = 9,// Network type + SENSORS_AN_NumberAccelerations = 10, // Количество ускорений за поездку + SENSORS_AN_NumberBraking = 11, // Количество торможений за поездку + SENSORS_AN_EngineOXTemperature = 12, // Температура ОХ двигателя + + SENSORS_AN_NumberTrip = 13, // Номер поездки + + SENSORS_AN_TripSpentFuel = 14, // Ср. расход за поездку + + SENSORS_AN_ANS1 = 15, // Отладочный датчик 1 + SENSORS_AN_ANS2 = 16, // Отладочный датчик 2 + SENSORS_AN_ANS3 = 17, // Отладочный датчик 3 + SENSORS_AN_ANS4 = 18, // Отладочный датчик 4 + SENSORS_AN_ANS5 = 19, // Отладочный датчик 5 + + +} eSensorsAn; + + +/* +typedef enum { + SENSORS_AN_Uptime = 0, // Время работы прибора в минутах, после последней перезагрузки/включения + SENSORS_AN_ExternalTemperature = 1, // Внешняя температура, С + SENSORS_AN_FuelLevel = 2, // Уровень топлива, л + SENSORS_AN_VehicleStatus = 3, // Статус автомобиля + SENSORS_AN_TripMileage = 4,// Пробег поездки + SENSORS_AN_AverageSpeed = 5,// Средняя скорость + SENSORS_AN_MinutesOfTravel = 6,// Минут поездки (сборная), у нас сейчас СЕКУНД !!!! + SENSORS_AN_EngineHours = 7,// Моточасы + SENSORS_AN_CarMileageAfterBCReset = 8,// Пробег авто после сброса БК + SENSORS_AN_AverageSpeedAfterBCReset = 9,// Средняя скорость после сброса БК + SENSORS_AN_TimeAfterBCReset = 10,// Время после сброса БК + SENSORS_AN_Voltage12Volts = 11, // Напряжение АКБ 12В + SENSORS_AN_NumberOfSatellites = 12,// Кол-во спутников, у нас сейчас не ИСПОЛЬЗУЕТСЯ !!! + SENSORS_AN_RSSI = 13,// RSSI (GSM Network) + SENSORS_AN_NetworkType = 14,// Network type + SENSORS_AN_NumberAccelerations = 15, // Количество ускорений за поездку + SENSORS_AN_NumberBraking = 16, // Количество торможений за поездку + SENSORS_AN_NumberAccelerationsAfterReset = 17, // Количество ускорений после сброса + SENSORS_AN_NumberBrakingAfterReset = 18, // Количество торможений после сброса + SENSORS_AN_NumberLateralAccelerations = 19, // Количество боковых ускорений за поездку + SENSORS_AN_NumberLateralAccelerationsAfterReset = 20, // Количество боковых ускорений после сброса + SENSORS_AN_NumberSpeedViolations = 21, // Количество нарушений скорости за поездку + SENSORS_AN_NumberSpeedViolationsAfterReset = 22, // Количество нарушений скорости после сброса + SENSORS_AN_EngineOXTemperature = 23, // Температура ОХ двигателя + SENSORS_AN_EngineOilTemperature = 24, // Температура масла двигателя + + SENSORS_AN_ANS1 = 25, // Отладочный датчик 1 + SENSORS_AN_ANS2 = 26, // Отладочный датчик 2 + SENSORS_AN_ANS3 = 27, // Отладочный датчик 3 + SENSORS_AN_ANS4 = 28, // Отладочный датчик 4 + SENSORS_AN_ANS5 = 29, // Отладочный датчик 5 + SENSORS_AN_NumberTrip = 30 // Номер поездки + +} eSensorsAn; +*/ + +/* +typedef enum { + SENSORS_DIG_VehicleAlarmSystemActivateSirenOnOff = 0, // Vehicle Alarm System activate siren + SENSORS_DIG_VehicleAlarmSystemActivateSirenGuarded = 1, // Состояние охранной сигнализации + + SENSORS_DIG_BatteryChargeStatus = 2, // Статус заряда АКБ + + SENSORS_DIG_PL_DoorStatus = 3, // Статус ПЛ двери + SENSORS_DIG_PP_DoorStatus = 4, // Статус ПП двери + SENSORS_DIG_ZL_DoorStatus = 5, // Статус ЗЛ двери + SENSORS_DIG_ZP_DoorStatus = 6, // Статус ЗП двери + SENSORS_DIG_HoodStatus = 7, // Статус капота + + SENSORS_DIG_WasherFluidLevel = 8, // Уровень омывающей жидкости + SENSORS_DIG_CoolantLevel = 9, // Уровень охлаждающей жидкости + SENSORS_DIG_PL_Window = 10, // Окно ПЛ + SENSORS_DIG_PP_Window = 11, // Окно ПП + SENSORS_DIG_ZL_Window = 12, // Окно ЗЛ + SENSORS_DIG_ZP_Window = 13, // Окно ЗП + + SENSORS_DIG_PL_TirePressureSensorBatteryStatus = 14, // Состояние батареи датчика давления шины ПЛ + SENSORS_DIG_PP_TirePressureSensorBatteryStatus = 15, // Состояние батареи датчика давления шины ПП + SENSORS_DIG_ZL_TirePressureSensorBatteryStatus = 16, // Состояние батареи датчика давления шины ЗЛ + SENSORS_DIG_ZP_TirePressureSensorBatteryStatus = 17, // Состояние батареи датчика давления шины ЗП + + SENSORS_DIG_BodyCanBusStatus = 18, // Статус шины BodyCan + SENSORS_DIG_DiagCanBusStatus = 19, // Статус шины DiagCan +} eSensorsDig; + +typedef enum { + SENSORS_AN_BatteryVoltage = 0, // Напряжение АКБ 12В + SENSORS_AN_Uptime = 1, // Время работы прибора в минутах, после последней перезагрузки/включения + SENSORS_AN_TemperatureInsideCabinFront = 2, // Температура внутри салона (передняя), С + SENSORS_AN_TemperatureInsideCabinBack = 3, // Температура внутри салона (задняя), С + SENSORS_AN_BatterySoH = 4, // SoH АКБ, % + SENSORS_AN_BatterySoC = 5, // SoC АКБ, % + SENSORS_AN_ExternalTemperature = 6, // Внешняя температура, С + SENSORS_AN_FuelLevel = 7, // Уровень топлива, л + SENSORS_AN_VehicleStatus = 8, // Статус автомобиля + SENSORS_AN_DoorLockStatus = 9, // Статус замков дверей + SENSORS_AN_TrunkStatus = 10, // Статус багажника (задняя дверь) + SENSORS_AN_WedFuelConsumptionAfterBK = 11,// Ср. расход топлива после БК + SENSORS_AN_WedRipExpense = 12,// Ср. расход за поездку + SENSORS_AN_TripMileage = 13,// Пробег поездки + SENSORS_AN_AverageSpeed = 14,// Средняя скорость + SENSORS_AN_MinutesOfTravel = 15,// Минут поездки (сборная) + SENSORS_AN_AutomaticTransmissionLeverPosition = 16, // Положение рычага АКПП + SENSORS_AN_DaysUntilMintenance = 17, // Дней до ТО + SENSORS_AN_MileageBeforeMaintenance = 18, // Пробег до ТО + SENSORS_AN_OilLevelInEngine = 19,// Уровень масла в двигателе + SENSORS_AN_EngineOilLevelIndicator = 20, // Индикатор уровня масла двигателя + SENSORS_AN_TirePressurePL = 21,// давление в шине ПЛ + SENSORS_AN_TirePressurePP = 22,// давление в шине ПП + SENSORS_AN_TirePressureZL = 23,// давление в шине ЗЛ + SENSORS_AN_TirePressureZP = 24,// давление в шине ЗП + SENSORS_AN_PLBusStatus = 25,// Состояние шины ПЛ + SENSORS_AN_TireConditionPP = 26,// Состояние шины ПП + SENSORS_AN_TireConditionZL = 27,// Состояние шины ЗЛ + SENSORS_AN_TireConditionZP = 28,// Состояние шины ЗП + SENSORS_AN_TargetTempCCUdriver = 29,// Целевая темп. CCU водитель + SENSORS_AN_TargetTempCCUPP = 30,// Целевая темп. CCU П-П + SENSORS_AN_TargetTempCCUZLPP = 31,// Целевая темп. CCU ЗЛ-П + SENSORS_AN_TargetTempCCUZPPP = 32,// Целевая темп. CCU ЗП-П + SENSORS_AN_EngineHours = 33,// Моточасы + SENSORS_AN_CarMileageAfterBCReset = 34,// Пробег авто после сброса БК + SENSORS_AN_AverageSpeedAfterBCReset = 35,// Средняя скорость после сброса БК + SENSORS_AN_TimeAfterBCReset = 36,// Время после сброса БК + SENSORS_AN_MileageOnRemainingFuel = 37,// Пробег на остатке топлива + SENSORS_AN_SoHHVBattery = 38,// SoH HV АКБ, % + SENSORS_AN_SoCHVBattery = 39,// SoC HV АКБ, % + SENSORS_AN_DriverSeatOccupancy = 40,// Занятость кресла водителя + SENSORS_AN_ChairOccupancyPP = 41,// Занятость кресла ПП + SENSORS_AN_ChairOccupancyZL = 42,// Занятость кресла ЗЛ + SENSORS_AN_ChairOccupancyZP = 43,// Занятость кресла ЗП + SENSORS_AN_NumberOfSatellites = 44,// Кол-во спутников + SENSORS_AN_RSSI = 45,// RSSI (GSM Network) + SENSORS_AN_NetworkType = 46,// Network type +} eSensorsAn; +*/ +bool EgtsProcessing_SendAuth(tEgtsProcessing *env); + +bool EgtsProcessing_SendSensors(tEgtsProcessing *env, bool isStorage); + +bool EgtsProcessing_SendFirmware(tEgtsProcessing *env); + +void EgtsProcessing_Default_SendSensorsDig(tEgtsProcessing *env); + +void EgtsProcessing_Default_SendSensorsAn(tEgtsProcessing *env); + +bool EgtsProcessing_SendCommandConfirmation(tEgtsProcessing *env, + uint8_t cmdType, + uint8_t cmdConfirmationType, + uint32_t cmdId, + uint32_t srcId, + + uint16_t address, + uint8_t size, + uint8_t act, + uint16_t cmd, + + uint8_t *DT, + uint16_t DT_SIZE); + +#endif //SMART_COMPONENTS_EGTSOUTPUTCOMMANDS_H diff --git a/EgtsProcessing.c b/EgtsProcessing.c new file mode 100644 index 0000000..6b5c370 --- /dev/null +++ b/EgtsProcessing.c @@ -0,0 +1,1807 @@ +// +// Created by cfif on 21.05.23. +// + +#include +#include +#include +#include +#include +#include +#include +#include "EgtsProcessing.h" +#include "stddef.h" +#include "AtGsm_GetTime.h" +#include "EgtsInputCommands.h" +#include "EgtsOutputCommands.h" +#include "CarPositionUpdate.h" +#include "egtsWorkerExt.h" +#include "LoggerToSerialPort.h" +#include "string.h" +#include "AtGsmSimComA7600_SSL_LOAD_CA.h" +#include "Certs.h" +#include "FirmwareLoader.h" +#include "EgtsTeledataPoint.h" +#include "GsmWithGnss_Info.h" +#include "EgtsEbu.h" +#include "Network.h" +#include "AtGsm_NetworkRegistrationStatus.h" +#include "egts.h" +#include "AtGsmOperatorSelection.h" +#include "ext_telematica.h" +#include "lfs_file_utils.h" +#include "ld_adr.h" +#include "SerialPortCanComInt.h" +#include "AtGsmSimcomSim7600.h" + + +#define LOG_SIGN "EGTS" +#define LOGGER &env->slog->logger + +bool onOffTelematica(tEgtsProcessing *env, bool *oneOn, bool *oneOff, char *task) { + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + + if (*oneOff) { + *oneOn = true; + *oneOff = false; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "%s - отключена", task); + } + + SystemDelayMs(1000); + + return true; + + } else { + if (*oneOn) { + *oneOn = false; + *oneOff = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "%s - включена", task); + } + } + + return false; +} + +void EgtsProcessing_TransmitterTaskMain(tEgtsProcessing *env); + +void EgtsProcessing_ListenerTask(tEgtsProcessing *env); + +char *sendLogHex(tEgtsProcessing *env, uint8_t *data, size_t size) { + memset(env->hexString, 0, sizeof(env->hexString)); + size_t len = 0; + vAsciiStringAddBytesAsHex(env->hexString, &len, data, size); + + LoggerStrInfo(LOGGER, LOG_SIGN, env->hexString, strlen(env->hexString)); + + return env->hexString; +} + +size_t EgtsProcessing_WorkerRead(tEgtsProcessing *env, uint8_t *data, size_t size) { + if (env->socketId != SOCKET_WRONG_CONTEXT) { + return SocketInterface_read(&env->gsm->socketIO, env->socketId, data, size, 2000); + } + + return 0; +} + +uint8_t findDelimiter(tString32 *address, char ch) { + + for (uint8_t i = 0; i < address->length; ++i) { + if (address->data[i] == ch) + return i; + } + + return 0; +} + +eEgtsCertsStatus changeServer(tEgtsProcessing *env, uint8_t numberServer) { + tIsFind check; + memset(&check, 0, sizeof(check)); + + env->numberServer = numberServer; + + + if (osMutexAcquire(env->gsm->gsmAt->access, 30000) == osOK) { + + if (numberServer == 0) { + + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.data[env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.length] = '\0'; + uint8_t pos = findDelimiter(&env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS, ':'); + String32Copy(&env->srvAddr, + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.data, + pos); + env->srvPort = atoi(&env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.data[pos + 1]); + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Установка сервера: %s", + env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.data); + + + env->clientType = eAtGsmSimComA7600_SslType_TCP; + + if (env->deviceTeledataStorageData->telematica.EGTS_SERVER_SSL_ENABLE) { + + env->clientType = eAtGsmSimComA7600_SslType_TLS; + + check = AtGsmSimComA7600_SSL_CHECK_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + file_crt, strlen(file_crt), + file_key, strlen(file_key), 2000); + + + if ((!check.isFind1) || (!check.isFind2) || (!check.isFind3)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ключи аутентификации не загружены") + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_UNLOAD; + } +/* + if (isCertTest() == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ключи аутентификации не загружены") + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_UNLOAD; + } +*/ + + if (AtGsmSimComA7600_SSL_CfgContext(env->gsm->gsmAt, eAtGsmSimComA7600_SslCfgType_STR, + "cacert", sizeof("cacert") - 1, 2, + (char *) file_ca, strlen(file_ca)) != AT_OK) { + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_ERROR; + } + + if (AtGsmSimComA7600_SSL_CfgContext(env->gsm->gsmAt, eAtGsmSimComA7600_SslCfgType_STR, + "clientcert", sizeof("clientcert") - 1, 2, + (char *) file_crt, strlen(file_crt)) != AT_OK) { + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_ERROR; + } + + if (AtGsmSimComA7600_SSL_CfgContext(env->gsm->gsmAt, eAtGsmSimComA7600_SslCfgType_STR, + "clientkey", sizeof("clientkey") - 1, 2, + (char *) file_key, strlen(file_key)) != AT_OK) { + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_ERROR; + } + + if (AtGsmSimComA7600_SSL_CfgContext(env->gsm->gsmAt, eAtGsmSimComA7600_SslCfgType_INT, + "ciphersuites", sizeof("ciphersuites") - 1, 2, + "0xFFFF", sizeof("0xFFFF") - 1) != AT_OK) { + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_ERROR; + } + + if (AtGsmSimComA7600_SSL_CfgContext(env->gsm->gsmAt, eAtGsmSimComA7600_SslCfgType_INT, + "authmode", sizeof("authmode") - 1, 2, + "2", sizeof("2") - 1) != AT_OK) { + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_ERROR; + } + + AtGsmSimComA7600_PdpActivate(env->gsm->gsmAt, 1); + + + AtGsmSimComA7600_DefinePdpAuthContext(env->gsm->gsmAt, 1, 1, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_PASS.data, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_PASS.length, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_USER.data, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_USER.length); + + + AtGsmSimComA7600_DefinePdpContext(env->gsm->gsmAt, 1, AtGsmSimComA7600_PdpType_IP, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.data, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.length); + + AtGsmSimComA7600_PdpActivate(env->gsm->gsmAt, 1); + + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_LOAD; + + } else { + + AtGsmSimComA7600_PdpActivate(env->gsm->gsmAt, 1); + AtGsmSimComA7600_DefinePdpContext(env->gsm->gsmAt, 1, AtGsmSimComA7600_PdpType_IP, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.data, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.length); + + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_LOAD; + } + + + } else { + + env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.data[env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.length] = '\0'; + uint8_t pos = findDelimiter(&env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS, ':'); + String32Copy(&env->srvAddr, + env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.data, + pos); + env->srvPort = atoi(&env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.data[pos + 1]); + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Установка сервера: %s", + env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.data); + + + env->clientType = eAtGsmSimComA7600_SslType_TCP; + + AtGsmSimComA7600_PdpActivate(env->gsm->gsmAt, 1); + AtGsmSimComA7600_DefinePdpContext(env->gsm->gsmAt, 1, AtGsmSimComA7600_PdpType_IP, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.data, + env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.length); + + osMutexRelease(env->gsm->gsmAt->access); + return CERTS_STATUS_LOAD; + + + } + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (changeServer)") + + return CERTS_STATUS_ERROR; + } + + +} + + +bool checkEbuFile(tEgtsProcessing *env, char *filename, uint32_t size) { + int lfs_err; + lfs_file_t file; + + if (size <= 4) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Ошибка размера файла, удаление файла: %s", filename) + lfs_err = lfs_remove(&env->fs->lfs, filename); + return false; + } + + lfs_err = lfs_file_open(&env->fs->lfs, &file, filename, LFS_O_RDONLY); + lfs_err = lfs_file_rewind(&env->fs->lfs, &file); + int reading = lfs_file_read(&env->fs->lfs, &file, env->wb, size); + + uint32_t crc = *(uint32_t *) &env->wb[size - 4]; + + uint32_t crcCalc = lfs_crc(0, env->wb, size - 4); + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + if (crc != crcCalc) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Ошибка CRC файла, удаление файла: %s", filename) + lfs_err = lfs_remove(&env->fs->lfs, filename); + return false; + } + + uint32_t versionEbu = *(uint32_t *) env->wb; + if (VERSION_EBU != versionEbu) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Не совпала версия файла, удаление файла: %s", filename) + lfs_err = lfs_remove(&env->fs->lfs, filename); + return false; + } + + return true; +} + +void EgtsProcessing_Init( + tEgtsProcessing *env, + tGsmWithGnss *gsm, + tRtcIO *rtcIO, + tLittleFileFs *fs, + tLoggerToSerialPort *slog +) { + env->egtsEnv.readData = (void *) EgtsProcessing_WorkerRead; + env->egtsEnv.readDataEnv = env; + env->egtsEnv.workingBuffer = env->wb; + env->egtsEnv.workingBufferLimit = sizeof(env->wb); + env->egtsEnv.workingBufferLength = 0; + env->gsm = gsm; + env->slog = slog; + env->fs = fs; + env->ebuReady = false; + + env->TelematicaServerNotActiveWaitTime = 0; + + env->rtc = rtcIO; + + env->isEnableTelematicaSendPoints = false; + env->rebootFirmware = false; + env->egtsPacketId = 0; + + env->egtsCanEnv.isEbuData = false; + + env->fl_firstStartTimeUpdateEBU = false; + + env->deviceTeledataStorageData = (tDeviceTeledataStorageData *) EXT_ENV_TELE.store.dataTeledata; + + env->isOneEBU = false; + + env->SENSORS_AN_MinutesOfTravel_gl = 0; + + CarEventResetPosition(env); + + EgtsProcessing_Default_SendSensorsDig(env); + EgtsProcessing_Default_SendSensorsAn(env); + + + uint32_t SENSORS_AN_NumberTrip_loc = 0; + + for (uint8_t i = 0; i < 24; ++i) { + uint32_t bit = EXT_ENV_TELE.vccIo->get(EXT_ENV_TELE.vccIo->env, 5) & 1; + SENSORS_AN_NumberTrip_loc |= (bit << i); + } + + if (SENSORS_AN_NumberTrip_loc == 0) { + + time_t timestamp; + RtcGet(rtcIO, ×tamp); + + SENSORS_AN_NumberTrip_loc = (uint32_t) timestamp; + } + + if (SENSORS_AN_NumberTrip_loc == 0) { + SENSORS_AN_NumberTrip_loc = 1; + } + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberTrip].value = SENSORS_AN_NumberTrip_loc; + + env->egtsTeledataAdditionalData.queue = osMessageQueueNew(TELEDATA_QUEUE_SIZE, sizeof(tEgtsTeledata), NULL); + env->egtsTeledataAdditionalData.queueEvent = osMessageQueueNew(TELEDATA_QUEUE_SIZE, 1, NULL); + env->egtsCommandConfirmationAdditionalData.queue = osMessageQueueNew(COMMAND_QUEUE_SIZE, sizeof(tEgtsCommand), + NULL); + + memset(&env->egtsTeledataEdit.egtsExtPositionDataArgs, 0, sizeof(tEgtsExtPositionDataArgs)); + env->egtsTeledataEdit.egtsExtPositionDataArgs.FLG.NSFE = 1; + env->egtsTeledataEdit.egtsExtPositionDataArgs.FLG.SFE = 1; + + int lfs_err; + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Сканирование файловой системы:"); + + struct lfs_info info; + lfs_dir_t dir; + + lfs_err = lfs_dir_open(&env->fs->lfs, &dir, ""); + lfs_err = lfs_dir_rewind(&env->fs->lfs, &dir); + + bool isEbuFileCheck = false; + + while (lfs_dir_read(&env->fs->lfs, &dir, &info) > 0) { + if (info.name[0] == '.') + continue; + + if (info.type == LFS_TYPE_DIR) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Директория: %s", info.name); + + lfs_err = lfs_remove(&env->fs->lfs, info.name); +/* + struct lfs_info sub_dir_info; + lfs_dir_t sub_dir; + + lfs_err = lfs_dir_open(&env->fs->lfs, &sub_dir, info.name); + lfs_err = lfs_dir_rewind(&env->fs->lfs, &sub_dir); + + while (lfs_dir_read(&env->fs->lfs, &sub_dir, &sub_dir_info) > 0) { + if (sub_dir_info.name[0] == '.') + continue; + + char filename[32]; + + filename[0] = '\0'; + strcat(filename, info.name); + strcat(filename, "/"); + strcat(filename, sub_dir_info.name); + + if (checkFile(env, filename, sub_dir_info.size)) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, " Файл: %s - OK", sub_dir_info.name); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, " Файл: %s - ERROR", sub_dir_info.name); + } + } + + lfs_err = lfs_dir_close(&env->fs->lfs, &sub_dir); +*/ + } else { + + if (memcmp(info.name, "points.bin", sizeof("points.bin") - 1) == 0) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл точек: %s - OK", info.name); + } else if (memcmp(info.name, "ebu.bin", sizeof("ebu.bin") - 1) == 0) { + + if (checkEbuFile(env, info.name, info.size)) { + isEbuFileCheck = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл настроек ЭБУ: %s - OK", info.name); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл настроек ЭБУ: %s - ОШИБКА (удален)", info.name); + } + + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл неизвестен: %s - УДАЛЕН", info.name); + lfs_err = lfs_remove(&env->fs->lfs, info.name); + } + + } + + } + + if (!isEbuFileCheck) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Файл точек: points.bin - УДАЛЕН"); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + } + + lfs_dir_close(&env->fs->lfs, &dir); + +/* + int lfs_err = lfs_mkdir(&env->fs->lfs, "points"); + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Сканирование файловой системы:"); + + struct lfs_info info; + lfs_dir_t dir; + + lfs_err = lfs_dir_open(&env->fs->lfs, &dir, ""); + lfs_err = lfs_dir_rewind(&env->fs->lfs, &dir); + + while (lfs_dir_read(&env->fs->lfs, &dir, &info) > 0) { + if (info.name[0] == '.') + continue; + + if (info.type == LFS_TYPE_DIR) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Директория: %s", info.name); + + struct lfs_info sub_dir_info; + lfs_dir_t sub_dir; + + lfs_err = lfs_dir_open(&env->fs->lfs, &sub_dir, info.name); + lfs_err = lfs_dir_rewind(&env->fs->lfs, &sub_dir); + + while (lfs_dir_read(&env->fs->lfs, &sub_dir, &sub_dir_info) > 0) { + if (sub_dir_info.name[0] == '.') + continue; + + char filename[32]; + + filename[0] = '\0'; + strcat(filename, info.name); + strcat(filename, "/"); + strcat(filename, sub_dir_info.name); + + if (checkFile(env, filename, sub_dir_info.size)) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, " Файл: %s - OK", sub_dir_info.name); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, " Файл: %s - ERROR", sub_dir_info.name); + } + } + + lfs_err = lfs_dir_close(&env->fs->lfs, &sub_dir); + + } else { + if (checkFile(env, info.name, info.size)) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл: %s - OK", info.name); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Файл: %s - ERROR", info.name); + } + + } + + } + + lfs_dir_close(&env->fs->lfs, &dir); +*/ + + SystemMutexCmsis_init(&env->accessEbu, NULL); + loadEbuTable(env); + +// setBufEbu(env); + + + eCanBaudRate can1BaudRate = CAN_BAUD_RATE_500K; + + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN1_BAUD_RATE == 125000) + can1BaudRate = CAN_BAUD_RATE_125K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN1_BAUD_RATE == 500000) + can1BaudRate = CAN_BAUD_RATE_500K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN1_BAUD_RATE == 250000) + can1BaudRate = CAN_BAUD_RATE_250K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN1_BAUD_RATE == 100000) + can1BaudRate = CAN_BAUD_RATE_1000K; + + eCanBaudRate canBaudRate; + EXT_ENV_TELE.CanPort_GetSpeed(CAN1, &canBaudRate); + + if (canBaudRate != can1BaudRate) { + EXT_ENV_TELE.CanPort_SetSpeed(CAN1, can1BaudRate); + } + + eCanBaudRate can2BaudRate = CAN_BAUD_RATE_500K; + + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN2_BAUD_RATE == 125000) + can2BaudRate = CAN_BAUD_RATE_125K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN2_BAUD_RATE == 500000) + can1BaudRate = CAN_BAUD_RATE_500K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN2_BAUD_RATE == 250000) + can2BaudRate = CAN_BAUD_RATE_250K; + if (env->deviceTeledataStorageData->telematica.EGTS_UNIT_CAN2_BAUD_RATE == 100000) + can2BaudRate = CAN_BAUD_RATE_1000K; + + EXT_ENV_TELE.CanPort_GetSpeed(CAN2, &canBaudRate); + + if (canBaudRate != can2BaudRate) { + EXT_ENV_TELE.CanPort_SetSpeed(CAN2, can2BaudRate); + } + + + +/* + can_filter_init_type can_filter0_init_struct; + can_filter_init_type can_filter1_init_struct; + + can_filter0_init_struct.filter_activate_enable = TRUE; + can_filter0_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter0_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter0_init_struct.filter_number = 0; + can_filter0_init_struct.filter_bit = CAN_FILTER_32BIT; + can_filter0_init_struct.filter_id_high = 0x380 << 5; + can_filter0_init_struct.filter_id_low = 0; + can_filter0_init_struct.filter_mask_high = 0x7FF << 5; + can_filter0_init_struct.filter_mask_low = 0; + + can_filter1_init_struct.filter_activate_enable = TRUE; + can_filter1_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter1_init_struct.filter_fifo = CAN_FILTER_FIFO1; + can_filter1_init_struct.filter_number = 1; + can_filter1_init_struct.filter_bit = CAN_FILTER_32BIT; + can_filter1_init_struct.filter_id_high =0x3e8 << 5; + can_filter1_init_struct.filter_id_low = 0; + can_filter1_init_struct.filter_mask_high = 0x7FF << 5; + can_filter1_init_struct.filter_mask_low = 0; + + EXT_ENV_TELE.CanPort_SetFilter(CAN2, &can_filter0_init_struct, &can_filter1_init_struct); +*/ + + can_filter_init_type can_filter0_init_struct; + can_filter_init_type can_filter1_init_struct; +/* + can_filter0_init_struct.filter_activate_enable = TRUE; + can_filter0_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter0_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter0_init_struct.filter_number = 0; + can_filter0_init_struct.filter_bit = CAN_FILTER_32BIT; + can_filter0_init_struct.filter_id_high = 0x7ca << 5; + can_filter0_init_struct.filter_id_low = 0; + can_filter0_init_struct.filter_mask_high = 0x7FF << 5; + can_filter0_init_struct.filter_mask_low = 0; +*/ + can_filter0_init_struct.filter_activate_enable = TRUE; + can_filter0_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter0_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter0_init_struct.filter_number = 0; + can_filter0_init_struct.filter_bit = CAN_FILTER_32BIT; + can_filter0_init_struct.filter_id_high = 0x700 << 5; + can_filter0_init_struct.filter_id_low = 0; + can_filter0_init_struct.filter_mask_high = 0x700 << 5; + can_filter0_init_struct.filter_mask_low = 0; + + can_filter1_init_struct.filter_activate_enable = TRUE; + can_filter1_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter1_init_struct.filter_fifo = CAN_FILTER_FIFO1; + can_filter1_init_struct.filter_number = 1; + can_filter1_init_struct.filter_bit = CAN_FILTER_32BIT; + can_filter1_init_struct.filter_id_high = 0; + can_filter1_init_struct.filter_id_low = 0; + can_filter1_init_struct.filter_mask_high = 0; + can_filter1_init_struct.filter_mask_low = 0; + + EXT_ENV_TELE.CanPort_SetFilter(CAN2, &can_filter0_init_struct, &can_filter1_init_struct); + + + InitThreadBlock(env->T_processing_Network, "Network", osPriorityNormal); + + InitThreadBlock(env->T_processing_input_command, "EgtsPrcInputCom", osPriorityNormal); + InitThreadBlock(env->T_processing_ebu, "EgtsPrcEbu", osPriorityNormal); + + InitThreadBlock(env->T_processing_event_teledata, "EgtsPrcEventTel", osPriorityNormal); + InitThreadBlock(env->T_processing_teledata, "EgtsPrcTeledata", osPriorityNormal); + + InitThreadBlock(env->T_processing_main, "EgtsPrcMain", osPriorityNormal); + + InitThreadBlock(env->T_listener, "EgtsListner", osPriorityNormal); + + SystemMutexCmsis_init(&env->txCanAccessQueue, NULL); + + CanMain_Init( + &env->CanMain, + env->deviceTeledataStorageData, + EXT_ENV_TELE.Can2_IO, + env->txCanAccessQueue, + EXT_ENV_TELE.testsTable, + env->slog, + &env->rawAccel, + &env->egtsTeledataEdit + ); + + CanMainMute_Init( + &env->CanMainMute, + EXT_ENV_TELE.Can2_IO, + env->txCanAccessQueue, + env->gsm, + env->slog + ); + + vSerialPortCanComInit(&env->tSerialPortCanComInt, + EXT_ENV_TELE.Can2_IO, + 256); + + env->serialPortCanComIntIO = vSerialPortCanComIntGetIo(&env->tSerialPortCanComInt); + + CanMainAdditional_Init( + &env->CanMainAdditional, + EXT_ENV_TELE.Can2_IO, + &env->tSerialPortCanComInt, + &env->CanMainMute, + env->txCanAccessQueue, + EXT_ENV_TELE.testsTable, + env->slog, + &env->rawAccel, + &env->egtsTeledataEdit, + &env->ebuState, + env->accessEbu, + &env->CanMain, + env, + &env->isEnableTelematicaSendPoints + ); + + + CanMainTest_Init( + &env->CanMainTest, + EXT_ENV_TELE.Can1_IO, + env->slog + ); + +} + +void EgtsProcessing_Start(tEgtsProcessing *env) { + + ThreadBlock_Start(env->T_processing_Network, env, EgtsProcessing_InfoTask); + + ThreadBlock_Start(env->T_processing_input_command, env, EgtsProcessing_TransmitterTaskInputCommand); + ThreadBlock_Start(env->T_processing_ebu, env, EgtsProcessing_TransmitterTaskEbu); + ThreadBlock_Start(env->T_processing_event_teledata, env, EgtsProcessing_EventTaskTeledata); + ThreadBlock_Start(env->T_processing_teledata, env, EgtsProcessing_TransmitterTaskTeledata); + + ThreadBlock_Start(env->T_processing_main, env, EgtsProcessing_TransmitterTaskMain); + ThreadBlock_Start(env->T_listener, env, EgtsProcessing_ListenerTask); + +} + +void EgtsProcessingCloseConnection(tEgtsProcessing *env) { + SocketInterface_close(&env->gsm->socketIO, env->socketId); + env->gsm->slots[0].addr.length = 0; +} + +bool EgtsProcessingSend(tEgtsProcessing *env, uint8_t *egtsRaw, uint16_t egtsRawLength, + eEgtsSendWait wait, volatile bool *wait1, volatile bool *wait2) { + + + uint32_t retry = env->deviceTeledataStorageData->telematica.EGTS_SERVER_PACKET_RETRANSMIT_ATTEMPTS; + + while (retry) { + + bool result = true; + + if (SocketInterface_send(&env->gsm->socketIO, env->socketId, egtsRaw, egtsRawLength, + defaultSocketTransmiteTimeout) != egtsRawLength) { + result = false; + } + + if (!result) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка отправки пакета (ошибка сокета)"); + return false; + } + + if (wait == EGTS_WAIT_0) + return result; + + uint32_t timeEnd = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_SERVER_PACKET_TOUT * 1000; + + while (timeEnd > SystemGetMs()) { + + if (wait == EGTS_WAIT_1) { + if (*wait1) { + return true; + } + } + + if (wait == EGTS_WAIT_2) { + if ((*wait1) && (*wait2)) { + return true; + } + } + + SystemDelayMs(1); + } + + --retry; + + if (!isAuth(env)) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка отправки пакета (ошибка аутентификации)"); + return false; + } + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Повторная отправка, осталось попыток: %d", retry); + } + + return false; +} + + +bool EgtsProcessing_SendResponse(tEgtsProcessing *env, + eEgtsServiceId sourceServiceId, + eEgtsServiceId recipientServiceId, + uint8_t srvFlags, + uint8_t rst, + uint16_t crn) { + uint8_t egtsRaw[256]; + memset(egtsRaw, 0, sizeof(egtsRaw)); + + if (env->socketId == SOCKET_WRONG_CONTEXT) { + return false; + } + + time_t timestamp; + RtcGet(env->gsm->Rtc, ×tamp); + + tEgtsRecordResponseData args = { + .CRN = crn, + .RST = rst, + }; + + ++env->egtsPacketId; + uint16_t packetResponseLength = vEgtsPackTransport( + env->egtsEnv.header.packetId, + env->egtsPacketId, + egtsRaw, + srvFlags, + EGTS_PT_RESPONSE, + sourceServiceId, + recipientServiceId, + timestamp, + EGTS_SR_RECORD_RESPONSE, + vEgtsPackResponseGen, + &args + ); + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Отправка пакета подтверждения:"); + sendLogHex(env, egtsRaw, packetResponseLength); + + EgtsProcessingSend(env, egtsRaw, packetResponseLength, EGTS_WAIT_0, NULL, NULL); + + return true; +} + +uint8_t EgtsProcessingOpenConnection(tEgtsProcessing *env) { + + AtGsmSimComA7600_PdpActivate(env->gsm->gsmAt, 1); + + env->socketId = SocketInterface_open( + &env->gsm->socketIO, + eSocketType_TCP, + env->clientType, + env->srvAddr.data, + env->srvAddr.length, + env->srvPort, + defaultSocketOpenTimeout + ); + + if (env->socketId == SOCKET_WRONG_CONTEXT) { + return SOCKET_WRONG_CONTEXT; + } + + return env->socketId; +} + +bool isAuth(tEgtsProcessing *env) { + + if ((env->egtsIdentityAdditionalData.isReceivedResponse) && + (env->egtsIdentityAdditionalData.isReceivedResultCode)) { + if (env->egtsIdentityAdditionalData.resultCodeAuth == 0) { + return true; + } + } + + return false; +} + + +bool WaitNetworkRegistration(tEgtsProcessing *env, uint16_t timeReg) { + + uint32_t timeEnd = SystemGetMs() + timeReg; + + tAtGsm_NetworkRegistrationReportMode mode; + tAtGsm_NetworkRegistrationState state; + + while (timeEnd > SystemGetMs()) { + + AtCommandResult result = AT_TIMEOUT; + if (osMutexAcquire(env->gsm->gsmAt->access, 2000) == osOK) { + result = AtGsm_NetworkRegistrationStatus(env->gsm->gsmAt, &mode, &state); + osMutexRelease(env->gsm->gsmAt->access); + } + + if (result) { + if (state == AT_NETWORK_REGISTRATION_STATE_REGISTERED_HOME || + state == AT_NETWORK_REGISTRATION_STATE_REGISTERED_ROAMING) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена регистрация") + + return true; + } + } + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + return AT_TIMEOUT; + } + + SystemDelayMs(100); + } + + return false; +} + +bool NetworkRequire(tEgtsProcessing *env) { + bool result = false; + + if (!WaitNetworkRegistration(env, 2000)) { + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + return false; + } + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Включение регистрации в сети"); + for (uint8_t i = 0; i < 3; ++i) { + + if (osMutexAcquire(env->gsm->gsmAt->access, 2000) == osOK) { + AtGsm_OperatorSelectionAutomatic(env->gsm->gsmAt); + osMutexRelease(env->gsm->gsmAt->access); + } + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + return false; + } + + SystemDelayMs(100); + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ждем сеть..."); + if (WaitNetworkRegistration(env, 2000)) { + result = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети получена"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети не получена"); + } + + } else { + result = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети присутствует"); + } + + + return result; +} + +void EventUpdateFirmwareFunc(void *envMma, bool result, bool isAbortOld) { + + tEgtsProcessing *env = (tEgtsProcessing *) envMma; + + if (result) { + + if (isAbortOld) { + + if (env->gsmFirmware.firmwareType == FIRMWARE_UVEOS) { + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Прошивка не загружена. Обновленная версия УВЭОС уже установлена") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Прошивка не загружена. Обновленная версия ТЕЛЕМАТИКИ уже установлена") + } + + /* + if (env->gsmFirmware.firmwareType == FIRMWARE_UVEOS) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Прошивка не загружена. Обновленная версия УВЭОС уже установлена") + + InitGsmFirmware(&env->gsmFirmware, + env->gsm->gsmAt, + FIRMWARE_TELE, + env->firmware_buf, + &env->firmwareStats, + &env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN, + &env->deviceTeledataStorageData->telematica.UPDATE_SERVER_ADDRESS, + env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS, + env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_PERIOD, + EXT_ENV_TELE.store.accessDumper, + false, + EventUpdateFirmwareFunc, + env, + env->slog); + + StartUpdateFirmware(&env->gsmFirmware); + } else { + + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Прошивка не загружена. Обновленная версия ТЕЛЕМАТИКИ уже установлена") + } +*/ + } else { + + if (env->gsmFirmware.firmwareType == FIRMWARE_UVEOS) { + EXT_ENV_TELE.store.AdditionalSettings->REGION_SIZE_UPDATE = FIRMWARE_MAIN_AREA_LENGTH; + } + + if (env->gsmFirmware.firmwareType == FIRMWARE_TELE) { + EXT_ENV_TELE.store.AdditionalSettings->REGION_SIZE_UPDATE = FIRMWARE_TELE_AREA_LENGTH; + } + + env->deviceTeledataStorageData->telematica.UPDATE_UVEOS_UPDATE = false; + + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Прошивка загружена. Для применения новой прошивки перезагрузите устройство") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическая перезагрузка, через 5 сек"); + SystemDelayMs(5000); + NVIC_SystemReset(); + } + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Прошивка не загружена") + + env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS = env->gsmFirmware.attempts; + + if (env->gsmFirmware.attempts == 0) { + env->deviceTeledataStorageData->telematica.UPDATE_UVEOS_UPDATE = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Попытки исчерпаны. Обновление будет завершено после получения команды на обновление"); + } + + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + +// LoggerStrFormatInfo(LOGGER, LOG_SIGN, +// "Обновление будет завершено позже. Осталось попыток %d из %d", env->gsmFirmware.attempts, +// env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS); + + } + +} + +void wait_CHECK_IN_PERIOD(tEgtsProcessing *env) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Соединение с сервером не установлено, повторная попытка соединения, через %d сек", + env->deviceTeledataStorageData->telematica.EGTS_SERVER_CHECK_IN_PERIOD); + + for (uint32_t i = 0; + i < env->deviceTeledataStorageData->telematica.EGTS_SERVER_CHECK_IN_PERIOD; ++i) { + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + break; + } + + SystemDelayMs(1000); + } +} + +void result_CHECK_SOCKET(tEgtsProcessing *env) { + if (env->gsm->codeResultOpen == 15) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Ошибка рукопожатия, переход на альтернативный сервер"); + } + + if (env->gsm->codeResultOpen == 10) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Ошибка открытия сеанса, переход на альтернативный сервер"); + } + + if (env->gsm->codeResultOpen == 19) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Ошибка сертификатов, переход на альтернативный сервер"); + } + + if (env->gsm->codeResultOpen == 20) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Ошибка выполнения команды (возможно отключены услуги связи), переход на альтернативный сервер"); + } +} + +_Noreturn void EgtsProcessing_TransmitterTaskMain(tEgtsProcessing *env) { + + bool isFirstStart = true; + bool isRebootNav = false; + uint32_t timeTeleOff = 0; + uint8_t stepAuth = 3; + tGsmWithGnssTimeStamp gsmWithGnssTimeStamp; + gsmWithGnssTimeStamp.status = 'V'; + + //---начало-----------ОБНОВЛЕНИЕ УВЭОС------------------------------ + InitGsmFirmware(&env->gsmFirmware, + env->gsm->gsmAt, + FIRMWARE_UVEOS, + env->firmware_buf, + &env->firmwareStats, + &env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN, + &env->deviceTeledataStorageData->telematica.UPDATE_SERVER_ADDRESS, + env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS, + env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_PERIOD, + EXT_ENV_TELE.store.accessDumper, + false, + EventUpdateFirmwareFunc, + env, + env->slog); + + GsmFirmware_Start(&env->gsmFirmware); + +//---конец-----------ОБНОВЛЕНИЕ УВЭОС------------------------------ + + while (EXT_ENV_TELE.store.device->factoryMode == true) { + if (egtsProcessing.timeFact < SystemGetMs()) { + egtsProcessing.timeFact = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Режим производственного теста") + } + SystemDelayMs(1000); + } + + for (;;) { + if (env->deviceTeledataStorageData->telematica.EGTS_SERVER_ADDRESS.length == 0) { + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не установлен адрес сервера телематики") + } + SystemDelayMs(1000); + continue; + } + + if (env->deviceTeledataStorageData->telematica.EGTS_ALT_SERVER_ADDRESS.length == 0) { + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не установлен адрес альтернативного сервера телематики") + } + SystemDelayMs(1000); + continue; + } + + if (env->deviceTeledataStorageData->telematica.EGTS_GPRS_APN.length == 0) { + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не установлен APN") + } + SystemDelayMs(1000); + continue; + } + + break; + } + + uint8_t socketId = SOCKET_WRONG_CONTEXT; + eSocketStatus socketStatus = eSocketStatus_Disconnected; + + tIsFind check; + memset(&check, 0, sizeof(check)); + + eEgtsCertsStatus isLoad; + while (1) { + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON) { + + isLoad = changeServer(env, 0); + + if (isLoad != CERTS_STATUS_LOAD) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Внутренняя ошибка настройки модема. Повторная попытка 1") + isLoad = changeServer(env, 0); + } + + if (isLoad != CERTS_STATUS_LOAD) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Внутренняя ошибка настройки модема. Повторная попытка 2") + isLoad = changeServer(env, 0); + } + + if (isLoad != CERTS_STATUS_LOAD) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Внутренняя ошибка настройки модема") + break; + } else { + break; + } + } else { + SystemDelayMs(1000); + } + + } + + if (isLoad != CERTS_STATUS_LOAD) + changeServer(env, 1); + + uint32_t timeOutCheckConnect = 0; + uint32_t timeIsNetworkRegistration = 0; + uint32_t timeOutCheckNav = AURUS_CHECK_NAV; + uint8_t stepCheckNav = 3; + + bool isRegistration; + + while (1) { + +// LoggerInfoStatic(LOGGER, LOG_SIGN, "НОВАЯ ПРОШИВКА ТЕЛЕМАТИКИ") + +//---начало-----------ОБНОВЛЕНИЕ УВЭОС------------------------------ +// if (EXT_ENV_TELE.store.runtime->EGTS_UPDATE_UVEOS) { +// EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON = false; +// } +//---конец-----------ОБНОВЛЕНИЕ УВЭОС------------------------------- + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON) { + + +///---начало------------------------------------Проверка навигации на сбой приемника------------------------------------ + if (egtsProcessing.timeNavUpdate < SystemGetMs()) { + egtsProcessing.timeNavUpdate = SystemGetMs() + 10000; + + if (osMutexAcquire(env->gsm->gnssRmcGga.rmcAccess, 2000) == osOK) { + + if ((env->gsm->gnssRmcGga.isRMC_Active == false) || (env->gsm->gnssRmcGga.isGGA_Active == false)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружена остановка навигации") + isRebootNav = true; + } + + if ((env->gsm->gnssRmcGga.gsmWithGnssTimeStamp.status == 'A') && + (gsmWithGnssTimeStamp.status == 'A')) { + if (memcmp((void *) &env->gsm->gnssRmcGga.gsmWithGnssTimeStamp, (void *) &gsmWithGnssTimeStamp, + sizeof(tGsmWithGnssTimeStamp)) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружена остановка времени навигации") + isRebootNav = true; + } + } + + memcpy(&gsmWithGnssTimeStamp, &env->gsm->gnssRmcGga.gsmWithGnssTimeStamp, + sizeof(tGsmWithGnssTimeStamp)); + env->gsm->gnssRmcGga.isRMC_Active = false; + env->gsm->gnssRmcGga.isGGA_Active = false; + + osMutexRelease(env->gsm->gnssRmcGga.rmcAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата доступа timeNavUpdate") + } + + if (isRebootNav) { + isRebootNav = false; + if (osMutexAcquire(env->gsm->gsmAt->access, 10000) == osOK) { + AtGsm_Gsnss_Simcom7600_StartReceiver(env->gsm->gsmAt, false); + AtGsm_Gsnss_Simcom7600_StartReceiver(env->gsm->gsmAt, true); + AtGsm_Gsnss_Simcom7600_SetConfigureStaticRMCThread(env->gsm->gsmAt); + osMutexRelease(env->gsm->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата (RestartResiver)") + } + } + + } +///---конец-------------------------------------Проверка навигации на сбой приемника------------------------------------ + + EXT_ENV_TELE.store.runtime->telematicaCloseConnect = false; + + isFirstStart = true; +/* + + char serverName[] = "http://firmware.ficom-it.info/intelcom/file.php"; + + EgtsProcessing_SendCommandConfirmation(env, + CT_COM, // + 0, + 0, + 0, + + 0, + 0, + 2, // Установка значения + 0x0204, // Адрес и порт сервера для связи с использованием TCP/IP протокола + + (uint8_t *)serverName, + sizeof(serverName) - 1); + + SystemDelayMs(5000); + +*/ + + if (EXT_ENV_TELE.store.device->telematicaIsActive) { + env->isEnableTelematicaSendPoints = true; + } else { + env->isEnableTelematicaSendPoints = env->deviceTeledataStorageData->telematica.EGTS_SERVER_ENABLE_TELEMATICA; + } + + } else { + + if (isFirstStart) { + isFirstStart = false; + EgtsProcessingCloseConnection(env); + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Соединение с сервером разорвано, ИД: %d", socketId); + } + + env->egtsIdentityAdditionalData.isReceivedResultCode = false; + + env->egtsEnv.workingBufferLength = 0; + env->isEnableTelematicaSendPoints = false; + env->fl_firstStartTimeUpdateEBU = false; + + EXT_ENV_TELE.store.runtime->telematicaCloseConnect = true; + + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Телематика отключена") + } + + +//---начало-----------ОБНОВЛЕНИЕ УВЭОС------------------------------ + + if (env->deviceTeledataStorageData->telematica.UPDATE_UVEOS_UPDATE) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Через 5 секунд начнется обновление прошивки УВЭОС") + + SystemDelayMs(5000); + + env->gsmFirmware.attempts = env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS; + env->gsmFirmware.attemptsAll = env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_ATTEMPTS; + env->gsmFirmware.attempts_period = env->deviceTeledataStorageData->telematica.UPDATE_SERVER_CHECK_IN_PERIOD; + + StartUpdateFirmware(&env->gsmFirmware); + + for (;;) { + if (env->deviceTeledataStorageData->telematica.UPDATE_UVEOS_UPDATE == false) { + env->gsmFirmware.startUpdateFirmware = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Через 5 секунд выход из режима обновления прошивки УВЭОС") + SystemDelayMs(5000); + break; + } + SystemDelayMs(1000); + } + + } + +//---конец-----------ОБНОВЛЕНИЕ УВЭОС------------------------------ + + SystemDelayMs(100); + continue; + } + + + //начало ---------------------------------Установка соединения с сервером--------------------------------------- + //начало ---------------------------------Установка соединения с сервером--------------------------------------- + //начало ---------------------------------Установка соединения с сервером--------------------------------------- + + + if ((socketStatus == eSocketStatus_Disconnected) || (socketId == SOCKET_WRONG_CONTEXT)) { + uint32_t retry = env->deviceTeledataStorageData->telematica.EGTS_SERVER_CHECK_IN_ATTEMPTS; + + while (retry) { + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + break; + } + + if (NetworkRequire(env)) { + isRegistration = true; + } else { + isRegistration = false; + } + + if (!isRegistration) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Нет регистрации в сети"); + continue; + } + + EgtsProcessingCloseConnection(env); + EgtsResetBuffer(&env->egtsEnv); + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Установка соединения с сервером"); + socketId = EgtsProcessingOpenConnection(env); + if (socketId != SOCKET_WRONG_CONTEXT) { + stepAuth = 3; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Соединение с сервером установлено, ИД: %d", socketId); + SystemDelayMs(1000); + socketStatus = SocketInterface_status(&env->gsm->socketIO, socketId); + if (socketStatus == eSocketStatus_Connected) { + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Аутентификация на сервере"); + + if (EgtsProcessing_SendAuth(env)) { + + if (!env->isOneEBU) { + env->isOneEBU = true; + env->firstStartTimeUpdateEBU = SystemGetMs() + 60000; + env->fl_firstStartTimeUpdateEBU = true; + } + + addTeledataQueueEvent(env, EVENT_TCP_CONNECTION_START); + + break; + } + } else { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Аутентификация на сервере невозможна. Соединение разорвано"); + } + } else { + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Ошибка соединения с сервером, код %d", + env->gsm->codeResultOpen); + + + if ((env->gsm->codeResultOpen == 15) || (env->gsm->codeResultOpen == 10) || + (env->gsm->codeResultOpen == 19) || (env->gsm->codeResultOpen == 20)) { + + if (stepAuth == 0) { + + stepAuth = 3; + + result_CHECK_SOCKET(env); + + if (env->numberServer == 1) { + wait_CHECK_IN_PERIOD(env); + } + + changeServer(env, 1); + + } else { + + --stepAuth; + + result_CHECK_SOCKET(env); + + } + + continue; + + } else { + stepAuth = 3; + wait_CHECK_IN_PERIOD(env); + } + + } + + --retry; + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Повторная попытка установки соединения с сервером, осталось попыток: %d", retry); + } + + if (retry == 0) { + wait_CHECK_IN_PERIOD(env); + } + + } + //конец ---------------------------------Установка соединения с сервером--------------------------------------- + //конец ---------------------------------Установка соединения с сервером--------------------------------------- + //конец ---------------------------------Установка соединения с сервером--------------------------------------- + + if (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false) { + continue; + } + + //начало --------------------------------Проверка таймера ожидания обновления----------------------------------- + //начало --------------------------------Проверка таймера ожидания обновления----------------------------------- + //начало --------------------------------Проверка таймера ожидания обновления----------------------------------- + if ((env->TelematicaServerNotActiveWaitTime > 0) && (env->TelematicaServerNotActiveWaitTime < SystemGetMs())) { + + env->TelematicaServerNotActiveWaitTime = 0; + + if (EXT_ENV_TELE.store.device->telematicaIsActive == false) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Телематика отключена (полностью). Обновление не найдено. Закрытие соединения") + EgtsProcessingCloseConnection(env); + + EXT_ENV_TELE.store.runtime->telematicaServerIsActive = false; + EXT_ENV_TELE.store.runtime->telematicaWaitConnect = true; + + SystemDelayMs(5000); + + continue; + } + } + + //конец ---------------------------------Проверка таймера ожидания обновления----------------------------------- + //конец ---------------------------------Проверка таймера ожидания обновления----------------------------------- + //конец ---------------------------------Проверка таймера ожидания обновления----------------------------------- + + + //начало ---------------------------------Проверка соединения--------------------------------------------------- + //начало ---------------------------------Проверка соединения--------------------------------------------------- + //начало ---------------------------------Проверка соединения--------------------------------------------------- + if ((timeOutCheckConnect < SystemGetMs()) || (env->gsm->isDisconnect)) { + + if (env->gsm->isDisconnect) { + env->gsm->isDisconnect = false; + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Обнаружен разрыв соединения") + } + + + timeOutCheckConnect = SystemGetMs() + AURUS_CHECK_CONNECT; + + if (socketId != SOCKET_WRONG_CONTEXT) { + + socketStatus = SocketInterface_status(&env->gsm->socketIO, socketId); + + if (socketStatus == eSocketStatus_Disconnected) { + env->egtsIdentityAdditionalData.isReceivedResultCode = false; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Соединение с сервером разорвано, ИД: %d", socketId); + EgtsProcessingCloseConnection(env); + } + + } + + } + //конец ---------------------------------Проверка соединения--------------------------------------------------- + //конец ---------------------------------Проверка соединения--------------------------------------------------- + //конец ---------------------------------Проверка соединения--------------------------------------------------- + + SystemDelayMs(1000); + } + +} + +//extern tFirmwareLoader FIRMWARE_LOADER; + +void EgtsProcessing_Worker(tEgtsProcessing *env) { + bool oneOn = true; + bool oneOff = true; + uint8_t stepAuth = 3; + + for (;;) { + + if (onOffTelematica(env, &oneOn, &oneOff, "Задача драйвер протокола")) + continue; + + EgtsCompleteResult *result = EgtsCompleteTransportExt(&env->egtsEnv); + + if ((result->completeResult == EGTS_COMPLETE_ERR_VER) || + (result->completeResult == EGTS_COMPLETE_HEADER_ERR_CRC) || + (result->completeResult == EGTS_COMPLETE_BODY_ERR_CRC) || + (result->completeResult == EGTS_COMPLETE_ERR_OVERFLOW)) { + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка в пакете ЕГТС"); + + + if (result->completeResult == EGTS_COMPLETE_ERR_OVERFLOW) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Переполнение приемного буфера"); + } + if (result->completeResult == EGTS_COMPLETE_ERR_VER) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка номера версии в пакете ЕГТС"); + } + + if (result->completeResult == EGTS_COMPLETE_HEADER_ERR_CRC) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка CRC заголовка в пакете ЕГТС"); + + LoggerFormatInfo(LOGGER, LOG_SIGN, "CRC CALC = 0x%02x, CRC RECEIVED = 0x%02x", result->calcHeaderCrc, + result->receivedHeaderCrc); + + char bufLogHexString[40]; + memset(bufLogHexString, 0, sizeof(bufLogHexString)); + size_t lenLog = 0; + vAsciiStringAddBytesAsHex(bufLogHexString, &lenLog, (uint8_t *) env->wb, 11); + LoggerFormatInfo(LOGGER, LOG_SIGN, "HEADER (%d): %s", 11, bufLogHexString); + + } + + if (result->completeResult == EGTS_COMPLETE_BODY_ERR_CRC) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка CRC тела в пакете ЕГТС"); + + LoggerFormatInfo(LOGGER, LOG_SIGN, "CRC CALC = 0x%04x, CRC RECEIVED = 0x%04x", result->calcBodyCrc, + result->receivedBodyCrc); + +// char bufLogHexString[400]; +// memset(bufLogHexString, 0, sizeof(bufLogHexString)); +// size_t lenLog = 0; +// vAsciiStringAddBytesAsHex(bufLogHexString, &lenLog, (uint8_t *) env->wb, result->fullLength); +// LoggerFormatInfo(LOGGER, LOG_SIGN, "HEADER + BODY (%d): %s", result->fullLength, bufLogHexString); + + } + + + if (env->socketId != SOCKET_WRONG_CONTEXT) { + EgtsProcessingCloseConnection(env); + } + + } + + if (EgtsIsTransportCompleteExt(&env->egtsEnv) == EGTS_COMPLETE_OK) { + + EgtsParseHeaderExt(&env->egtsEnv); + EgtsParseFrameData(&env->egtsEnv); + uint16_t lengthData = EgtsParseSrvRecordExt(&env->egtsEnv, env->egtsEnv.record); + + bool unknownPacket = true; + +// LoggerFormatInfo(LOGGER, LOG_SIGN, "env->egtsEnv.header.type = %u", env->egtsEnv.header.type); +// LoggerFormatInfo(LOGGER, LOG_SIGN, "env->egtsEnv.recSourceService = %u", env->egtsEnv.recSourceService); +// LoggerFormatInfo(LOGGER, LOG_SIGN, "nv->egtsEnv.subRecType = %u", env->egtsEnv.subRecType); + + //начало ---------------------------------Получена квитанция------------------------------------------------ + //начало ---------------------------------Получена квитанция------------------------------------------------ + //начало ---------------------------------Получена квитанция------------------------------------------------ + + if (env->egtsEnv.header.type == EGTS_PT_RESPONSE) { + + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + + if (env->egtsEnv.recSourceService == EGTS_AUTH_SERVICE) { + + if (env->egtsEnv.subRecType == EGTS_SR_RECORD_RESPONSE) { + if (env->egtsEnv.ptResponse.responsePacketId == env->egtsIdentityAdditionalData.idPacked) { + + tEgtsRecordResponseData *egtsRecordResponseData = (tEgtsRecordResponseData *) env->egtsEnv.subRecData; + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет (id: %u) подтверждения запроса аутентификации, status: %u RST: %u", + env->egtsEnv.ptResponse.responsePacketId, env->egtsEnv.ptResponse.status, + egtsRecordResponseData->RST); + + unknownPacket = false; + + if ((env->egtsEnv.ptResponse.status == 0) && (egtsRecordResponseData->RST == 0)) + env->egtsIdentityAdditionalData.isReceivedResponse = true; + } else { + unknownPacket = false; + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет подтверждения запроса аутентификации (не верный), id: %u id (ожидаемый): %u", + env->egtsEnv.ptResponse.responsePacketId, + env->egtsIdentityAdditionalData.idPacked); + } + } + + } + + + + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + + //начало ---------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало ---------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало ---------------------------------Сервис ПРОШИВКИ----------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_FIRMWARE_SERVICE) { + if (env->egtsEnv.subRecType == EGTS_SR_RECORD_RESPONSE) { + + if (env->egtsEnv.ptResponse.responsePacketId == + env->egtsIdentityAdditionalData.idPacked) { + + tEgtsRecordResponseData *egtsRecordResponseData = (tEgtsRecordResponseData *) env->egtsEnv.subRecData; + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет (id: %u) подтверждения запроса прошивки, status: %u RST: %u", + env->egtsEnv.ptResponse.responsePacketId, env->egtsEnv.ptResponse.status, + egtsRecordResponseData->RST); + + unknownPacket = false; + + if ((env->egtsEnv.ptResponse.status == 0) && (egtsRecordResponseData->RST == 0)) + env->egtsIdentityAdditionalData.isReceivedResponse = true; + } else { + unknownPacket = false; + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет подтверждения запроса прошивки (не верный), id: %u id (ожидаемый): %u", + env->egtsEnv.ptResponse.responsePacketId, + env->egtsIdentityAdditionalData.idPacked); + } + + + } + } + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + + //начало ---------------------------------Сервис ТЕЛЕДАННЫХ--------------------------------------------- + //начало ---------------------------------Сервис ТЕЛЕДАННЫХ--------------------------------------------- + //начало ---------------------------------Сервис ТЕЛЕДАННЫХ--------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_TELEDATA_SERVICE) { + + if (env->egtsEnv.ptResponse.responsePacketId == env->egtsTeledataAdditionalData.idPacked) { + tEgtsRecordResponseData *egtsRecordResponseData = (tEgtsRecordResponseData *) env->egtsEnv.subRecData; + uint16_t POS_DATA_CRN = egtsRecordResponseData->CRN; + uint8_t POS_DATA_RST = egtsRecordResponseData->RST; + /* + lengthData += EgtsParseSrvRecordExt(&env->egtsEnv, env->egtsEnv.record + lengthData); + egtsRecordResponseData = (tEgtsRecordResponseData *) env->egtsEnv.subRecData; + uint16_t DIG_SENS_CRN = egtsRecordResponseData->CRN; + uint8_t DIG_SENS_RST = egtsRecordResponseData->RST; + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет подтверждения отправки теледанных, status: %u POS_DATA_RST: %u DIG_SENS_RST: %u", + env->egtsEnv.ptResponse.status, POS_DATA_RST, DIG_SENS_RST); + */ + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет (id: %u) подтверждения отправки теледанных, status: %u POS_DATA_RST: %u", + env->egtsEnv.ptResponse.responsePacketId, env->egtsEnv.ptResponse.status, + POS_DATA_RST); + + unknownPacket = false; + + env->egtsTeledataAdditionalData.isReceivedResponse = true; + } else { + unknownPacket = false; + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет подтверждения отправки теледанных (не верный), id: %u id (ожидаемый): %u", + env->egtsEnv.ptResponse.responsePacketId, + env->egtsIdentityAdditionalData.idPacked); + } + } + //конец ---------------------------------Сервис ТЕЛЕДАННЫХ---------------------------------------------- + //конец ---------------------------------Сервис ТЕЛЕДАННЫХ---------------------------------------------- + //конец ---------------------------------Сервис ТЕЛЕДАННЫХ---------------------------------------------- + + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_COMMANDS_SERVICE) { + + if (env->egtsEnv.ptResponse.responsePacketId == + env->egtsCommandConfirmationAdditionalData.idPacked) { + tEgtsRecordResponseData *egtsRecordResponseData = (tEgtsRecordResponseData *) env->egtsEnv.subRecData; + uint16_t POS_DATA_CRN = egtsRecordResponseData->CRN; + uint8_t POS_DATA_RST = egtsRecordResponseData->RST; + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет (id: %u) подтверждения отправки команды, status: %u POS_DATA_RST: %u", + env->egtsEnv.ptResponse.responsePacketId, env->egtsEnv.ptResponse.status, + POS_DATA_RST); + + unknownPacket = false; + + env->egtsCommandConfirmationAdditionalData.isReceivedResponse = true; + } else { + unknownPacket = false; + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет подтверждения отправки команды (не верный), id: %u id (ожидаемый): %u", + env->egtsEnv.ptResponse.responsePacketId, + env->egtsCommandConfirmationAdditionalData.idPacked); + } + } + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + + + } + //конец ---------------------------------Получена квитанция------------------------------------------------ + //конец ---------------------------------Получена квитанция------------------------------------------------ + //конец ---------------------------------Получена квитанция------------------------------------------------ + + + //начало ---------------------------------Получены данные--------------------------------------------------- + //начало ---------------------------------Получены данные--------------------------------------------------- + //начало ---------------------------------Получены данные--------------------------------------------------- + if (env->egtsEnv.header.type == EGTS_PT_APPDATA) { + + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + //начало ---------------------------------Сервис АУТЕНТИФИКАЦИИ----------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_AUTH_SERVICE) { + if (env->egtsEnv.subRecType == EGTS_SR_RESULT_CODE) { + + env->egtsIdentityAdditionalData.resultCodeAuth = *((uint8_t *) (env->egtsEnv.subRecData)); + + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет результата аутентификации, код: %d", + env->egtsIdentityAdditionalData.resultCodeAuth); + + EgtsProcessing_SendResponse(env, EGTS_AUTH_SERVICE, + EGTS_AUTH_SERVICE, + EGTS_SERVICE_FLAGS_AUTH, + 0, + env->egtsEnv.recordNumber); + + // Ошибка АУТЕНТИФИКАЦИИ + if (env->egtsIdentityAdditionalData.resultCodeAuth == 165) { + + if (stepAuth == 0) { + stepAuth = 3; + + LoggerStrInfoStatic(LOGGER, LOG_SIGN, + "Не корректный сертификат, переход на альтернативный сервер"); + changeServer(env, 1); + } else { + --stepAuth; + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Не корректный сертификат, переход на альтернативный сервер через %u попыток", + stepAuth); + } + + } else { + stepAuth = 3; + } + + + unknownPacket = false; + env->egtsIdentityAdditionalData.isReceivedResultCode = true; + } + } + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + //конец ---------------------------------Сервис АУТЕНТИФИКАЦИИ------------------------------------------ + + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + //начало ---------------------------------Сервис КОМАНД------------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_COMMANDS_SERVICE) { + unknownPacket = false; + + tEgtsCommand egtsCommand; + egtsCommand.cmdType = env->egtsEnv.srCommand->cmdType; + egtsCommand.cmdId = env->egtsEnv.srCommand->cmdId; + egtsCommand.act = env->egtsEnv.srCommand->act; + egtsCommand.cmd = env->egtsEnv.srCommand->cmd; + egtsCommand.dataSize = env->egtsEnv.subRecLength - 15; + + if (egtsCommand.dataSize > 512) + egtsCommand.dataSize = 512; + + memcpy(egtsCommand.data, env->egtsEnv.srCommand->dataPointer, egtsCommand.dataSize); + + EgtsProcessing_SendResponse(env, EGTS_COMMANDS_SERVICE, + EGTS_COMMANDS_SERVICE, + EGTS_SERVICE_FLAGS_COMMAND, + 0, + env->egtsEnv.recordNumber); + + addCommandQueue(env, &egtsCommand); + + } + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + //конец ---------------------------------Сервис КОМАНД------------------------------------------------- + + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_FIRMWARE_SERVICE) { + if (env->egtsEnv.subRecType == EGTS_SR_SERVICE_PART_DATA) { + unknownPacket = false; + + env->TelematicaServerNotActiveWaitTime = 0; + + receivedUpdateFirmware(env); + } + } + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ +/* + + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + //начало --------------------------------Сервис ПРОШИВКИ----------------------------------------------- + if (env->egtsEnv.recSourceService == EGTS_FIRMWARE_SERVICE) { + if (env->egtsEnv.subRecType == EGTS_SR_SERVICE_PART_DATA) { + unknownPacket = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получен пакет прошивки"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Прошивка в этой версии не поддерживается"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Прошивка будет получена в загрузчике при следующей перезагрузке"); + } + } + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ + //конец ---------------------------------Сервис ПРОШИВКИ------------------------------------------------ +*/ + } + //конец ---------------------------------Получены данные---------------------------------------------------- + //конец ---------------------------------Получены данные---------------------------------------------------- + //конец ---------------------------------Получены данные---------------------------------------------------- + + + if (unknownPacket) { + uint16_t len = + env->egtsEnv.headerLength + env->egtsEnv.frameDataLength + env->egtsEnv.frameDataSrcLength; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получен неопознанный пакет:"); + sendLogHex(env, env->egtsEnv.workingBuffer, len); + + } + + EgtsResetBuffer(&env->egtsEnv); + } + + } +} + +_Noreturn void EgtsProcessing_ListenerTask(tEgtsProcessing *env) { + while (1) { + EgtsProcessing_Worker(env); + } +} diff --git a/EgtsProcessing.h b/EgtsProcessing.h new file mode 100644 index 0000000..0c64c3b --- /dev/null +++ b/EgtsProcessing.h @@ -0,0 +1,357 @@ +// +// Created by cfif on 21.05.23. +// + +#ifndef SMART_COMPONENTS_EGTSPROCESSING_H +#define SMART_COMPONENTS_EGTSPROCESSING_H + +#include +#include "SocketInterface.h" +#include "stdint.h" +#include "stddef.h" +#include "stdbool.h" +#include "CmsisRtosThreadUtils.h" +#include "egtsWorker.h" +#include "AtCmdBase.h" +#include "GsmWithGnss.h" +#include "LoggerToSerialPort.h" +#include "Certs.h" +#include "LittleFsInterface.h" +#include "DeviceStorage.h" +#include "Nmea0183Parser.h" +#include "DataStorage.h" +#include "PointEvent.h" +#include "CanSerialPortFrameTP.h" +#include "CanMain.h" +#include "GetGsmFirmware.h" +#include "EraGlonassUveos_Dumper.h" +#include "ext_telematica.h" +#include "EgtsTelesataTypes.h" +#include "SerialPortCanComInt.h" + + +#define AURUS_CHECK_CONNECT 15000 +#define AURUS_CHECK_NAV 5000 +#define AURUS_CHECK_NETWORK_STATUS 30000 + + +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//начало ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ + +typedef struct { + uint16_t idPacked; + bool isReceivedResponse; +} tEgtsFirmwareAdditionalData; + +typedef struct { + uint32_t timestamp; + uint16_t idFirmware; + uint16_t partNumber; + uint16_t countNumber; + char module[20]; + + uint8_t bufEbu[2048]; + uint16_t bufLen; +} tEgtsFirmwareDataArgs; + +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ +//конец ---------------------------------Прошивка ЭБУ------------------------------------------------------------------ + + +//начало ---------------------------------Аутентификация--------------------------------------------------------------- +//начало ---------------------------------Аутентификация--------------------------------------------------------------- +//начало ---------------------------------Аутентификация--------------------------------------------------------------- + +typedef struct { + uint8_t *IMEI; + uint8_t IMEI_len; + uint32_t TerminalID; +} tEgtsIdentityDataArgs; + +typedef struct { +} tEgtsIdentityModuleDataArgs; + +typedef struct { + uint16_t idPacked; + bool isReceivedResponse; + bool isReceivedResultCode; + uint16_t resultCodeAuth; +} tEgtsIdentityAdditionaData; + +//конец ---------------------------------Аутентификация--------------------------------------------------------------- +//конец ---------------------------------Аутентификация--------------------------------------------------------------- +//конец ---------------------------------Аутентификация--------------------------------------------------------------- + + +//начало ---------------------------------Команды----------------------------------------------------------------------- +//начало ---------------------------------Команды----------------------------------------------------------------------- +//начало ---------------------------------Команды----------------------------------------------------------------------- + +#define COMMAND_QUEUE_SIZE 10 + +typedef struct { + uint16_t ADR; + uint8_t SZ; + uint8_t ACT; + uint16_t CCD; + uint8_t *DT; + uint8_t DT_SIZE; +} tEgtsSrCmdConfirmationExComData; + +typedef struct { + uint8_t CT; + uint8_t CCT; + uint32_t CID; + uint32_t SID; + uint8_t ACFE; + uint8_t CHSFE; + uint8_t CHS; + uint8_t ACL; + uint16_t AC; + tEgtsSrCmdConfirmationExComData CmdData; +} tEgtsCommandConfirmationDataArgs; + +typedef struct { + osMessageQueueId_t queue; + uint16_t idPacked; + bool isReceivedResponse; +} tEgtsCommandConfirmationAdditionalData; + + +typedef struct { + uint8_t cmdType; + uint32_t cmdId; + uint8_t act; + uint16_t cmd; + uint8_t commandConfirmationType; + uint16_t dataSize; + uint8_t data[512]; +} tEgtsCommand; + +//конец ---------------------------------Команды------------------------------------------------------------------------ +//конец ---------------------------------Команды------------------------------------------------------------------------ +//конец ---------------------------------Команды------------------------------------------------------------------------ + +typedef struct { + bool isEbuData; + uint16_t speed; + uint32_t dist; +} tEgtsCanEnv; + +typedef enum { + EGTS_WAIT_0 = 0, + EGTS_WAIT_1 = 1, + EGTS_WAIT_2 = 2 +} eEgtsSendWait; + +typedef struct __attribute__ ((packed)) { + uint32_t SIZE_ROOT_CA; + uint32_t SIZE_CLIENT_KEY; + uint32_t SIZE_CLIENT_CRT; + uint32_t ENC; +} tEgtsCertInfo; + +typedef struct { + uint32_t timeOutCheckTeledata_IGN_TimeUpdate; + uint32_t timeOutCheckTeledata_EM_TimeUpdate; + + uint32_t timeOutCheckTeledata_TimeSpeedUpdate; + + bool isUpdatePoints; + + bool isOneNav; + + bool oneOn; + bool oneOff; + bool isBeginEndNav; + + bool isEVENT_NAVIGATION_START_STOP; + bool isEVENT_ROTATE_ANGLE_LIMIT; + bool isEVENT_DISTANCE; + bool isEVENT_TIMEOUT_ENGINE_OFF; + bool isEVENT_TIMEOUT_ENGINE_ON; + bool isEVENT_EMERGENCY_TRACKING_TIMEOUT; + bool isEVENT_VEH_STATE_CHANGED; + bool isEVENT_MOVEMENT_ON; + bool isEVENT_MOVEMENT_OFF; + + uint16_t beginAngle; + uint16_t beginDist; + +} tEgtsPointEnv; + +typedef struct { + + tSerialPortIO *log; + volatile uint16_t egtsPacketId; + uint16_t counter; + uint8_t socketId; + EgtsWorkerEnvironment egtsEnv; + tLoggerToSerialPort *slog; + tLittleFileFs *fs; + + tEgtsPointEnv egtsPointEnv; + + tCanMain CanMain; + tCanMainAdditional CanMainAdditional; + + tSerialPortCanComInt tSerialPortCanComInt; + tSerialPortIO serialPortCanComIntIO; + + tCanMainMute CanMainMute; + tCanMainTest CanMainTest; + + struct { + uint32_t stopPositionLimitTime; + volatile eCarPosition carPosition; + + tNmeaRmc beginPosition; + tNmeaRmc movePosition; + + bool isTimerMoving; + uint32_t timerMoving; + + uint16_t dataSpeed[4]; + uint16_t dataSpeedStep; + + } carEventPosition; + + tStaticThreadBlock(1024) T_processing_Network; + tStaticThreadBlock(1024) T_processing_input_command; + tStaticThreadBlock(1024) T_processing_ebu; + tStaticThreadBlock(1024) T_processing_event_teledata; + tStaticThreadBlock(2048) T_processing_teledata; + tStaticThreadBlock(2048) T_processing_main; + tStaticThreadBlock(2048) T_listener; + +// uint8_t wb[1024 * 10]; + uint8_t wb[1024 * 32]; +// uint8_t wb[1024 * 10]; + + + char hexString[2048 + 256]; + uint8_t egtsRawFirmware[1024 + 128]; + + tLocationPointInDegDouble *bleLoc; + tGsmWithGnss *gsm; + tRtcIO *rtc; + + // Теледанные + volatile tEgtsTeledataAdditionalData egtsTeledataAdditionalData; + tEgtsTeledata egtsTeledataUveos; // Состояние по запросу от УВЭОС + tEgtsTeledata egtsTeledataSent; // Последнее отправленное состояние + tEgtsTeledata egtsTeledataEdit; // Формируемое состояние + tEgtsTeledata egtsTeledataFix; // Фиксируемое состояние + + // Прошивка модулей ЭБУ + volatile tEgtsFirmwareAdditionalData egtsFirmwareAdditionalData; + tEgtsFirmwareDataArgs egtsFirmwareDataArgs; + SystemMutexCmsis accessEbu; + tEgtsEbuState ebuState; + bool ebuReady; + + // Аутентификация + volatile tEgtsIdentityAdditionaData egtsIdentityAdditionalData; + tEgtsIdentityDataArgs egtsIdentityDataArgs; + tEgtsIdentityModuleDataArgs egtsModuleDataArgs; + + // Команды + volatile tEgtsCommandConfirmationAdditionalData egtsCommandConfirmationAdditionalData; + tEgtsCommandConfirmationDataArgs egtsCommandConfirmationDataArgs; + tEgtsCommand egtsCommandSent; // Последняя извлеченная команда + + tString32 srvAddr; + uint16_t srvPort; + eAtGsmSimComA7600_SSL_Type clientType; + + tDeviceTeledataStorageData *deviceTeledataStorageData; + + tEgtsCanEnv egtsCanEnv; + + uint16_t pPointsStorageSent; + + bool isEnableTelematicaSendPoints; + uint32_t firstStartTimeUpdateEBU; + bool fl_firstStartTimeUpdateEBU; + + uint16_t firmwareBufCrc; + uint32_t firmwareOffset; + + bool rebootFirmware; + + int32_t x1; + int32_t y1; + int32_t z1; + int32_t x2; + int32_t y2; + int32_t z2; + uint8_t count_shot; + uint16_t count_free; + uint32_t timeAccelUpdate; + uint32_t timeAccelUpdateUds; + + uint32_t timeNavUpdate; + uint32_t timeFact; + + tGsmFirmware gsmFirmware; + // Буфер для хранений порции + uint8_t firmware_buf[2048]; + tFirmwareStats firmwareStats; + + tCerts certs; + + volatile tRawAccel rawAccel; + + bool isOneEBU; + + uint32_t TelematicaServerNotActiveWaitTime; + + SystemMutexCmsis txCanAccessQueue; + + uint16_t totalSpeed; + uint32_t SENSORS_AN_MinutesOfTravel_gl; + + uint8_t numberServer; + + uint32_t timerUpdate; + bool isTimerUpdate; + +} tEgtsProcessing; + +extern tEgtsProcessing egtsProcessing; + +void EgtsProcessing_Init( + tEgtsProcessing *env, + tGsmWithGnss *gsm, + tRtcIO *rtcIO, + tLittleFileFs *fs, + tLoggerToSerialPort *slog +); + +char *sendLogHex(tEgtsProcessing *env, uint8_t *data, size_t size); + +void EgtsProcessing_Start(tEgtsProcessing *env); + +bool EgtsProcessingSend(tEgtsProcessing *env, uint8_t *egtsRaw, uint16_t egtsRawLength, + eEgtsSendWait wait, volatile bool *wait1, volatile bool *wait2); + +void EgtsProcessingCloseConnection(tEgtsProcessing *env); + +bool isAuth(tEgtsProcessing *env); + +uint8_t findDelimiter(tString32 *address, char ch); + +bool EgtsProcessing_SendResponse(tEgtsProcessing *env, + eEgtsServiceId sourceServiceId, + eEgtsServiceId recipientServiceId, + uint8_t srvFlags, + uint8_t rst, + uint16_t crn); + +bool onOffTelematica(tEgtsProcessing *env, bool *oneOn, bool *oneOff, char *task); + +void receivedUpdateFirmware(tEgtsProcessing *env); + +#endif //SMART_COMPONENTS_EGTSPROCESSING_H diff --git a/EgtsTeledataPoint.c b/EgtsTeledataPoint.c new file mode 100644 index 0000000..97a96c1 --- /dev/null +++ b/EgtsTeledataPoint.c @@ -0,0 +1,828 @@ +// +// Created by cfif on 12.06.2024. +// +#include "EgtsTeledataPoint.h" +#include "string.h" +#include "EgtsOutputCommands.h" +#include "CarPositionUpdate.h" +#include "EgtsTimestamp.h" +#include "math.h" +#include "Nmea0183Parser.h" +#include "Rtc.h" +#include "ext_telematica.h" +#include "SystemDelayInterface.h" +#include "ext_telematica.h" +#include "lfs_file_utils.h" +#include "EgtsTeledataStoragePoint.h" + +#define LOG_SIGN "EGTS TELE" +#define LOGGER &env->slog->logger + +const tStringStatic textEgtsEventTetedata[] = { + + StringStaticInit("EVENT_TIMEOUT_ENGINE_ON (0) - Наступление таймера при включенном зажигании\0"), + StringStaticInit("EVENT_DISTANCE (1) - Превышение заданного расстояния\0"), + StringStaticInit("EVENT_ROTATE_ANGLE_LIMIT (2) - Превышение заданного курсового угла\0"), + StringStaticInit("EVENT_RESPONSE (3) - Событие по запросу\0"), + StringStaticInit("EVENT_INPUT_CHANGED (4) - Изменение по аналоговым/дискретным входам\0"), + StringStaticInit("EVENT_TIMEOUT_ENGINE_OFF (5) - Наступление таймера при выключенном зажигании\0"), + StringStaticInit("-\0"), + StringStaticInit("EVENT_HI_SPEED_LIMIT (7) - Превышение одного из заданных порогов скорости\0"), + StringStaticInit("EVENT_CPU_RESTART (8) - Событие при старте прибора после перезагрузки по запросу\0"), + StringStaticInit("-\0"), + StringStaticInit("EVENT_TAMPER (10) - Срабатывание датчика вскрытия корпуса\0"), + StringStaticInit("EVENT_EXT_POWER_LOST (11) - Пропадание внешнего питания\0"), + StringStaticInit("EVENT_INT_BATTERY_LOW (12) - Низкий заряд встроенного АКБ\0"), + StringStaticInit("EVENT_ALARM_BUTTON (13) - Нажата кнопка тревоги\0"), + StringStaticInit("EVENT_USER_CALL (14) - Совершен голосовой вызов с устройства\0"), + StringStaticInit("EVENT_EMERGENCY_CALL (15) - Экстренный вызов\0"), + StringStaticInit("EVENT_DATA_FROM_EXT_SERVICE (16) - Данные с внешнего сервиса (в SDM не используется)\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("EVENT_INT_BATTERY_FAIL (19) - Неисправность внутреннего источника питания\0"), + StringStaticInit("EVENT_RAPID_ACCELERATION (20) - Резкий разгон\0"), + StringStaticInit("EVENT_RAPID_DECELERATION (21) - Резкое торможение\0"), + StringStaticInit("EVENT_NAVIGATION_FAIL (22) - Неисправность навигационного модуля\0"), + StringStaticInit("EVENT_ACC_FAIL (23) - Неисправность акселерометра\0"), + StringStaticInit("EVENT_GSM_ANTENNA_FAIL (24) - Неисправность антенны сотовой связи\0"), + StringStaticInit("EVENT_NAV_ANTENNA_FAIL (25) - Неисправность антенны ГНСС\0"), + StringStaticInit("-\0"), + StringStaticInit("EVENT_LOW_SPEED_LIMIT (27) - Снижение ниже одного из заданных порогов скорости\0"), + StringStaticInit("EVENT_MOVEMENT_WITH_ENGINE_OFF (28) - Передвижение при выключенном зажигании\0"), + StringStaticInit("EVENT_EMERGENCY_TRACKING_TIMEOUT (29) - Таймер посылки точек при экстренном слежении\0"), + StringStaticInit("EVENT_NAVIGATION_START_STOP (30) - Событие при начале/окончании навигационного решения\0"), + StringStaticInit("EVENT_NAVIGATION_UNSTABLE (31) - Нестабильная навигация\0"), + StringStaticInit("EVENT_TCP_CONNECTION_START (32) - Событие при установлении соединения с сервером\0"), + StringStaticInit("EVENT_GSM_UNSTABLE (33) - Нестабильная сотовая связь\0"), + StringStaticInit("EVENT_TCP_UNSTABLE (34) - Нестабильное соединение с сервером\0"), + StringStaticInit("EVENT_STATE_CHANGED (35) - Изменение состояния устройства\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("-\0"), + StringStaticInit("EVENT_FIRMWARE_UPDATE (62) - Событие при старте устройства после обновления ПО\0"), + StringStaticInit("EVENT_CHANGE_POS (63) - Событие по изменению местоположения\0"), + StringStaticInit( + "VENT_START_SL_MODE_LOW_LVB (64) - Событие по переходу в режим глубокий сон по низкому напряжению АКБ\0"), + StringStaticInit( + "VENT_START_SL_MODE_ENGINE_OFF (65) - Событие по переходу в режим глубокий сон через заданное время после выключения двигателя\0"), + StringStaticInit( + "EVENT_START_SL_MODE_GSM_OFF (66) - Событие по переходу в глубокий сон при отсутствии связи\0"), + StringStaticInit( + "VENT_EXIT_FROM_SL_MODE_CAN_ON (67) - Событие при выходе из глубокого сна по появлению активности в CAN-шине\0"), + StringStaticInit( + "VENT_EXIT_FROM_SL_MODE_HIGH_POW (68) - Событие при выходе из глубокого сна по появлению высокого напряжения на внешнем АКБ\0"), + StringStaticInit( + "VENT_EXIT_FROM_SL_MODE_TIMEOUT (69) - Событие при выходе из глубокого сна по заданному таймеру\0"), + StringStaticInit("EVENT_GSM_CERTS_UPLOAD (70) - Событие по факту загрузки набора сертификатов\0"), + StringStaticInit("EVENT_EGTS_CONFIG_UPDATED (71) - Событие по факту загрузки файла конфигурации\0"), + StringStaticInit( + "VENT_EXIT_FROM_SL_MODE_ERS (72) - Событие при выходе из глубокого сна для запуска двигателя по расписанию\0"), + StringStaticInit("EVENT_WATCHDOG_RESTART (73) - Событие при старте прибора после перезагрузки по вотчдогу\0"), + StringStaticInit("EVENT_VEH_STATE_CHANGED (74) - Изменение статуса автомобиля\0"), + StringStaticInit("EVENT_DOORS_LOCK_STATE_CHANGED (75) - Изменение статуса замков дверей\0"), + StringStaticInit( + "VENT_VAS_ALARM_STATE_CHANGED (76) - Изменения статуса тревоги системы контроля доступа (сигнализация)\0"), + StringStaticInit("EVENT_LVB_STATE_CHANGED (77) - Изменения статуса внешнего АКБ\0"), + StringStaticInit("EVENT_DOORS_STATE_CHANGED (78) - Изменение статуса дверей и капота\0"), + StringStaticInit("EVENT_CCU_STATE_CHANGED (79) - Изменение статуса климат-контроля\0"), + StringStaticInit("EVENT_TCU_STATE_CHANGED (80) - Изменение статуса КПП\0"), + StringStaticInit("EVENT_REFUELING (81) - Событие заправки топливного бака\0"), + StringStaticInit("EVENT_SEATS_STATE_CHANGED (82) - Событие изменения статуса кресел\0"), + StringStaticInit("EVENT_EXT_POWER_ON (83) - Событие при старте прибора после появления внешнего питания\0"), + StringStaticInit("EVENT_CAN_RECIVE_ON (84) - Событие при появлении активности CAN-шины\0"), + StringStaticInit("EVENT_CAN_RECIVE_OFF (85) - Событие при пропадании активности CAN-шины\0"), + StringStaticInit("EVENT_MOVEMENT_ON (86) - Событие при начале движения\0"), + StringStaticInit("EVENT_MOVEMENT_OFF (87) - Событие при окончании движения\0") +}; + + +void addTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata) { + + if (!isAuth(env)) { + if ((egtsTeledata->egtsPosDataArgs.SRC != EVENT_EMERGENCY_CALL) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_USER_CALL) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_VEH_STATE_CHANGED) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_ROTATE_ANGLE_LIMIT) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_NAVIGATION_START_STOP)) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Соединение с сервером не установлено. Точка не критичная. Сохранение в очередь отменено") + return; + } + } + + osStatus_t status = osMessageQueuePut(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0x0, 0U); + + if (status != osOK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueue (1)") + + tEgtsTeledata egtsTeledataStore; + + for (uint8_t i = 0; i < 100; ++i) { + if (extractTeledataQueue(env, &egtsTeledataStore, 1)) { + + bool result = dumpPointStorage(env, &egtsTeledataStore, false); + if (!result) + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище (1)") + + } else { + break; + } + } + + status = osMessageQueuePut(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0x0, 0U); + if (status != osOK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueue (2)") + } + } + + +} + +void addTeledataQueueEvent(tEgtsProcessing *env, eEgtsEventTetedata egtsTeledataEvent) { + + osStatus_t status = osMessageQueuePut(env->egtsTeledataAdditionalData.queueEvent, &egtsTeledataEvent, 0x0, 0U); + + if (status != osOK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueueEvent") + } else { + if (egtsTeledataEvent < 88) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[egtsTeledataEvent].data); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло неизвестное событие: %u", egtsTeledataEvent); + } + } +} + +bool extractTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata, uint32_t timeout) { + osStatus_t status = osMessageQueueGet(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0, timeout); + + if ((status != osOK) && (status != osErrorTimeout)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка извлечения из очереди extractTeledataQueue") + } + + if (status == osOK) { + return true; + } + + return false; +} + +bool extractTeledataQueueEvent(tEgtsProcessing *env, eEgtsEventTetedata *egtsTeledataEvent, uint32_t timeout) { + osStatus_t status = osMessageQueueGet(env->egtsTeledataAdditionalData.queueEvent, egtsTeledataEvent, 0, timeout); + + if ((status != osOK) && (status != osErrorTimeout)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка извлечения из очереди extractTeledataQueueEvent") + } + + if (status == osOK) { + return true; + } + + return false; +} + +static double nmeaLocationToDeg(double dec) { + double _dec = dec; + int deg = (int) (_dec / 100); + int min = (int) (_dec) - (deg * 100); + + double sec = (double) (_dec - min - 100 * deg) * 60.0; + + return deg + min / 60.0 + sec / 3600.0; +} + +void addEventFromUveos(tEgtsProcessing *env, const eEgtsEventTetedata *event) { + time_t timestamp = 0; + + RtcGet(env->gsm->Rtc, ×tamp); + + tNmeaRmc nmeaRmc; + Gnss_GetFullNavData(env->gsm, &nmeaRmc); + + uint8_t countSats = GnssGgaGetSat(env->gsm); + env->egtsTeledataUveos.egtsExtPositionDataArgs.SAT = countSats; + env->egtsTeledataUveos.egtsExtPositionDataArgs.NS = 1; + + env->egtsTeledataUveos.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); + + env->egtsTeledataAdditionalData.LAT = nmeaLocationToDeg(nmeaRmc.location.latitude); + env->egtsTeledataAdditionalData.LON = nmeaLocationToDeg(nmeaRmc.location.longitude); + + double lat = (fabs(env->egtsTeledataAdditionalData.LAT) / 90) * 0xFFFFFFFF; + env->egtsTeledataUveos.egtsPosDataArgs.LAT = (uint32_t) lat; + + double lon = (fabs(env->egtsTeledataAdditionalData.LON) / 180) * 0xFFFFFFFF; + env->egtsTeledataUveos.egtsPosDataArgs.LONG = (uint32_t) lon; + + env->egtsTeledataUveos.egtsPosDataArgs.FLG.VLD = (nmeaRmc.status == 'A') ? 1 + : 0; // Битовый флаг, признак «валидности» координатных данных + + env->egtsTeledataUveos.egtsPosDataArgs.FLG.FIX = 0; // битовое поле, тип определения координат + env->egtsTeledataUveos.egtsPosDataArgs.FLG.CS = 0; // битовое поле, тип используемой системы + env->egtsTeledataUveos.egtsPosDataArgs.FLG.BB = 0; // битовый флаг, признак отправки данных из памяти («черный ящик») + + if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { + env->egtsTeledataUveos.egtsPosDataArgs.FLG.MV = 1; // битовый флаг, признак движения + } else { + env->egtsTeledataUveos.egtsPosDataArgs.FLG.MV = 0; // битовый флаг, признак движения + } + + env->egtsTeledataUveos.egtsPosDataArgs.FLG.LAHS = (nmeaRmc.location.nsIndicator == 'S') ? 1 + : 0; // битовый флаг определяет полушарие широты + env->egtsTeledataUveos.egtsPosDataArgs.FLG.LOHS = (nmeaRmc.location.ewIndicator == 'W') ? 1 + : 0; // битовый флаг определяет полушарие долготы + env->egtsTeledataUveos.egtsPosDataArgs.FLG.ALTE = 1; // битовый флаг определяет наличие поля ALT в подзаписи + + uint16_t speed = (uint16_t) (nmeaRmc.knotVelocity * 1.82 * 10); + uint16_t dir = (uint16_t) nmeaRmc.headingAngle; + + env->egtsTeledataUveos.egtsPosDataArgs.SPD.SPD = speed & + 0b0011111111111111; // скорость в км/ч с дискретностью 0,1 км/ч (используется 14 младших бит) + + int32_t alt = GnssGgaGetAlt(env->gsm); + + if (alt >= 0) { + env->egtsTeledataUveos.egtsPosDataArgs.SPD.ALTS = 0; + } else { + env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 1; + } + + env->egtsTeledataUveos.egtsPosDataArgs.SPD.DIRH = dir >> 8; // направление движения + + env->egtsTeledataUveos.egtsPosDataArgs.DIR = dir; // направление движения + env->egtsTeledataUveos.egtsPosDataArgs.ODM = 0; // пройденное расстояние (пробег) в км, с дискретностью 0,1 км + env->egtsTeledataUveos.egtsPosDataArgs.DIN = 0; // битовые флаги, определяют состояние основных дискретных входов + env->egtsTeledataEdit.egtsPosDataArgs.ALT = abs(alt); + + env->egtsTeledataUveos.egtsPosDataArgs.SRC = *event; // определяет источник (событие) + + // Обновление датчиков + env->egtsTeledataUveos.egtsSensorsAnArgs = env->egtsTeledataEdit.egtsSensorsAnArgs; + env->egtsTeledataUveos.egtsSensorsDigArgs = env->egtsTeledataEdit.egtsSensorsDigArgs; + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сохранение события от УВЭОС") + bool result = dumpPointStorage(env, &env->egtsTeledataUveos, true); + + SystemDelayMs(1500); +} + +_Noreturn void EgtsProcessing_TransmitterTaskTeledata(tEgtsProcessing *env) { + bool oneOn = true; + bool oneOff = true; + + env->pPointsStorageSent = 0; + + for (;;) { + + if (onOffTelematica(env, &oneOn, &oneOff, "Задача отправки")) + continue; + + //начало ---------------------------------Отправка теледанных--------------------------------------------------- + //начало ---------------------------------Отправка теледанных--------------------------------------------------- + //начало ---------------------------------Отправка теледанных--------------------------------------------------- + + if (!isAuth(env)) { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание аутентификации на сервере") + SystemDelayMs(1000); + continue; + } + + uint32_t countPoints = 1; + + while (countPoints) { + + getPointStorageCount(env, &countPoints); + + if (loadPointStorage(env, &env->egtsTeledataSent)) { + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "В хранилище найдены точки: %d", countPoints) + + if (env->egtsTeledataSent.egtsPosDataArgs.SRC < 88) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Событие в хранилище: %s", + textEgtsEventTetedata[env->egtsTeledataSent.egtsPosDataArgs.SRC].data); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Неизвестное событие в хранилище: %d", + env->egtsTeledataSent.egtsPosDataArgs.SRC); + } + + // Передача теледанных + if (EgtsProcessing_SendSensors(env, true) == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача теледанных не удалась") + } else { + ++env->pPointsStorageSent; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Теледанные из хранилища отправлены"); + } + + } else { + env->pPointsStorageSent = 0; + } + + if (!isAuth(env) || (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false)) { + break; + } + + } + + if (!isAuth(env) || (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false)) { + continue; + } + + + if (extractTeledataQueue(env, &env->egtsTeledataSent, 1)) { + +/* + // начало --- тест --- + for (int j = 0; j < 10000; ++j) { + + for (int i = 0; i < 7000; ++i) { + if (dumpPointStorage(env, &env->egtsTeledataSent, false) == false) { + asm("nop"); + break; + } + } + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Циклов: %d", j) + + deleteFilePointStorage(env); + asm("nop"); + } + // конец --- тест --- +*/ + + + if (env->egtsTeledataSent.egtsPosDataArgs.SRC < 88) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Отправка события: %s", + textEgtsEventTetedata[env->egtsTeledataSent.egtsPosDataArgs.SRC].data); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Неизвестное событие: %u", + env->egtsTeledataSent.egtsPosDataArgs.SRC); + + continue; + } +/* + if (!isAuth(env)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Нет регистрации в сети или аутентификации на сервере") + bool result = dumpPointStorage(env, &env->egtsTeledataSent, false); + + if (!result) + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище") + + continue; + } +*/ + // Передача теледанных + if (EgtsProcessing_SendSensors(env, false) == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача теледанных не удалась") + + +// bool result = dumpPointStorage(env, &env->egtsTeledataSent, false); +// if (!result) +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище") + + } + } + + //конец ---------------------------------Отправка теледанных--------------------------------------------------- + //конец ---------------------------------Отправка теледанных--------------------------------------------------- + //конец ---------------------------------Отправка теледанных--------------------------------------------------- + } + +} + +uint16_t getTotalSpeed(tEgtsProcessing *env, tNmeaRmc *nmeaRmc) { + + uint16_t totalSpeed = 0; + + if (nmeaRmc->status == 'A') + totalSpeed = (uint16_t) (nmeaRmc->knotVelocity * 1.82); + + if (env->egtsCanEnv.isEbuData) { + totalSpeed = env->egtsCanEnv.speed; + } + + return totalSpeed; +} + +uint32_t getTotalDist(tEgtsProcessing *env) { + + return env->egtsCanEnv.dist; + +} + +_Noreturn void EgtsProcessing_EventTaskTeledata(tEgtsProcessing *env) { + + bool isTimestamp = true; + time_t timestamp = 0; + + uint32_t timeTeleOff = 0; + + env->egtsPointEnv.isUpdatePoints = true; + + env->egtsPointEnv.isOneNav = true; + + env->egtsPointEnv.oneOn = true; + env->egtsPointEnv.oneOff = true; + env->egtsPointEnv.isBeginEndNav = false; + + env->egtsPointEnv.beginAngle = 0; + env->egtsPointEnv.beginDist = 0; + + uint32_t timeTimestamp = 0; + + eEgtsTsStatus egtsTsStatus = TS_STATUS_UNKNOWN; + + bool isOneFixMove = true; + + for (;;) { + + if (onOffTelematica(env, &env->egtsPointEnv.oneOn, &env->egtsPointEnv.oneOff, "Задача формирования точек")) { + + if (GpioPinGet(EXT_ENV_TELE.ignition)) { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; + } else { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; + } + + continue; + } + + RtcGet(env->gsm->Rtc, ×tamp); + + if (timestamp < 1718359909) { + + if (timeTimestamp < SystemGetMs()) { + timeTimestamp = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание получения временной метки") + } + + SystemDelayMs(1000); + continue; + } else { + if (isTimestamp) { + isTimestamp = false; + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Временная метка получена") + } + } + + if (!env->isEnableTelematicaSendPoints) { + if (timeTeleOff < SystemGetMs()) { + timeTeleOff = SystemGetMs() + 10000; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание разрешения телематики") + } + SystemDelayMs(1000); + continue; + } + + env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP = false; + env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT = false; + env->egtsPointEnv.isEVENT_DISTANCE = false; + env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF = false; + env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON = false; + env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT = false; + env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED = false; + + env->egtsPointEnv.isEVENT_MOVEMENT_ON = false; + env->egtsPointEnv.isEVENT_MOVEMENT_OFF = false; + + + eEgtsEventTetedata egtsEventTetedata = EVENT_INVALID_STATE; + + if (extractTeledataQueueEvent(env, &egtsEventTetedata, 100)) { + + } + + tNmeaRmc nmeaRmc; + Gnss_GetFullNavData(env->gsm, &nmeaRmc); + + + //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ + //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ + //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ + + env->totalSpeed = getTotalSpeed(env, &nmeaRmc); + + bool isBeginNav = false; + if ((env->egtsPointEnv.isBeginEndNav == false) && (nmeaRmc.status == 'A')) { + env->egtsPointEnv.isBeginEndNav = true; + isBeginNav = true; + } + + bool isEndNav = false; + if ((env->egtsPointEnv.isBeginEndNav == true) && (nmeaRmc.status != 'A')) { + env->egtsPointEnv.isBeginEndNav = false; + isEndNav = true; + } + + if ((isBeginNav) || (isEndNav)) { + env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_NAVIGATION_START_STOP].data); + } + + uint16_t moveAngle = (uint16_t) nmeaRmc.headingAngle; + uint16_t angle = abs(moveAngle - env->egtsPointEnv.beginAngle); + + if (angle > env->deviceTeledataStorageData->telematica.EGTS_FLEET_COURSE_THRESHOLD) { + + env->egtsPointEnv.beginAngle = moveAngle; + + if ((env->carEventPosition.carPosition == CAR_POSITION_MOVE) && + (env->totalSpeed > env->deviceTeledataStorageData->telematica.EGTS_GNSS_COURSE_SPEED)) { + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Скорость транспортного средства: %d", env->totalSpeed); + + env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_ROTATE_ANGLE_LIMIT].data); + } + + } + + uint16_t moveDist = getTotalDist(env); + uint16_t dist = abs(moveDist - env->egtsPointEnv.beginDist); + + if (dist > env->deviceTeledataStorageData->telematica.EGTS_FLEET_DIST_THRESHOLD) { + env->egtsPointEnv.beginDist = moveDist; + + env->egtsPointEnv.isEVENT_DISTANCE = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_DISTANCE].data); + } + + //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- + //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- + //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- + + // Отслеживание изменение состояния + if (egtsTsStatus != env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value) { + egtsTsStatus = env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value; + env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_VEH_STATE_CHANGED].data); + } + + + // Сброс события таймера, если было другое событие + if (((egtsEventTetedata != EVENT_INVALID_STATE) && (egtsEventTetedata != EVENT_EMERGENCY_TRACKING_TIMEOUT)) || + (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) || + (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) || + (env->egtsPointEnv.isEVENT_DISTANCE)) { + + if (GpioPinGet(EXT_ENV_TELE.ignition)) { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; + } else { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; + } + } + + // Отслеживание таймеров зажигания + if (GpioPinGet(EXT_ENV_TELE.ignition)) { + if (env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate < SystemGetMs()) { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; + env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_TIMEOUT_ENGINE_ON].data); + + } + + } else { + if (env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate < SystemGetMs()) { + env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; + env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_TIMEOUT_ENGINE_OFF].data); + } + + } + + // Отслеживание движения + // CarEventPosition(env, &nmeaRmc, totalSpeed); + + env->egtsPointEnv.isUpdatePoints = false; + + // Если транспортное средство в движении + if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { + if (isOneFixMove) { + isOneFixMove = false; + env->egtsPointEnv.isEVENT_MOVEMENT_ON = true; + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_MOVEMENT_ON].data); + } + + env->egtsPointEnv.isUpdatePoints = true; + } + + // Отслеживание таймера экстренного слежения + if ((env->carEventPosition.carPosition == CAR_POSITION_MOVE) && + (env->deviceTeledataStorageData->telematica.EGTS_FLEET_EM_MON_PERIOD != 0) && + (env->egtsPointEnv.timeOutCheckTeledata_EM_TimeUpdate < SystemGetMs())) { + + env->egtsPointEnv.timeOutCheckTeledata_EM_TimeUpdate = + SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_EM_MON_PERIOD * 1000; + env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT = true; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_EMERGENCY_TRACKING_TIMEOUT].data); + } + + + // Если транспортное средство не в движении + if (env->carEventPosition.carPosition == CAR_POSITION_FIX) { + isOneFixMove = true; + env->egtsPointEnv.isEVENT_MOVEMENT_OFF = true; + env->carEventPosition.carPosition = CAR_POSITION_UNDEFINED; + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", + textEgtsEventTetedata[EVENT_MOVEMENT_OFF].data); + } + + + if ((egtsEventTetedata != EVENT_INVALID_STATE) || + (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) || + (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) || + (env->egtsPointEnv.isEVENT_DISTANCE) || + (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF) || + (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON) || + (env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT) || + (env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED) || + (env->egtsPointEnv.isEVENT_MOVEMENT_ON) || + (env->egtsPointEnv.isEVENT_MOVEMENT_OFF) + ) { + + // Первое получение навигации + if (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) { + env->egtsPointEnv.isUpdatePoints = true; + } + + if (env->egtsPointEnv.isUpdatePoints) { + + uint8_t countSats = GnssGgaGetSat(env->gsm); + + env->egtsTeledataEdit.egtsExtPositionDataArgs.SAT = countSats; + env->egtsTeledataEdit.egtsExtPositionDataArgs.NS = 1; + + + env->egtsTeledataEdit.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); + + env->egtsTeledataAdditionalData.LAT = nmeaLocationToDeg(nmeaRmc.location.latitude); + env->egtsTeledataAdditionalData.LON = nmeaLocationToDeg(nmeaRmc.location.longitude); + + double lat = (fabs(env->egtsTeledataAdditionalData.LAT) / 90) * 0xFFFFFFFF; + env->egtsTeledataEdit.egtsPosDataArgs.LAT = (uint32_t) lat; + + double lon = (fabs(env->egtsTeledataAdditionalData.LON) / 180) * 0xFFFFFFFF; + env->egtsTeledataEdit.egtsPosDataArgs.LONG = (uint32_t) lon; + + env->egtsTeledataEdit.egtsPosDataArgs.FLG.VLD = (nmeaRmc.status == 'A') ? 1 + : 0; // Битовый флаг, признак «валидности» координатных данных + + env->egtsTeledataEdit.egtsPosDataArgs.FLG.FIX = 0; // битовое поле, тип определения координат + env->egtsTeledataEdit.egtsPosDataArgs.FLG.CS = 0; // битовое поле, тип используемой системы + env->egtsTeledataEdit.egtsPosDataArgs.FLG.BB = 0; // битовый флаг, признак отправки данных из памяти («черный ящик») + + if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { + env->egtsTeledataEdit.egtsPosDataArgs.FLG.MV = 1; // битовый флаг, признак движения + } else { + env->egtsTeledataEdit.egtsPosDataArgs.FLG.MV = 0; // битовый флаг, признак движения + } + + env->egtsTeledataEdit.egtsPosDataArgs.FLG.LAHS = (nmeaRmc.location.nsIndicator == 'S') ? 1 + : 0; // битовый флаг определяет полушарие широты + env->egtsTeledataEdit.egtsPosDataArgs.FLG.LOHS = (nmeaRmc.location.ewIndicator == 'W') ? 1 + : 0; // битовый флаг определяет полушарие долготы + env->egtsTeledataEdit.egtsPosDataArgs.FLG.ALTE = 1; // битовый флаг определяет наличие поля ALT в подзаписи + + uint16_t speed = (uint16_t) (nmeaRmc.knotVelocity * 1.82 * 10); + uint16_t dir = (uint16_t) nmeaRmc.headingAngle; + + env->egtsTeledataEdit.egtsPosDataArgs.SPD.SPD = speed & + 0b0011111111111111; // скорость в км/ч с дискретностью 0,1 км/ч (используется 14 младших бит) + + int32_t alt = GnssGgaGetAlt(env->gsm); + + if (alt >= 0) { + env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 0; + } else { + env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 1; + } + + env->egtsTeledataEdit.egtsPosDataArgs.SPD.DIRH = dir >> 8; // направление движения + + env->egtsTeledataEdit.egtsPosDataArgs.DIR = dir; // направление движения + env->egtsTeledataEdit.egtsPosDataArgs.ODM = 0; // пройденное расстояние (пробег) в км, с дискретностью 0,1 км + env->egtsTeledataEdit.egtsPosDataArgs.DIN = 0; // битовые флаги, определяют состояние основных дискретных входов + + env->egtsTeledataEdit.egtsPosDataArgs.ALT = abs(alt); + + // Обновление фиксированное позиции + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление фиксированной позиции") + env->egtsTeledataFix = env->egtsTeledataEdit; + + } else { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Фиксированные координаты. Движение не зафиксировано") + + env->egtsTeledataEdit.egtsPosDataArgs = env->egtsTeledataFix.egtsPosDataArgs; + + if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { + env->egtsTeledataEdit.egtsPosDataArgs.FLG.MV = 1; // битовый флаг, признак движения + } else { + env->egtsTeledataEdit.egtsPosDataArgs.FLG.MV = 0; // битовый флаг, признак движения + } + + env->egtsTeledataEdit.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); + + } + + if (egtsEventTetedata != EVENT_INVALID_STATE) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = egtsEventTetedata; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_NAVIGATION_START_STOP; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_ROTATE_ANGLE_LIMIT; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_DISTANCE) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_DISTANCE; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_TIMEOUT_ENGINE_OFF; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_TIMEOUT_ENGINE_ON; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_MOVEMENT_ON) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_MOVEMENT_ON; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_EMERGENCY_TRACKING_TIMEOUT; // определяет источник (событие) + + if (nmeaRmc.status != 'A') { + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Посылка точек при экстренном слежении не требуется, навигация не валидна") + } else { + addTeledataQueue(env, &env->egtsTeledataEdit); + } + } + + if (env->egtsPointEnv.isEVENT_MOVEMENT_OFF) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_MOVEMENT_OFF; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + if (env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED) { + env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_VEH_STATE_CHANGED; // определяет источник (событие) + addTeledataQueue(env, &env->egtsTeledataEdit); + } + + } + + } +} \ No newline at end of file diff --git a/EgtsTeledataPoint.h b/EgtsTeledataPoint.h new file mode 100644 index 0000000..e6af114 --- /dev/null +++ b/EgtsTeledataPoint.h @@ -0,0 +1,16 @@ +// +// Created by cfif on 12.06.2024. +// + +#ifndef SMART_COMPONENTS_EGTSTELEDATAPOINT_H +#define SMART_COMPONENTS_EGTSTELEDATAPOINT_H +#include "EgtsProcessing.h" + +_Noreturn void EgtsProcessing_TransmitterTaskTeledata(tEgtsProcessing *env); +_Noreturn void EgtsProcessing_EventTaskTeledata(tEgtsProcessing *env); +void addTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata); +void addTeledataQueueEvent(tEgtsProcessing *env, eEgtsEventTetedata egtsTeledataEvent); +bool extractTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata, uint32_t timeout); +void addEventFromUveos(tEgtsProcessing *env, const eEgtsEventTetedata *event); + +#endif //SMART_COMPONENTS_EGTSTELEDATAPOINT_H diff --git a/EgtsTeledataStoragePoint.c b/EgtsTeledataStoragePoint.c new file mode 100644 index 0000000..9da9aa9 --- /dev/null +++ b/EgtsTeledataStoragePoint.c @@ -0,0 +1,313 @@ +// +// Created by cfif on 02.08.2024. +// +#include "EgtsTeledataStoragePoint.h" +#include "lfs_file_utils.h" + +#define LOG_SIGN "EGTS STORE" +#define LOGGER &env->slog->logger + +extern const tStringStatic textEgtsEventTetedata[]; + +extern void addTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata); + +bool getPointStorageCount(tEgtsProcessing *env, uint32_t *countValidPoints) { + int lfs_err; + lfs_file_t file; + + tEgtsStorageTeledata egtsStorageTeledata; + + *countValidPoints = 0; + + lfs_err = lfs_file_open(&env->fs->lfs, &file, "points.bin", LFS_O_RDONLY); + + if (lfs_err != 0) { + return false; + } + + lfs_soff_t fileSize = lfs_file_size(&env->fs->lfs, &file); + +// lfs_err = lfs_file_rewind(&env->fs->lfs, &file); + int32_t seek = lfs_file_seek(&env->fs->lfs, &file, env->pPointsStorageSent * sizeof(tEgtsStorageTeledata), + LFS_SEEK_SET); + + uint32_t countPoints = fileSize / sizeof(tEgtsStorageTeledata) - env->pPointsStorageSent; + + for (uint32_t i = 0; i < countPoints; ++i) { + + int reading = lfs_file_read(&env->fs->lfs, &file, &egtsStorageTeledata, sizeof(tEgtsStorageTeledata)); + + if (reading != sizeof(tEgtsStorageTeledata)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка чтения файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + uint32_t crcCalc = lfs_crc(0, &egtsStorageTeledata, + sizeof(tEgtsStorageTeledata) - sizeof(egtsStorageTeledata.crc)); + + if (egtsStorageTeledata.crc != crcCalc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + if (egtsStorageTeledata.isValid) { + ++(*countValidPoints); + } + + } + + if (*countValidPoints == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Удаление точек из хранилища") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + return true; +} + +bool dumpPointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata, bool over) { + + if (env->egtsTeledataSent.egtsPosDataArgs.SRC < 88) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Сохранение точки в хранилище, событие: %s", + textEgtsEventTetedata[egtsTeledata->egtsPosDataArgs.SRC].data); + } else { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Неизвестное событие. Сохранение точки в хранилище, событие: %d", + env->egtsTeledataSent.egtsPosDataArgs.SRC); + } + + if ((egtsTeledata->egtsPosDataArgs.SRC != EVENT_EMERGENCY_CALL) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_USER_CALL) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_VEH_STATE_CHANGED) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_ROTATE_ANGLE_LIMIT) && + (egtsTeledata->egtsPosDataArgs.SRC != EVENT_NAVIGATION_START_STOP)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Точка не критичная. Сохранение отменено") + return true; + } + + int freeBlock = getFreeSize(&env->fs->lfs); + + int lfs_err; + + // 25 + if (freeBlock < 2) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "В хранилище закончилась память") + + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } else { +// LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Блоков, свободно: %d", freeBlock); + } + + /* + if (over) { + if (freeBlock <= 10) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "В хранилище закончилась память") + return false; + } + } else { + if (freeBlock <= 25) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "В хранилище закончилась память") + return false; + } + } +*/ + + lfs_file_t file; + + lfs_err = lfs_file_open(&env->fs->lfs, &file, "points.bin", LFS_O_WRONLY | LFS_O_APPEND | LFS_O_CREAT); + + if (lfs_err != 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка открытия файла (запись): points.bin") + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + tEgtsStorageTeledata egtsStorageTeledata; + egtsStorageTeledata.egtsPosDataArgs = egtsTeledata->egtsPosDataArgs; + egtsStorageTeledata.egtsExtPositionDataArgs = egtsTeledata->egtsExtPositionDataArgs; + egtsStorageTeledata.egtsSensorsDigArgs = egtsTeledata->egtsSensorsDigArgs; + egtsStorageTeledata.egtsSensorsAnArgs = egtsTeledata->egtsSensorsAnArgs; + + egtsStorageTeledata.isValid = true; + egtsStorageTeledata.crc = lfs_crc(0, &egtsStorageTeledata, + sizeof(tEgtsStorageTeledata) - sizeof(egtsStorageTeledata.crc)); + + int writes = lfs_file_write(&env->fs->lfs, &file, &egtsStorageTeledata, sizeof(tEgtsStorageTeledata)); + + if (writes != sizeof(tEgtsStorageTeledata)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + if (lfs_err != 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи файла: points.bin") + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + return true; +} + +bool loadPointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata) { + int lfs_err; + lfs_file_t file; + + lfs_err = lfs_file_open(&env->fs->lfs, &file, "points.bin", LFS_O_RDONLY); + + if (lfs_err != 0) { + return false; + } + + tEgtsStorageTeledata egtsStorageTeledata; + egtsStorageTeledata.egtsPosDataArgs = egtsTeledata->egtsPosDataArgs; + egtsStorageTeledata.egtsExtPositionDataArgs = egtsTeledata->egtsExtPositionDataArgs; + egtsStorageTeledata.egtsSensorsDigArgs = egtsTeledata->egtsSensorsDigArgs; + egtsStorageTeledata.egtsSensorsAnArgs = egtsTeledata->egtsSensorsAnArgs; + + lfs_soff_t fileSize = lfs_file_size(&env->fs->lfs, &file); + +// lfs_err = lfs_file_rewind(&env->fs->lfs, &file); + int32_t seek = lfs_file_seek(&env->fs->lfs, &file, env->pPointsStorageSent * sizeof(tEgtsStorageTeledata), + LFS_SEEK_SET); + +// uint32_t countPoints = fileSize / sizeof(tEgtsStorageTeledata); + +// for (uint32_t i = 0; i < countPoints; ++i) { + + int reading = lfs_file_read(&env->fs->lfs, &file, &egtsStorageTeledata, sizeof(tEgtsStorageTeledata)); + + if (reading != sizeof(tEgtsStorageTeledata)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка чтения файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + uint32_t crcCalc = lfs_crc(0, &egtsStorageTeledata, + sizeof(tEgtsStorageTeledata) - sizeof(egtsStorageTeledata.crc)); + + if (egtsStorageTeledata.crc != crcCalc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + if (egtsStorageTeledata.isValid) { + lfs_err = lfs_file_close(&env->fs->lfs, &file); + egtsTeledata->egtsPosDataArgs = egtsStorageTeledata.egtsPosDataArgs; + egtsTeledata->egtsExtPositionDataArgs = egtsStorageTeledata.egtsExtPositionDataArgs; + egtsTeledata->egtsSensorsDigArgs = egtsStorageTeledata.egtsSensorsDigArgs; + egtsTeledata->egtsSensorsAnArgs = egtsStorageTeledata.egtsSensorsAnArgs; + return true; + } + +// } + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + return false; +} + +bool deleteFilePointStorage(tEgtsProcessing *env) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Удаление точек из хранилища") + + int lfs_err = lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + + if (lfs_err != 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка удаления файла: points.bin") + return false; + } + + return true; +} + +/* +bool deletePointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata) { + int lfs_err; + lfs_file_t file; + + tEgtsStorageTeledata egtsStorageTeledata; + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Удаление точки из хранилища") + + lfs_err = lfs_file_open(&env->fs->lfs, &file, "points.bin", LFS_O_RDWR); + + if (lfs_err != 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка открытия файла (чтение): points.bin") + return false; + } + + lfs_soff_t fileSize = lfs_file_size(&env->fs->lfs, &file); + + lfs_err = lfs_file_rewind(&env->fs->lfs, &file); + + uint32_t countPoints = fileSize / sizeof(tEgtsStorageTeledata); + + for (uint32_t i = 0; i < countPoints; ++i) { + + int reading = lfs_file_read(&env->fs->lfs, &file, &egtsStorageTeledata, sizeof(tEgtsStorageTeledata)); + + if (reading != sizeof(tEgtsStorageTeledata)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка чтения файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + uint32_t crcCalc = lfs_crc(0, &egtsStorageTeledata, + sizeof(tEgtsStorageTeledata) - sizeof(egtsStorageTeledata.crc)); + + if (egtsStorageTeledata.crc != crcCalc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + if (egtsStorageTeledata.isValid) { + + egtsStorageTeledata.isValid = false; + egtsStorageTeledata.crc = lfs_crc(0, &egtsStorageTeledata, + sizeof(tEgtsStorageTeledata) - sizeof(egtsStorageTeledata.crc)); + + int32_t seek = lfs_file_seek(&env->fs->lfs, &file, i * sizeof(tEgtsStorageTeledata) + sizeof(tEgtsStorageTeledata)- 8, LFS_SEEK_SET); + + int writes = lfs_file_write(&env->fs->lfs, &file, &egtsStorageTeledata, 8); + + if (writes != 8) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи файла: points.bin") + lfs_err = lfs_file_close(&env->fs->lfs, &file); + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + if (lfs_err != 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи файла: points.bin") + lfs_err = lfs_remove(&env->fs->lfs, "points.bin"); + return false; + } + + return true; + } + + } + + lfs_err = lfs_file_close(&env->fs->lfs, &file); + + return true; +} +*/ \ No newline at end of file diff --git a/EgtsTeledataStoragePoint.h b/EgtsTeledataStoragePoint.h new file mode 100644 index 0000000..b5d0858 --- /dev/null +++ b/EgtsTeledataStoragePoint.h @@ -0,0 +1,17 @@ +// +// Created by cfif on 02.08.2024. +// + +#ifndef SMART_COMPONENTS_TELEMATICA_EGTSTELEDATASTORAGEPOINT_H +#define SMART_COMPONENTS_TELEMATICA_EGTSTELEDATASTORAGEPOINT_H + +#include "EgtsProcessing.h" + +bool getPointStorageCount(tEgtsProcessing *env, uint32_t *countValidPoints); +bool dumpPointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata, bool over); +bool loadPointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata); +bool deleteFilePointStorage(tEgtsProcessing *env); +//bool deletePointStorage(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata); + + +#endif //SMART_COMPONENTS_TELEMATICA_EGTSTELEDATASTORAGEPOINT_H diff --git a/EgtsTelesataTypes.h b/EgtsTelesataTypes.h new file mode 100644 index 0000000..b0bc102 --- /dev/null +++ b/EgtsTelesataTypes.h @@ -0,0 +1,258 @@ +// +// Created by cfif on 03.09.2024. +// + +#ifndef SMART_COMPONENTS_TELEMATICA_V2_EGTSTELESATATYPES_H +#define SMART_COMPONENTS_TELEMATICA_V2_EGTSTELESATATYPES_H + +#include "stdint.h" +#include "CmsisRtosThreadUtils.h" +#include "stdbool.h" + +#define TELEDATA_QUEUE_SIZE 20 + +typedef enum { + CAR_POSITION_UNDEFINED = 0, + CAR_POSITION_FIX = 1, + CAR_POSITION_MOVE = 2 +} eCarPosition; + +typedef struct __attribute__ ((packed)) { + uint16_t SPD: 14; + uint8_t ALTS: 1; + uint8_t DIRH: 1; +} tSPD; + +typedef struct __attribute__ ((packed)) { + uint8_t VLD: 1; + uint8_t CS: 1; + uint8_t FIX: 1; + uint8_t BB: 1; + uint8_t MV: 1; + uint8_t LAHS: 1; + uint8_t LOHS: 1; + uint8_t ALTE: 1; +} tFLG; + +typedef struct __attribute__ ((packed)) { + uint8_t state: 4; + uint16_t number: 12; +} tEgtsSensorsDigState; + +typedef struct __attribute__ ((packed)) { + uint8_t number; + uint32_t value: 24; +} tEgtsSensorsAnState; + +typedef struct { + tEgtsSensorsDigState sensorsDigState[4]; +} tEgtsSensorsDigDataArgs; + + +typedef struct { + tEgtsSensorsAnState sensorsAnState[20]; +} tEgtsSensorsAnDataArgs; + +typedef struct __attribute__ ((packed)) { + uint32_t NTM; + uint32_t LAT; + uint32_t LONG; + tFLG FLG; + tSPD SPD; + uint8_t DIR; + uint32_t ODM; + uint8_t DIN; + uint32_t ALT; + uint16_t SRC; +} tEgtsPositionDataArgs; + + +typedef struct __attribute__ ((packed)) { + uint8_t VFE: 1; + uint8_t HFE: 1; + uint8_t PFE: 1; + uint8_t SFE: 1; + uint8_t NSFE: 1; + uint8_t RESERVED1: 1; + uint8_t RESERVED2: 1; + uint8_t RESERVED3: 1; +} tEXTFLG; + +typedef struct __attribute__ ((packed)) { + tEXTFLG FLG; + uint8_t SAT; + uint16_t NS; +} tEgtsExtPositionDataArgs; + +typedef struct { + osMessageQueueId_t queue; + osMessageQueueId_t queueEvent; + uint16_t idPacked; + bool isReceivedResponse; + double LAT; + double LON; +} tEgtsTeledataAdditionalData; + +typedef struct { + tEgtsPositionDataArgs egtsPosDataArgs; + tEgtsExtPositionDataArgs egtsExtPositionDataArgs; + tEgtsSensorsDigDataArgs egtsSensorsDigArgs; + tEgtsSensorsAnDataArgs egtsSensorsAnArgs; + uint32_t isValid; + uint32_t crc; +} tEgtsStorageTeledata; + +typedef struct { + tEgtsPositionDataArgs egtsPosDataArgs; + tEgtsExtPositionDataArgs egtsExtPositionDataArgs; + tEgtsSensorsDigDataArgs egtsSensorsDigArgs; + tEgtsSensorsAnDataArgs egtsSensorsAnArgs; +} tEgtsTeledata; + +//конец ---------------------------------Теледанные--------------------------------------------------------------------- +//конец ---------------------------------Теледанные--------------------------------------------------------------------- +//конец ---------------------------------Теледанные--------------------------------------------------------------------- + +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- + +#define TESTER_REQUEST_FUNC 0x7DF +#define TESTER_REQUEST_ABS_ESP 0x7E3 +#define TESTER_REQUEST_ACU 0x7E5 +#define TESTER_REQUEST_ECM 0x7E0 +#define TESTER_REQUEST_GNSS 0x7CA +#define TESTER_REQUEST_HVAC 0x7E4 +#define TESTER_REQUEST_IMMO_D 0x723 +#define TESTER_REQUEST_ITELMA_IMMO_D 0x7e6 +#define TESTER_REQUEST_PTS 0x7E7 +#define TESTER_REQUEST_SAS 0x70D + + +#define TESTER_RESPONSE_ABS_ESP 0x7EB +#define TESTER_RESPONSE_ACU 0x7ED +#define TESTER_RESPONSE_ECM 0x7E8 +#define TESTER_RESPONSE_GNSS 0x7DA +#define TESTER_RESPONSE_HVAC 0x7EC +#define TESTER_RESPONSE_IMMO_D 0x7A3 +#define TESTER_RESPONSE_ITELMA_IMMO_D 0x7ee +#define TESTER_RESPONSE_PTS 0x7EF +#define TESTER_RESPONSE_SAS 0x70E + +#define EBU_STATE_UPDATE 0 +#define EBU_STATE_INIT 0xFFFFFFFF + +#define EBU_COUNT_FS_ITEMS 6 +#define EBU_COUNT_TABLE_ITEMS 9 +#define EBU_COUNT_TEST_ITEMS 20 +#define EBU_COUNT_DID_LIST_ITEMS 18 + +typedef enum { + EBU_GNSS = 0, + EBU_ABS = 1, + EBU_ECM = 2, + EBU_HVAC = 3, + EBU_IMMO = 4, + EBU_PTS = 5, + + EBU_UNKNOWN = 255 +} eEgtsEbu; + +typedef enum { + TS_STATUS_DEEP_SLEEP = 0, + TS_STATUS_SLEEP = 1, + TS_STATUS_STANDBY = 2, + TS_STATUS_IGNITION = 3, + TS_STATUS_DRIVE = 4, + TS_STATUS_REMOTE_START = 5, + TS_STATUS_SERVICE_MODE = 6, + TS_STATUS_PREHEATING = 8, + TS_STATUS_COMFORT = 9, + TS_STATUS_MULTIMEDIA = 10, + TS_STATUS_UNKNOWN = 15 +} eEgtsTsStatus; + +typedef struct { + eEgtsEbu ebu; + const char *ebuName; + uint16_t ecu_req; + uint16_t ecu_resp; + uint16_t test_did; + uint16_t did_list[EBU_COUNT_DID_LIST_ITEMS]; +} tEgtsEbuName; + +typedef enum { + CERTS_STATUS_LOAD = 0, + CERTS_STATUS_UNLOAD = 1, + CERTS_STATUS_ERROR = 2 +} eEgtsCertsStatus; + +typedef enum { + TEST_FIRMWARE = 0, + TEST_IGNITION = 1, + TEST_BAT_CONNECT = 2, + TEST_BAT_CHARGE = 3, + TEST_BAT_VOLTAGE = 4, + TEST_GNSS_ANT = 5, + TEST_SPEAKER_CONNECT = 6, + TEST_BIP_CONNECT = 7, + TEST_ACCEL = 8, + TEST_GSM = 9, + TEST_AUDIO_CODEC = 10, + TEST_VIN = 11, + TEST_ACCEL_CALIB = 12, + TEST_EOL = 13, + TEST_TELE = 14, + TEST_MODEM_SOFT_REV = 15, + TEST_CERT_REV = 16, + TEST_AUDIO_FILE = 17, + TEST_AMPLIFIER = 18, + TEST_SIM_ERA = 19, + TEST_SIM_COMERS = 20, + +} eEgtsTestEbu; + +typedef enum { + STATUS_STEP_NONE = 0, + STATUS_STEP_DIAGNOSTIC = 1, + STATUS_STEP_READ_DTC = 2, + STATUS_STEP_READ_TEST_IDENTIFIER = 3, + STATUS_STEP_READ_IDENTIFIER = 4, + STATUS_STEP_DTC_CLEAR = 5 +} eEgtsStepStatus; + +typedef struct { + eEgtsTestEbu ebu; + const char *ebuTestName; +} tEgtsEbuTestName; + +typedef struct { + eEgtsEbu ebu; + bool clearDTC; + uint32_t timestamp; +} tEgtsEbuItemState; + +#define VERSION_EBU 6 + +typedef struct { + uint32_t version; + tEgtsEbuItemState ebuItemState[EBU_COUNT_FS_ITEMS]; + uint16_t count; + uint32_t crc; +} tEgtsEbuState; + +typedef struct { + bool isUdsBufReady; + eEgtsStepStatus step; + int8_t attempts; + uint8_t counterDID; + uint8_t ebuIndex; + uint8_t buf[2048]; + uint16_t bufLen; +} tEgtsEbuUdsReady; + +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- +//начало ---------------------------------ЭБУ------------------------------------------------------------------------- + +#endif //SMART_COMPONENTS_TELEMATICA_V2_EGTSTELESATATYPES_H diff --git a/EgtsUpdateFirmware.c b/EgtsUpdateFirmware.c new file mode 100644 index 0000000..a187e44 --- /dev/null +++ b/EgtsUpdateFirmware.c @@ -0,0 +1,320 @@ +// +// Created by cfif on 12.07.2024. +// +#include "EgtsUpdateFirmware.h" +#include "InternalFlashPage.h" +#include "AtGsmSimComA7600_SSL_LOAD_CA.h" +#include "FirmwareLoader.h" +#include "aes.h" +#include "EgtsProcessing.h" +#include "SystemDelayInterface.h" +#include "egts_crc.h" +#include "GsmWithGnss_Info.h" + +#define LOG_SIGN "EGTS_UPDATE" +#define LOGGER &env->slog->logger + +extern tFirmwareLoader FIRMWARE_LOADER; + +void receivedUpdateFirmware(tEgtsProcessing *env) { + if(env->isTimerUpdate == false){ + env->isTimerUpdate = true; + env->timerUpdate = SystemGetMs()+60*5*1000; + } + LoggerFormatInfo(LOGGER, LOG_SIGN, + "Получен пакет прошивки, %d из %d (%d байт данных)", + env->egtsEnv.firmware->PartNumber, + env->egtsEnv.firmware->ExpectedPartsQuantity, + env->egtsEnv.firmware->dataLength); + + + eEgtsFirmwareResult isFirmwareResult = EGTS_FIRMWARE_OK; + uint8_t rst = EGTS_PC_IN_PROGRESS; + + // Пришел первый пакет обновления + if (env->egtsEnv.firmware->PartNumber == 1) { + + // Останов навигации + //LoggerInfoStatic(LOGGER, LOG_SIGN, "Остановка потока навигации"); + //SetConfigureStaticRMCThreadStop(env->gsm); + + env->firmwareOffset = 0; + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Подготовка ПЗУ"); + env->firmwareBufCrc = env->egtsEnv.firmware->WholeObjectSignature; + + if (osMutexAcquire(EXT_ENV_TELE.store.accessDumper, 5000) == osOK) { + if (FirmwareLoader_ClearUpdateFlash(&FIRMWARE_LOADER)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "ПЗУ очищено"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка очистки ПЗУ"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_WRITE_PZU; + } + + osMutexRelease(EXT_ENV_TELE.store.accessDumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа receivedUpdateFirmware"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_ACCESS; + } + + } + + if (env->firmwareOffset + env->egtsEnv.firmware->dataLength > FIRMWARE_LOADER.fwSize) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Переполнение буфера ПЗУ"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_OVERFLOW_PZU; + } else { + + if (osMutexAcquire(EXT_ENV_TELE.store.accessDumper, 5000) == osOK) { + if (sInternalFlashPage_Write(FIRMWARE_LOADER.update.address, + env->firmwareOffset, + env->egtsEnv.firmware->dataPointer, + env->egtsEnv.firmware->dataLength) == env->egtsEnv.firmware->dataLength) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Успешно записан в ПЗУ"); + + env->firmwareOffset += env->egtsEnv.firmware->dataLength; + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи в ПЗУ"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_WRITE_PZU; + } + + osMutexRelease(EXT_ENV_TELE.store.accessDumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа receivedUpdateFirmware"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_ACCESS; + } + + if (env->egtsEnv.firmware->PartNumber == env->egtsEnv.firmware->ExpectedPartsQuantity) { + + uint16_t crcEgts16 = CRC16EGTS((uint8_t *) (FIRMWARE_LOADER.update.address), env->firmwareOffset); + + if (crcEgts16 != env->firmwareBufCrc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы (ЕГТС)"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_EGTS_CRC; + } + + uint32_t pos = env->firmwareOffset - 256; + + uint32_t offsetMetaCrc = *(uint32_t *) &((uint8_t *) (FIRMWARE_LOADER.update.address))[pos]; + pos += 4; + uint32_t offsetMetaSize = *(uint32_t *) &((uint8_t *) (FIRMWARE_LOADER.update.address))[pos]; + pos += 4; + + tString32 FW_NAME; + + FW_NAME.length = *(uint8_t *) &((uint8_t *) (FIRMWARE_LOADER.update.address))[pos]; + pos += 1; + + if (FW_NAME.length > 32) { + FW_NAME.length = 0; + } else { + memcpy(FW_NAME.data, &((uint8_t *) (FIRMWARE_LOADER.update.address))[pos], FW_NAME.length); + } + + uint8_t posDel = findDelimiter(&FW_NAME, '_') + 1; + + if (memcmp(&FW_NAME.data[posDel], "TELE", 4) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка телематики"); + } else if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка ключей"); + } else if (memcmp(&FW_NAME.data[posDel], "UVEOS", 5) == 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка УВЭОС"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена неизвестная прошивка"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_UNKNOWN; + } + + if (isFirmwareResult == EGTS_FIRMWARE_OK) { + + uint32_t crc32 = 0; + for (uint32_t i = 0; i < offsetMetaSize; ++i) { + crc32 += ((uint8_t *) FIRMWARE_LOADER.update.address)[i]; + } + + if (crc32 != offsetMetaCrc) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы (ПРОШИВКИ)"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_MY_CRC; + } else { + + if (memcmp(&FW_NAME.data[posDel], "TELE", 4) == 0) { + + EXT_ENV_TELE.store.AdditionalSettings->REGION_SIZE_UPDATE = env->firmwareOffset; + + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Загрузка прошивки телематики завершена"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Необходимо перезагрузить устройство"); + rst = EGTS_PC_OK; + env->rebootFirmware = true; + + } else if (memcmp(&FW_NAME.data[posDel], "UVEOS", 5) == 0) { + + EXT_ENV_TELE.store.AdditionalSettings->REGION_SIZE_UPDATE = env->firmwareOffset; + + EraGlonassUveosDumper_ForceDump(EXT_ENV_TELE.store.uveosDumper); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Загрузка прошивки УВЭОС завершена"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Необходимо перезагрузить устройство"); + rst = EGTS_PC_OK; + env->rebootFirmware = true; + + + } else if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { + + tIsFind check; + memset(&check, 0, sizeof(check)); + + tEgtsCertInfo *egtsCertInfo = (tEgtsCertInfo *) ((uint8_t *) (FIRMWARE_LOADER.update.address)); + + uint8_t *firmwareKeyBuf = &env->wb[0]; + + + if (offsetMetaSize > (sizeof(env->wb))) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка выделения ОЗУ при загрузке ключей") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка загрузки ключей"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_KEY; + } else { + memcpy(firmwareKeyBuf, (uint8_t *) (FIRMWARE_LOADER.update.address), offsetMetaSize); + + // Если ключи зашифрованы + if (egtsCertInfo->ENC) { + + struct AES_ctx ctx; + uint8_t key[16]; + uint8_t iv[16]; + memset(iv, '3', sizeof(key)); + memset(key, '0', sizeof(key)); + uint8_t offsetKey = 0; + + uint32_t lenEnc = offsetMetaSize - sizeof(tEgtsCertInfo); + + uint8_t IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length; + if (EXT_ENV_TELE.store.device->cgsmid.length >= 2) { + if ((EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 1] == '\n') && + (EXT_ENV_TELE.store.device->cgsmid.data[IMEI_len - 2] == '\r')) { + IMEI_len = EXT_ENV_TELE.store.device->cgsmid.length - 2; + } + } + + if (IMEI_len < 16) + offsetKey = 16 - IMEI_len; + + memcpy(&key[offsetKey], EXT_ENV_TELE.store.device->cgsmid.data, IMEI_len); + + + AES_init_ctx_iv(&ctx, key, iv); + AES_CBC_decrypt_buffer(&ctx, &firmwareKeyBuf[sizeof(tEgtsCertInfo)], + lenEnc); + } + + if (osMutexAcquire(env->gsm->gsmAt->access, 15000) == osOK) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Удаление старых ключей"); + + check = AtGsmSimComA7600_SSL_CHECK_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + file_crt, strlen(file_crt), + file_key, strlen(file_key), 2000); + + if ((!check.isFind1) && (!check.isFind2) && (!check.isFind3)) + LoggerInfoStatic(LOGGER, LOG_SIGN, "Старые ключи удалены"); + + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + &firmwareKeyBuf[sizeof(tEgtsCertInfo)], + egtsCertInfo->SIZE_ROOT_CA, + 2000); + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_key, strlen(file_key), + &firmwareKeyBuf[sizeof(tEgtsCertInfo) + + egtsCertInfo->SIZE_ROOT_CA], + egtsCertInfo->SIZE_CLIENT_KEY, 2000); + + AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, + file_crt, strlen(file_crt), + &firmwareKeyBuf[sizeof(tEgtsCertInfo) + + egtsCertInfo->SIZE_ROOT_CA + + egtsCertInfo->SIZE_CLIENT_KEY], + egtsCertInfo->SIZE_CLIENT_CRT, 2000); + + check = AtGsmSimComA7600_SSL_CHECK_CA(env->gsm->gsmAt, + file_ca, strlen(file_ca), + file_crt, strlen(file_crt), + file_key, strlen(file_key), 2000); + + if ((check.isFind1) && (check.isFind2) && (check.isFind3)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Новые ключи загружены"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Необходимо перезагрузить устройство"); + rst = EGTS_PC_OK; + env->rebootFirmware = true; + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка загрузки ключей"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_KEY; + } + + osMutexRelease(env->gsm->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа при загрузке ключей"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_ACCESS; + } + + } + + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена неизвестная прошивка"); + isFirmwareResult = EGTS_FIRMWARE_ERROR_UNKNOWN; + } + + + } + + + } + + } + } + + if ((isFirmwareResult != EGTS_FIRMWARE_OK)) { + + if (isFirmwareResult == EGTS_FIRMWARE_ERROR_OVERFLOW_PZU) { + rst = EGTS_PC_MODULE_MEM_FLT; + } + + if ((isFirmwareResult == EGTS_FIRMWARE_ERROR_ACCESS) || (isFirmwareResult == EGTS_FIRMWARE_ERROR_KEY)) { + rst = EGTS_PC_MODULE_PROC_FLT; + } + + if (isFirmwareResult == EGTS_FIRMWARE_ERROR_WRITE_PZU) { + rst = EGTS_PC_MODULE_IO_FLT; + } + + if (isFirmwareResult == EGTS_FIRMWARE_ERROR_UNKNOWN) { + rst = EGTS_PC_MODULE_FW_FLT; + } + + if ((isFirmwareResult == EGTS_FIRMWARE_ERROR_EGTS_CRC) || (isFirmwareResult == EGTS_FIRMWARE_ERROR_MY_CRC)) { + rst = EGTS_PC_DATACRC_ERROR; + } + + } + + + EgtsProcessing_SendResponse(env, EGTS_FIRMWARE_SERVICE, + EGTS_FIRMWARE_SERVICE, + EGTS_SERVICE_FLAGS_FIRMWARE, + rst, + env->egtsEnv.recordNumber); + + if (env->rebootFirmware) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическая перезагрузка, через 5 сек"); + SystemDelayMs(5000); + NVIC_SystemReset(); + } + +} \ No newline at end of file diff --git a/EgtsUpdateFirmware.h b/EgtsUpdateFirmware.h new file mode 100644 index 0000000..4f3178b --- /dev/null +++ b/EgtsUpdateFirmware.h @@ -0,0 +1,27 @@ +// +// Created by cfif on 12.07.2024. +// + +#ifndef SMART_COMPONENTS_TELEMATICA_EGTSUPDATEFIRMWARE_H +#define SMART_COMPONENTS_TELEMATICA_EGTSUPDATEFIRMWARE_H + +#define EGTS_PC_OK 0 +#define EGTS_PC_IN_PROGRESS 1 +#define EGTS_PC_MODULE_IO_FLT 162 // Сбой в работе блока ввода/вывода модуля +#define EGTS_PC_MODULE_MEM_FLT 163 // Сбой в работе внутренней памяти модуля +#define EGTS_PC_MODULE_PROC_FLT 159 // Сбой в работе микроконтроллера модуля +#define EGTS_PC_MODULE_FW_FLT 161 // Сбой в работе внутреннего ПО модуля +#define EGTS_PC_DATACRC_ERROR 138 // Ошибка контрольной суммы данных + +typedef enum { + EGTS_FIRMWARE_OK = 0, + EGTS_FIRMWARE_ERROR_WRITE_PZU = 1, + EGTS_FIRMWARE_ERROR_OVERFLOW_PZU = 2, + EGTS_FIRMWARE_ERROR_ACCESS = 3, + EGTS_FIRMWARE_ERROR_UNKNOWN = 4, + EGTS_FIRMWARE_ERROR_EGTS_CRC = 5, + EGTS_FIRMWARE_ERROR_MY_CRC = 6, + EGTS_FIRMWARE_ERROR_KEY = 7 +} eEgtsFirmwareResult; + +#endif //SMART_COMPONENTS_TELEMATICA_EGTSUPDATEFIRMWARE_H diff --git a/Network.c b/Network.c new file mode 100644 index 0000000..4a84890 --- /dev/null +++ b/Network.c @@ -0,0 +1,119 @@ +// +// Created by cfif on 05.06.2024. +// +#include "Network.h" +#include "GsmWithGnss_Info.h" +#include "EgtsOutputCommands.h" +#include "ext_telematica.h" +#include "SystemDelayInterface.h" +#include "EgtsEbu.h" + +#define LOG_SIGN "EGTS_INFO" +#define LOGGER &env->slog->logger + +extern volatile uint32_t valueCounter1; +extern volatile uint32_t valueCounter2; +extern volatile uint32_t valueCounter3; + + +void _Noreturn EgtsProcessing_InfoTask(tEgtsProcessing *env) { + + uint32_t timeOutCheckNetworkStatus = 0; + + bool oneOn = true; + bool oneOff = true; + + while (1) { + + // Поднят пин зажигания + bool isIgnition = GpioPinGet(EXT_ENV_TELE.ignition); + + // Поднят пин зажигания + if (isIgnition) { + // Обороты больше 100 + if (env->CanMainAdditional.EngineSpeed > 100) { + ++env->SENSORS_AN_MinutesOfTravel_gl; + } + } + + if (SystemGetMs() > env->CanMainAdditional.isTimeSENSORS_DIG_BodyCanBusStatus + 3500) { + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_BodyCanBusStatus].state = 0; + } else { + env->egtsTeledataEdit.egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_BodyCanBusStatus].state = 1; + } + + if (onOffTelematica(env, &oneOn, &oneOff, "Задача информации")) + continue; + + //начало-----------------Обновление счетчиков телематики (для отладки)-------------------------------------- + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS1].value = valueCounter1; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS2].value = valueCounter2; + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS3].value = valueCounter3; + //конец------------------Обновление счетчиков телематики (для отладки)-------------------------------------- + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Voltage12Volts].value = *EXT_ENV_TELE.vBoardVoltage; + + //начало ---------------------------------Обновление RSSI NETWORK SAT------------------------------------------- + //начало ---------------------------------Обновление RSSI NETWORK SAT------------------------------------------- + //начало ---------------------------------Обновление RSSI NETWORK SAT------------------------------------------- + + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Uptime].value = + SystemGetMs() / 60000; // Uptime + + // По умолчанию в SLEEP, до этого было в TS_STATUS_STANDBY + eEgtsTsStatus SENSORS_AN_VehicleStatus_loc = TS_STATUS_SLEEP; + + // Поднят пин зажигания + if (isIgnition) { + SENSORS_AN_VehicleStatus_loc = TS_STATUS_IGNITION; + + // Обороты больше 100 + if (env->CanMainAdditional.EngineSpeed > 100) { + SENSORS_AN_VehicleStatus_loc = TS_STATUS_DRIVE; + } + + } else { + // Температура двигателя + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOXTemperature].value = 0; + // Внешняя температура + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ExternalTemperature].value = 0; + // Обороты двигателя + env->CanMainAdditional.EngineSpeed = 0; + } + + // Секунд поездки + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_MinutesOfTravel].value = env->SENSORS_AN_MinutesOfTravel_gl; + + // Установка значения сенсора состояния + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value = SENSORS_AN_VehicleStatus_loc; + + if (timeOutCheckNetworkStatus < SystemGetMs()) { + + timeOutCheckNetworkStatus = SystemGetMs() + AURUS_CHECK_NETWORK_STATUS; + uint8_t status = EpsNetworkRegistrationStatus(env->gsm); + + if (status == 0) + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].value = 0; + + if ((status > 0) && (status <= 3)) { + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].value = 44; // 2G + } + + if ((status >= 4) && (status <= 7)) { + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].value = 60; // 3G + } + + if (status >= 8) { + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NetworkType].value = 76; // LTE + } + + uint8_t rssi = QuerySignalQuality(env->gsm); + env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_RSSI].value = rssi; + } + //конец ---------------------------------Обновление RSSI NETWORK SAT-------------------------------------------- + //конец ---------------------------------Обновление RSSI NETWORK SAT-------------------------------------------- + //конец ---------------------------------Обновление RSSI NETWORK SAT-------------------------------------------- + + SystemDelayMs(1000); + } +} \ No newline at end of file diff --git a/Network.h b/Network.h new file mode 100644 index 0000000..6e5491c --- /dev/null +++ b/Network.h @@ -0,0 +1,11 @@ +// +// Created by cfif on 05.06.2024. +// + +#ifndef SMART_COMPONENTS_NETWORK_H +#define SMART_COMPONENTS_NETWORK_H +#include "EgtsProcessing.h" + +void _Noreturn EgtsProcessing_InfoTask(tEgtsProcessing *env); + +#endif //SMART_COMPONENTS_NETWORK_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..30c15d5 --- /dev/null +++ b/modular.json @@ -0,0 +1,18 @@ +{ + "dep": [ + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "Legacy_EgtsEncoderDecoder" + } + ], + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} +