From b8016219e3dbe2851b0bacc3a3b64c8eec6e519d Mon Sep 17 00:00:00 2001 From: cfif Date: Wed, 4 Dec 2024 13:10:49 +0300 Subject: [PATCH] Init --- Inc/EraGlonassUveos.h | 168 +++++++ Inc/EraGlonassUveos_Dumper.h | 17 + Inc/EraGlonassUveos_EcallProvider.h | 67 +++ Inc/EraGlonassUveos_Indicatior.h | 28 ++ Inc/EraGlonassUveos_NavDataProvider.h | 30 ++ Inc/EraGlonassUveos_Private.h | 46 ++ Inc/EraGlonassUveos_SmsProvider.h | 20 + Src/EraGlonassUveos.c | 314 ++++++++++++ Src/EraGlonassUveos_DoNothingModes.c | 127 +++++ Src/EraGlonassUveos_Egts.c | 198 ++++++++ Src/EraGlonassUveos_EmergencyMode.c | 686 ++++++++++++++++++++++++++ modular.json | 47 ++ 12 files changed, 1748 insertions(+) create mode 100644 Inc/EraGlonassUveos.h create mode 100644 Inc/EraGlonassUveos_Dumper.h create mode 100644 Inc/EraGlonassUveos_EcallProvider.h create mode 100644 Inc/EraGlonassUveos_Indicatior.h create mode 100644 Inc/EraGlonassUveos_NavDataProvider.h create mode 100644 Inc/EraGlonassUveos_Private.h create mode 100644 Inc/EraGlonassUveos_SmsProvider.h create mode 100644 Src/EraGlonassUveos.c create mode 100644 Src/EraGlonassUveos_DoNothingModes.c create mode 100644 Src/EraGlonassUveos_Egts.c create mode 100644 Src/EraGlonassUveos_EmergencyMode.c create mode 100644 modular.json diff --git a/Inc/EraGlonassUveos.h b/Inc/EraGlonassUveos.h new file mode 100644 index 0000000..a7524b3 --- /dev/null +++ b/Inc/EraGlonassUveos.h @@ -0,0 +1,168 @@ +// +// Created by xemon on 21.10.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_H + +#include "UveosGostSettings.h" +#include "EraGlonassMsdTable.h" + +#include "LoggerInterface.h" +#include "UveosEmergencyEventInterface.h" +#include "UserButtonsInterface.h" + +#include "EraGlonassUveos_NavDataProvider.h" +#include "EraGlonassUveos_EcallProvider.h" +#include "EraGlonassUveos_SmsProvider.h" +#include "EraGlonassUveos_Dumper.h" +#include "EraGlonassUveos_Indicatior.h" +#include "AudioPlayerInterface.h" +#include "DeviceStorage.h" +#include "RtcIO.h" + + + +typedef enum { + UVEOS_DO_NOTHING_DISABLED, + UVEOS_DO_NOTHING_GARAGE, + UVEOS_DO_NOTHING_TESTING, + UVEOS_DO_NOTHING_MOVE_TO, +} eUveosDoNothing; + +typedef enum { + ERA_GLONASS_UVEOS_CALL_SUCCESS, + ERA_GLONASS_UVEOS_CALL_FAIL, + ERA_GLONASS_UVEOS_CALL_USER_BREAK, + ERA_GLONASS_UVEOS_SMS_SENT, + ERA_GLONASS_UVEOS_SEND_FAIL, + ERA_GLONASS_UVEOS_TEST_CALL_NOT_ALLOWED, +} eEraGlonassUveos_EcallProcessingResult; + + + +typedef struct { + uint8_t len; + uint8_t data[ERA_GLONASS_MSD_ENCODED_BUFFER_LENGTH]; +} tMsdEncoded; + +typedef struct { + uint8_t len; + uint8_t data[128]; +} tEgtsEncoded; + +typedef struct { + tLoggerInterface *logger; + tUveosGostSettings *settings; + + tNavDataProvider *navDataProvider; + tEraGlonassMsdTable *msdTable; + tEraGlonassMsdTableItem *currentMsd; + tEraGlonassUveosDumperInterface *dumper; + tEraGlonassEcallProvider *ecallProvider; + tUserButtonsInterface *buttons; + tEraGlonassSmsProvider *smsProvider; + tEraGlonassUveosIndicator *indicator; + + struct { + uint16_t emergensy; + uint16_t additional; + + } buttonsIds; + + struct { + uint64_t allowInCall; + uint64_t requireNetwork; + uint64_t lastTestCall; + uint64_t lastInMemTransmit; + uint64_t lastNetworkRequest; + uint64_t powerOfDelay; + tRtcIO *rtcIo + } timings; + + struct { + uint32_t movDist; + uint64_t stopLimitTime; + eUveosDoNothing mode; + EraGlonassUveosNavData beginPosition; + EraGlonassUveosNavData movePosition; + } doNothing; + + tAudioPlayerInterface *audioPlayer; + uint32_t offsetToDistance; +} tEraGlonassUveos; + +void EraGlonassUveos_Init( + tEraGlonassUveos *env, + tLoggerInterface *logger, + + tEraGlonassMsdTable *msdTable, + tUveosGostSettings *settings, + tEraGlonassUveosDumperInterface *dumper, + + tNavDataProvider *navDataProvider, + tEraGlonassEcallProvider *ecallProvider, + tEraGlonassSmsProvider *smsProvider, + + tEraGlonassUveosIndicator *indicator, + tUserButtonsInterface *buttons, + uint16_t addButtonId, + tAudioPlayerInterface *audioPlayer, + tRtcIO *Rtc, + uint32_t stopLimitTime +); + +void EraGlonassUveos_CompileMsd(tEraGlonassUveos *env, tEraGlonassMsd *msd, tMsdEncoded *msdEncoded); + +void EraGlonassUveos_InvalidateSettings(tEraGlonassUveos *env); + +bool EraGlonassUveos_IsAllowInCall(tEraGlonassUveos *env); + +bool EraGlonassUveos_IsStandby(tEraGlonassUveos *env); + +bool EraGlonassUveos_IsPowerOffDelay(tEraGlonassUveos *env); + +bool EraGlonassUveos_IsRequireNetwork(tEraGlonassUveos *env); + +bool EraGlonassUveos_IsEraAllowed(tEraGlonassUveos *env); + +void EraGlonassUveos_ProcessingEra(tEraGlonassUveos *env); + +void EraGlonassUveos_ProcessingCheckNoSendMSD(tEraGlonassUveos *env); + +void EraGlonassUveos_ManualEmergencyCall(tEraGlonassUveos *env, bool fl_blocRegNet); + +void EraGlonassUveos_SetTimings(tEraGlonassUveos *env); + +void EraGlonassUveos_setNewNumber(tEraGlonassUveos *env, uint16_t target, char *number, uint8_t lenghtNum); + +bool EraGlonassUveos_ProcessEgtsPacket(tEraGlonassUveos *env, uint8_t *data, uint16_t dataSize); + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_TestEmergencyCall( + tEraGlonassUveos *env, tMSD_DiagnosticResult *diagnosticResult, + bool blocReg +); + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergencyEvent(tEraGlonassUveos *env, tUveosEmergencyEvent *event); + +void EraGlonassUveos_TestingStarted(tEraGlonassUveos *env); + +void EraGlonassUveos_GarageStarted(tEraGlonassUveos *env); + +void EraGlonassUveos_DoNothingModeDistance(tEraGlonassUveos *env, bool sourseNaData) ; + +void EraGlonassUveos_DoNotingReset(tEraGlonassUveos *env); + +void EraGlonassUveos_DoNotingSetStartPos(tEraGlonassUveos *env); + +uint16_t EraGlonassUveos_GetNoSendMSDCount(tEraGlonassUveos *env); + +static void EraGlonassUveos_EgtsMsdReq(tEraGlonassUveos *env); + +static void EraGlonassUveos_UpdateMsd(tEraGlonassUveos *env, eEcallTimeSourse timeSourse); + +void setMsdToPull(tEraGlonassUveos *env, const bool *mndSendFlag, bool *wasNewSetMsd, bool *wasResent, tMsdEncoded *msdEncoded); + +void reSetMsdToPull(tEraGlonassUveos *env, const bool *wasNewSetMsd, const bool *wasResent, tMsdEncoded *msdEncoded); + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_H diff --git a/Inc/EraGlonassUveos_Dumper.h b/Inc/EraGlonassUveos_Dumper.h new file mode 100644 index 0000000..ab3b209 --- /dev/null +++ b/Inc/EraGlonassUveos_Dumper.h @@ -0,0 +1,17 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_DUMPER_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_DUMPER_H + +typedef void (*eraGlonassForceDumpCall)(void *env); + +typedef struct { + void *env; + eraGlonassForceDumpCall forceDump; +} tEraGlonassUveosDumperInterface; + +#define EraGlonassUveosDumper_ForceDump(ENV) (ENV)->forceDump((ENV)->env) + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_DUMPER_H diff --git a/Inc/EraGlonassUveos_EcallProvider.h b/Inc/EraGlonassUveos_EcallProvider.h new file mode 100644 index 0000000..9daa670 --- /dev/null +++ b/Inc/EraGlonassUveos_EcallProvider.h @@ -0,0 +1,67 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_ECALLPROVIDER_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_ECALLPROVIDER_H + +#include "stdint.h" +#include "stdbool.h" + +typedef bool (*sendEcallCall)( + void *env, + + uint8_t *msd, + size_t msdLength, + + char *phoneNumber, + size_t phoneNumberLength, + + eEcallActivationType activationType, + eEcallTestMode testMode, + bool blocReg +); + +typedef bool (*setNewMsd)( + void *env, + uint8_t *msd, + size_t msdLength +); + +typedef bool (*eraGlonassEcallProviderCall)(void *env); + +typedef struct { + void *env; + void *smsEnv; + setNewMsd settingNewMsd; + sendEcallCall ecall; + eraGlonassEcallProviderCall isDialing; + eraGlonassEcallProviderCall isMsdSent; + eraGlonassEcallProviderCall isMsdReSent; + eraGlonassEcallProviderCall isActive; + eraGlonassEcallProviderCall hangup; + + void (*checkSms)(void *env); + bool (*isNetworkReg) (void *env, uint32_t state, bool mode); + bool (*isNetworkState) (void *env, uint16_t time); + + void *ShutdownEnv; + void (*CheckShutdown)(void *env); + +} tEraGlonassEcallProvider; + +#define EraGlonassEcallProvider_SettingNewMsd(ENV, MSD, MSD_LEN) (ENV)->settingNewMsd((ENV)->env,MSD, MSD_LEN) +#define EraGlonassEcallProvider_Ecall(ENV, MSD, MSD_LEN, PHONE, PHONE_LEN, ACTIVATION, MODE, BLOCREG) (ENV)->ecall((ENV)->env,MSD, MSD_LEN, PHONE, PHONE_LEN, ACTIVATION, MODE, BLOCREG) +#define EraGlonassEcallProvider_IsDialing(ENV) (ENV)->isDialing((ENV)->env) +#define EraGlonassEcallProvider_IsMsdSent(ENV) (ENV)->isMsdSent((ENV)->env) +#define EraGlonassEcallProvider_IsMsdReSent(ENV) (ENV)->isMsdReSent((ENV)->env) +#define EraGlonassEcallProvider_IsActive(ENV) (ENV)->isActive((ENV)->env) +#define EraGlonassEcallProvider_Hangup(ENV) (ENV)->hangup((ENV)->env) +#define EraGlonassEcallProvider_CheckSms(ENV) (ENV)->checkSms((ENV)->smsEnv) +#define EraGlonassEcallProvider_CheckNetState(ENV, TIME) (ENV)->isNetworkState((ENV)->env,TIME) +#define EraGlonassEcallProvider_CheckShutdownIsBattary(ENV) (ENV)->CheckShutdown((ENV)->ShutdownEnv) + +#define EraGlonassEcallProvider_NetRegistration(ENV, MODE) (ENV)->isNetworkReg((ENV)->env,0,MODE) + + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_ECALLPROVIDER_H diff --git a/Inc/EraGlonassUveos_Indicatior.h b/Inc/EraGlonassUveos_Indicatior.h new file mode 100644 index 0000000..ce27d03 --- /dev/null +++ b/Inc/EraGlonassUveos_Indicatior.h @@ -0,0 +1,28 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_INDICATIOR_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_INDICATIOR_H + +typedef enum { + UVEOS_STATUS_MANUAL_BEGIN, + UVEOS_STATUS_AUTOMATIC_BEGIN, + UVEOS_STATUS_TESTING_BEGIN, + UVEOS_STATUS_CALL_INITIATE, + UVEOS_STATUS_DIALING, + UVEOS_STATUS_MSD_TRANSMIT, + UVEOS_STATUS_SMS_TRANSMIT, + UVEOS_STATUS_CALL_ACTIVE, + UVEOS_STATUS_CALL_FAILURE, +} tEraGlonassUveosStatus; + +typedef struct { + void *env; + + void (*show)(void *env, tEraGlonassUveosStatus status); +} tEraGlonassUveosIndicator; + +#define EraGlonassUveosIndicator_Show(ENV, STATE) (ENV)->show((ENV)->env,STATE) + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_INDICATIOR_H diff --git a/Inc/EraGlonassUveos_NavDataProvider.h b/Inc/EraGlonassUveos_NavDataProvider.h new file mode 100644 index 0000000..c783f03 --- /dev/null +++ b/Inc/EraGlonassUveos_NavDataProvider.h @@ -0,0 +1,30 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_NAVDATAPROVIDER_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_NAVDATAPROVIDER_H + +#include "stdint.h" + +typedef struct { + int32_t latitude; + int32_t longitude; + + uint16_t direction; + uint8_t valid; +} EraGlonassUveosNavData; + +typedef struct { + void *env; + + void (*getNavData)(void *env, EraGlonassUveosNavData *navData, bool locSourse); + + void (*getTime)(void *env, uint32_t *time); +} tNavDataProvider; + +#define NavDataProvider_GetNavData(PROVIDER, NAV, LOCSOUESE) (PROVIDER)->getNavData((PROVIDER)->env, NAV, LOCSOUESE) +#define NavDataProvider_GetTime(PROVIDER, TIME) (PROVIDER)->getTime((PROVIDER)->env, TIME) + + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_NAVDATAPROVIDER_H diff --git a/Inc/EraGlonassUveos_Private.h b/Inc/EraGlonassUveos_Private.h new file mode 100644 index 0000000..22259c8 --- /dev/null +++ b/Inc/EraGlonassUveos_Private.h @@ -0,0 +1,46 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_PRIVATE_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_PRIVATE_H + +#include +#include +#include +#include "EraGlonassUveos.h" +#include "egts.h" + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergency( + tEraGlonassUveos *env, + eEcallActivationType activationType, + eEcallTestMode testMode, + bool blocReg +); + +bool EraGlonassUveos_EgtsResponse(tEraGlonassUveos *env, uint16_t recNum, uint16_t crn, uint16_t cid); + +bool EraGlonassUveos_EgtsSmsConfirmation( + tEraGlonassUveos *env, + uint8_t cmdType, + uint8_t cmdConfirmationType, + uint32_t cmdId, + uint32_t srcId, + uint16_t address, + uint8_t size, + uint8_t act, + uint16_t reqType +); + +bool EraGlonassUveos_ResentMsdTry(tEraGlonassUveos *env, tEraGlonassMsdTableItem *msdItem); + +void EraGlonassUveos_Indicate(tEraGlonassUveos *env, tEraGlonassUveosStatus status); + +void EraGlonassUveos_UpdateCurrentSettingsMsd(tEraGlonassUveos *env, eEcallTimeSourse timeSourse); + +void EraGlonassUveos_GenCurrentMsd(tEraGlonassUveos *env, eEcallActivationType activationType, + eEcallTestMode testMode, eEcallTimeSourse timeSourse); + +static bool EraGlonassUveos_EmergencySendMsdSmsTry(tEraGlonassUveos *env, tMsdEncoded *msdEncoded); + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_PRIVATE_H diff --git a/Inc/EraGlonassUveos_SmsProvider.h b/Inc/EraGlonassUveos_SmsProvider.h new file mode 100644 index 0000000..de0404c --- /dev/null +++ b/Inc/EraGlonassUveos_SmsProvider.h @@ -0,0 +1,20 @@ +// +// Created by xemon on 30.11.22. +// + +#ifndef UVEOS_ON_NATION_ERAGLONASSUVEOS_SMSPROVIDER_H +#define UVEOS_ON_NATION_ERAGLONASSUVEOS_SMSPROVIDER_H + +#include "stdbool.h" +#include "stdint.h" + +typedef struct { + void *env; + + bool (*sendDataPdu)(void *env, char *phone, uint8_t phoneSize, uint8_t *data, uint16_t dataSize); +} tEraGlonassSmsProvider; + + +#define EraGlonassSmsProvider_SendDataPdu(ENV, PHONE, DATA, DATA_LEN) (ENV)->sendDataPdu((ENV)->env,(PHONE).data,(PHONE).length,DATA,DATA_LEN) + +#endif //UVEOS_ON_NATION_ERAGLONASSUVEOS_SMSPROVIDER_H diff --git a/Src/EraGlonassUveos.c b/Src/EraGlonassUveos.c new file mode 100644 index 0000000..a2468ff --- /dev/null +++ b/Src/EraGlonassUveos.c @@ -0,0 +1,314 @@ +// +// Created by xemon on 21.10.22. +// + + +#include "EraGlonassUveos_Private.h" + + +#define LOGGER env->logger +#define LOG_SIGN "УВЭОС" + +void EraGlonassUveos_Init( + tEraGlonassUveos *env, + tLoggerInterface *logger, + + tEraGlonassMsdTable *msdTable, + tUveosGostSettings *settings, + tEraGlonassUveosDumperInterface *dumper, + + tNavDataProvider *navDataProvider, + tEraGlonassEcallProvider *ecallProvider, + tEraGlonassSmsProvider *smsProvider, + + tEraGlonassUveosIndicator *indicator, + tUserButtonsInterface *buttons, + uint16_t addButtonId, + tAudioPlayerInterface *audioPlayer, + tRtcIO *Rtc, + uint32_t stopLimitTime +) { + env->timings.rtcIo = Rtc; + env->buttons = buttons; + env->buttonsIds.additional = addButtonId; + env->dumper = dumper; + env->ecallProvider = ecallProvider; + env->logger = logger; + env->settings = settings; + env->navDataProvider = navDataProvider; + env->msdTable = msdTable; + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + env->doNothing.stopLimitTime = stopLimitTime; + env->smsProvider = smsProvider; + env->indicator = indicator; + + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + EraGlonassMsdInit(&env->currentMsd->msd); + + env->timings.lastInMemTransmit = 0; + env->timings.lastTestCall = 0; + env->timings.allowInCall = 0; + env->timings.lastNetworkRequest = 0; + env->timings.requireNetwork = 0; + env->timings.powerOfDelay = 0; + + env->audioPlayer = audioPlayer; + EraGlonassUveos_InvalidateSettings(env); +} + +void EraGlonassUveos_InvalidateSettings(tEraGlonassUveos *env) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем параметры из настроек...") + EraGlonassMsdSetPassengersNumber(&env->currentMsd->msd, env->settings->VEHICLE_PASSENGERS_NUMBER); + EraGlonassMsdSetVehicleType(&env->currentMsd->msd, env->settings->VEHICLE_TYPE); + EraGlonassMsdSetVIN(&env->currentMsd->msd, env->settings->VIN.data, env->settings->VIN.length); + + EraGlonassMsdSetPropulsionStorageType(&env->currentMsd->msd, env->settings->VEHICLE_PROPULSION_STORAGE_TYPE); +} + +bool EraGlonassUveos_RequiredInMemTransmit(tEraGlonassUveos *env) { + tEraGlonassMsdTableItem *first = EraGlonassMsdTable_GetNoSendData(env->msdTable, NULL); + if (first) { + return true; + } + return false; +} + +bool EraGlonassUveos_IsAllowInCall(tEraGlonassUveos *env) { + if (env->timings.allowInCall > SystemGetMs()) { + return true; + } else { + return false; + } +} + +static const uint32_t NETWORK_REQ_DELAY = 3000; + +//запрос необходимости передачи мнд из памяти +//для предварительного срабатывания заранее за вермя T до реального срабатывания необходиммо задать +//праметр timeOffset = T, в таком случае функция вернет true на T милисикунд раньше +bool EraGlonassUveos_InMemTransmitNow(tEraGlonassUveos *env, uint32_t timeOffset) { + if (EraGlonassUveos_RequiredInMemTransmit(env)) { + if (env->timings.lastInMemTransmit) { + uint32_t nextTransmit = env->timings.lastInMemTransmit + + (env->settings->INT_MEM_TRANSMIT_INTERVAL * 60 * 1000); + if (nextTransmit < timeOffset) { + return true; + } else { + return ((nextTransmit - timeOffset) < SystemGetMs()); + } + } else { + return true; + } + } + return false; +} + +// если установелнно время до которого мы должны находиться в сети +// и это время меньше текущего говорим что сеть нужна +bool EraGlonassUveos_IsStandby(tEraGlonassUveos *env) { + if((env->timings.requireNetwork > 0 ) && (env->timings.requireNetwork > SystemGetMs()) ){ + return true; + } + return false; +} + +bool EraGlonassUveos_IsPowerOffDelay(tEraGlonassUveos *env) { + if(env->timings.powerOfDelay > SystemGetMs() ){ + return true; + } + return false; +} + +bool EraGlonassUveos_IsRequireNetwork(tEraGlonassUveos *env) { + if (EraGlonassUveos_InMemTransmitNow(env, NETWORK_REQ_DELAY)) { + return true; + } + return EraGlonassUveos_IsStandby(env); +} + + + +bool EraGlonassUveos_IsVinCorrect(tEraGlonassUveos *env) { + //todo похорошему нужно проверять vin на валидность, а так просто смотрим есть ли он вообще + return env->settings->VIN.length; +} + +bool EraGlonassUveos_IsEraAllowed(tEraGlonassUveos *env) { + return EraGlonassUveos_IsVinCorrect(env); +} + +void EraGlonassUveos_ProcessingInMemTransmit(tEraGlonassUveos *env) { + + if (EraGlonassUveos_InMemTransmitNow(env, 0)) { + tEraGlonassMsdTableItem *item = NULL; + + //Достаем из таблицы неотправленное МНД + while ((item = EraGlonassMsdTable_GetNextUnsent(env->msdTable, item)) != NULL) { + //остались ли у нас попытки переотправки и валидный ли id в таблице + if (item->attemptsLeft > 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружено не обработанное экстренное событие") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Производится переотправка МНД") + if (EraGlonassUveos_ResentMsdTry(env, item)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД успешно переотправлен") + EraGlonassMsdTable_Init(env->msdTable); + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось переотправить МНД, продолжаются попытки") + } + } + } + env->timings.lastInMemTransmit += (env->settings->INT_MEM_TRANSMIT_INTERVAL * 60 * 1000); + } +} + +void EraGlonassUveos_ProcessingCheckNoSendMSD(tEraGlonassUveos *env) { + tEraGlonassMsdTableItem *item = NULL; + volatile bool sendThisMSDFlag = false; + volatile uint8_t tempAttemptsLeft = 0; + volatile uint8_t noSendMsdCount = EraGlonassMsdTable_GetNoSendDataCount(env->msdTable); + item = EraGlonassMsdTable_GetNoSendData(env->msdTable, NULL); + + volatile uint8_t isChekCount = 0; + volatile uint8_t isSendCount = 0; + + for(; isChekCount < noSendMsdCount; isChekCount++){ + + if(item!= NULL) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружено не обработанное экстренное событие") + tempAttemptsLeft = item->attemptsLeft; + EraGlonassMsdSetDataEmergencySituationFlags(&item->msd, item->msd.MSD_Data.msgId, AUTOMATIC_ACTIVATION, + EMERGENCY_CALL); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Производится переотправка МНД") + if (EraGlonassUveos_ResentMsdTry(env, item)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД успешно переотправлен") + sendThisMSDFlag = true; + } else { + item->attemptsLeft--; + sendThisMSDFlag = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось переотправить МНД, продолжаются попытки") + } + + if (!sendThisMSDFlag) { + item->attemptsLeft = tempAttemptsLeft; + } + EraGlonassUveosDumper_ForceDump(env->dumper); + } + item = EraGlonassMsdTable_GetNoSendData(env->msdTable, NULL); + + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка данных по не отправленным экстренным событиям выполнена") + + if (isSendCount == noSendMsdCount){ + EraGlonassMsdTable_Init(env->msdTable); + EraGlonassUveosDumper_ForceDump(env->dumper); + } +} + +void EraGlonassUveos_ProcessingEra(tEraGlonassUveos *env) { + EraGlonassUveos_ProcessingInMemTransmit(env); +} + +void EraGlonassUveos_SetTimings(tEraGlonassUveos *env) { + env->timings.allowInCall = SystemGetMs() + (env->settings->CALL_AUTO_ANSWER_TIME * 60 * 1000); + env->timings.requireNetwork = SystemGetMs() + (env->settings->NAD_DEREGISTRATION_TIME * 60 * 1000); + env->timings.powerOfDelay = SystemGetMs() + (env->settings->notGost.FULL_POWER_OFF_TIME * 60 * 1000); + env->timings.lastInMemTransmit = SystemGetMs() + (env->settings->INT_MEM_TRANSMIT_INTERVAL * 60 * 1000); +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergencyEvent(tEraGlonassUveos *env, tUveosEmergencyEvent *event) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_AUTOMATIC_BEGIN); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Экстренное событие, автоматический вызов") + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Заполняем дополнительную информацию в МНД о обстаятельствах события") + tEraGlonassMsd_DataTypedef *msd = &env->currentMsd->msd.MSD_Data; + msd->additionalDataPresent = true; + msd->additionalData.diagnosticResult = NULL; + env->currentMsd->msd.MSD_Data.msgId = 1; + + if (event->isImpact) { + msd->additionalData.asi15Present = true; + //todo проверить значение типа данных asi15 в мнд + msd->additionalData.asi15 = (uint16_t) (event->impactValue * 1000); + } + + if (event->isFlip) { + msd->additionalData.crashInfoPresent = true; + EraGlonassMsd_CrashInfoClear(&msd->additionalData.crashInfo); + EraGlonassMsd_OptionalFlagSet(msd->additionalData.crashInfo.CrashWithRollover, true); + } + + eEraGlonassUveos_EcallProcessingResult res; + res = EraGlonassUveos_ProcessingEmergency(env, AUTOMATIC_ACTIVATION, env->settings->notGost.ECALL_TEST_MODE, false); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем время пребывания в сети и ожидания входящего вызова") + uint32_t t = SystemGetMs() + 250; + while (t > SystemGetMs()){} + EraGlonassUveos_Indicate(env, UVEOS_STATUS_DIALING); + t = SystemGetMs() + 10; + while (t > SystemGetMs()){} + EraGlonassUveos_SetTimings(env); + + return res; +} + +void EraGlonassUveos_ManualEmergencyCall(tEraGlonassUveos *env, bool fl_blocRegNet) { + + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MANUAL_BEGIN); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Экстренный вызов инициирован вручную") + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Убираем дополнительную информацию в МНД") + tEraGlonassMsd_DataTypedef *msd = &env->currentMsd->msd.MSD_Data; + + msd->additionalDataPresent = false; + msd->additionalData.diagnosticResult = NULL; + + EraGlonassUveos_ProcessingEmergency(env, MANUAL_ACTIVATION, env->settings->notGost.ECALL_TEST_MODE, fl_blocRegNet); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем время пребывания в сети и ожидания входящего вызова") + uint32_t t = SystemGetMs() + 250; + while (t > SystemGetMs()){} + EraGlonassUveos_Indicate(env, UVEOS_STATUS_DIALING); + t = SystemGetMs() + 10; + while (t > SystemGetMs()){} + EraGlonassUveos_SetTimings(env); +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_TestEmergencyCall( + tEraGlonassUveos *env, tMSD_DiagnosticResult *diagnosticResult, + bool blocReg +) { + + if (env->timings.lastTestCall && + ((env->timings.lastTestCall + (env->settings->TEST_REGISTRATION_PERIOD * 60 * 1000)) > SystemGetMs())) { + return ERA_GLONASS_UVEOS_TEST_CALL_NOT_ALLOWED; + } + +// EraGlonassUveos_Indicate(env, UVEOS_STATUS_TESTING_BEGIN); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Тестовый экстренный вызов инициирован") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Заполняем дополнительную информацию в МНД резульатами тестирования") + + tEraGlonassMsd_DataTypedef *msd = &env->currentMsd->msd.MSD_Data; +// msd->additionalDataPresent = true; + msd->additionalData.asi15Present = false; + msd->additionalData.crashInfoPresent = false; +// env->currentMsd->msd.MSD_Data.additionalData.diagnosticResult = diagnosticResult; + env->currentMsd->msd.MSD_Data.msgId = 1; + + eEraGlonassUveos_EcallProcessingResult result = EraGlonassUveos_ProcessingEmergency( + env, MANUAL_ACTIVATION, TEST_CALL, blocReg + ); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем время пребывания в сети") + env->timings.requireNetwork = SystemGetMs() + (env->settings->POST_TEST_REGISTRATION_TIME * 1000); + env->timings.lastTestCall = SystemGetMs(); + + return result; +} + +void EraGlonassUveos_Indicate(tEraGlonassUveos *env, tEraGlonassUveosStatus status) { + if (env->indicator) { + EraGlonassUveosIndicator_Show(env->indicator, status); + } +} \ No newline at end of file diff --git a/Src/EraGlonassUveos_DoNothingModes.c b/Src/EraGlonassUveos_DoNothingModes.c new file mode 100644 index 0000000..fb4f834 --- /dev/null +++ b/Src/EraGlonassUveos_DoNothingModes.c @@ -0,0 +1,127 @@ +#include +#include +#include "EraGlonassUveos.h" +#include "AsciiStringAssmeblingUtils.h" +#include "SystemDelayInterface.h" + +#define LOGGER env->logger +#define LOG_SIGN "УВЭОС,DO_NOT_DISTAN" + +uint64_t tim= 0; + +void EraGlonassUveos_TestingStarted(tEraGlonassUveos *env) { + env->doNothing.mode = UVEOS_DO_NOTHING_TESTING; + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.beginPosition, false); + +} + +void EraGlonassUveos_GarageStarted(tEraGlonassUveos *env) { + env->doNothing.mode = UVEOS_DO_NOTHING_GARAGE; + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.beginPosition, true); +} + +void EraGlonassUveos_DoNotingReset(tEraGlonassUveos *env) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.beginPosition, true); +} + +void EraGlonassUveos_DoNotingSetStartPos(tEraGlonassUveos *env) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.movePosition, false); +} + +uint32_t getAbsOfPosition(EraGlonassUveosNavData *now, tEraGlonassUveos *env, bool flagSet){ + if(flagSet == true) { + return abs(now->latitude - env->doNothing.beginPosition.latitude); + } else { + return abs(now->longitude - env->doNothing.beginPosition.longitude); + } +} + +void EraGlonassUveos_DoNothingModeDistance(tEraGlonassUveos *env, bool sourseNaData) { + uint32_t latDistance; + uint32_t lonDistance; + size_t str_len = 0; + char step[5]; + + if (env->doNothing.stopLimitTime < SystemGetMs()) { + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.movePosition, sourseNaData); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Установлена новая точка отсчёта движения ТС"); + env->doNothing.stopLimitTime = SystemGetMs() + (40 * 1000); + } + + EraGlonassUveosNavData movDinst; + NavDataProvider_GetNavData(env->navDataProvider, &movDinst, sourseNaData); + if ( + (env->doNothing.mode != UVEOS_DO_NOTHING_GARAGE) && + (env->doNothing.mode != UVEOS_DO_NOTHING_TESTING) && + (env->doNothing.movePosition.valid > 1) + ) { + + latDistance = abs(movDinst.latitude - env->doNothing.movePosition.latitude); + lonDistance = abs(movDinst.longitude - env->doNothing.movePosition.longitude); + + double x = latDistance * 0.1; + double y = lonDistance * 0.1; + double move = sqrt(x * x + y * y); + env->doNothing.movDist = (uint32_t) move; + + if ( env->doNothing.movDist > 25) { + env->doNothing.mode = UVEOS_DO_NOTHING_MOVE_TO; + } else { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + } + } + +///=================== + + EraGlonassUveosNavData now; + NavDataProvider_GetNavData(env->navDataProvider, &now, sourseNaData); + if(now.valid > 0) { + + latDistance = abs(now.latitude - env->doNothing.beginPosition.latitude); + lonDistance = abs(now.longitude - env->doNothing.beginPosition.longitude); + + double x = latDistance * 0.1; + double y = lonDistance * 0.1; + double move = sqrt( (x * x) + (y * y) ); + uint32_t res = (uint32_t) move; + + if((env->doNothing.mode == UVEOS_DO_NOTHING_GARAGE) && (tim < SystemGetMs())) { + vAsciiStringInit(step, &str_len, 5); + vAsciiStringAddDecimalInt64(step, &str_len, res, 5); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Текущее отклонение (режим ГАРАЖ) = "); + LoggerInfo(LOGGER, LOG_SIGN, step, str_len); + + if (env->settings->GARAGE_MODE_END_DISTANCE < res) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + } + tim = SystemGetMs() + 10000; + } + + if(env->doNothing.mode == UVEOS_DO_NOTHING_TESTING) { + vAsciiStringInit(step, &str_len, 5); + vAsciiStringAddDecimalInt64(step, &str_len, res, 5); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Текущее отклонение (режим тестирования) = "); + LoggerInfo(LOGGER, LOG_SIGN, step, str_len); + if (env->settings->TEST_MODE_END_DISTANCE < res) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + } + } + + if ( + (env->settings->GARAGE_MODE_END_DISTANCE < res) && + (env->doNothing.mode = UVEOS_DO_NOTHING_GARAGE) + ) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + } + if ( + (env->settings->TEST_MODE_END_DISTANCE < res) && + (env->doNothing.mode = UVEOS_DO_NOTHING_TESTING) + ) { + env->doNothing.mode = UVEOS_DO_NOTHING_DISABLED; + } + + env->offsetToDistance = res; + } +} diff --git a/Src/EraGlonassUveos_Egts.c b/Src/EraGlonassUveos_Egts.c new file mode 100644 index 0000000..add5e74 --- /dev/null +++ b/Src/EraGlonassUveos_Egts.c @@ -0,0 +1,198 @@ +// +// Created by xemon on 09.01.23. +// + +#include "EraGlonassUveos_Private.h" +#include + +#define LOGGER env->logger +#define LOG_SIGN "УВЭОС,ЕГТС" + +static void EraGlonassUveos_EgtsMsdReq(tEraGlonassUveos *env) { + uint32_t noSendMsdCount = EraGlonassMsdTable_GetCount(env->msdTable); + tEraGlonassMsdTableItem *item = NULL; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Поиск МНД доступных для переотправки") + if(noSendMsdCount > 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Доступный МНД присутствует, поиск крайних...") + for (uint32_t id = 0; id < EraGlonassMsdTable_GetSize(); ++id) { + if (env->msdTable->items[id].msd.MSD_Data.timestamp > item->msd.MSD_Data.timestamp) { + item = &env->msdTable->items[id]; + } + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Крайний МНД найден") + } + + if ( item != NULL) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Переотправка МНД") + + env->currentMsd = item; + env->currentMsd->msd.MSD_Data.msgId++; + EraGlonassUveos_UpdateCurrentSettingsMsd(env, NOT_CHANGE_TIME); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Установка флагов МНД...") + EraGlonassMsdSetDataEmergencySituationFlags(&env->currentMsd->msd, env->currentMsd->msd.MSD_Data.msgId, MANUAL_ACTIVATION, + EMERGENCY_CALL); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Переотправка МНД...") + EraGlonassUveos_ResentMsdTry(env, env->currentMsd); + + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Генерация нового МНД...") + EraGlonassUveos_GenCurrentMsd(env, MANUAL_ACTIVATION, EMERGENCY_CALL, RTC_TIME_SOURSE); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Установка флагов МНД...") + EraGlonassMsdSetDataEmergencySituationFlags(&env->currentMsd->msd, env->currentMsd->msd.MSD_Data.msgId, AUTOMATIC_ACTIVATION, + EMERGENCY_CALL); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получение сгенерированного МНД...") + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправка МНД...") + EraGlonassUveos_ResentMsdTry(env, env->currentMsd); + } + + EraGlonassUveosDumper_ForceDump(env->dumper); + SystemDelayMs(500); +} + +void EraGlonassUveos_setNewNumber(tEraGlonassUveos *env, uint16_t target, char *number, uint8_t lenghtNum) { + SystemDelayMs(500); + switch (target) { + case EGTS_ECALL_TEST_NUMBER: + env->settings->ECALL_TEST_NUMBER.length = lenghtNum; + memcpy(&env->settings->ECALL_TEST_NUMBER.data, number, lenghtNum); + EraGlonassUveosDumper_ForceDump(env->dumper); + SystemDelayMs(1000); + break; + + case EGTS_ECALL_SMS_FALLBACK_NUMBER: + env->settings->ECALL_SMS_FALLBACK_NUMBER.length = lenghtNum; + memcpy(&env->settings->ECALL_SMS_FALLBACK_NUMBER.data, number, lenghtNum); + EraGlonassUveosDumper_ForceDump(env->dumper); + SystemDelayMs(1000); + break; + + default: + break; + } +} + +bool EraGlonassUveos_ProcessEgtsPacket(tEraGlonassUveos *env, uint8_t *binaryData, uint16_t dataSize) { + char egtsHexStr[dataSize * 2]; + size_t egtsHexStrLen = 0; + vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, binaryData, dataSize); + LoggerInfoStatic(LOGGER, LOG_SIGN, "EGTS PACK") + LoggerInfo(LOGGER, LOG_SIGN, egtsHexStr, egtsHexStrLen); + + EgtsWorkerEnvironment egtsWorkerEnv; + + memset(&egtsWorkerEnv.subRecMemAlloc, 0, sizeof(EgtsSubRecMemAlloc)); + egtsWorkerEnv.workingBufferLength = dataSize; + egtsWorkerEnv.workingBuffer = binaryData; + + if (EgtsIsTransportComplete(&egtsWorkerEnv)) { + EgtsParseHeader(&egtsWorkerEnv); + EgtsParseFrameData(&egtsWorkerEnv); + EgtsParseSrvRecord(&egtsWorkerEnv); + + if (egtsWorkerEnv.srCommand) { + switch (egtsWorkerEnv.srCommand->cmd) { + case EGTS_ECALL_MSD_REQ: + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получен запрос на повторную отправку МНД по средствам SMS сообщения") + EraGlonassUveos_EgtsMsdReq(env); + return true; + + case EGTS_ECALL_REQ: + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправка подтверждения на запрос эксренного вызова") + EraGlonassUveos_EgtsSmsConfirmation(env, + egtsWorkerEnv.srCommand->cmdType, + egtsWorkerEnv.srCommand->cmdConfirmationType, + egtsWorkerEnv.srCommand->cmdId, + egtsWorkerEnv.srCommand->srcId, + egtsWorkerEnv.srCommand->address, + egtsWorkerEnv.srCommand->size, + egtsWorkerEnv.srCommand->act, + EGTS_TEST_MODE + ); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Запрос эксренного вызова") + env->currentMsd->msd.MSD_Data.msgId++; + if (egtsWorkerEnv.srCommand->data.ecallReq.reqType == EGTS_ECALL_REQ_MANUAL) { + EraGlonassUveos_ManualEmergencyCall(env, false); + } else { + tUveosEmergencyEvent event = {.isImpact = true, .impactValue=0.0f}; + EraGlonassUveos_ProcessingEmergencyEvent(env, &event); + } + return true; + + case EGTS_ECALL_TEST_NUMBER: + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Получена команда на установку номера для тестового вызова " + "(EGTS_ECALL_TEST_NUMBER)") + EraGlonassUveos_EgtsSmsConfirmation(env, + egtsWorkerEnv.srCommand->cmdType, + egtsWorkerEnv.srCommand->cmdConfirmationType, + egtsWorkerEnv.srCommand->cmdId, + egtsWorkerEnv.srCommand->srcId, + egtsWorkerEnv.srCommand->address, + egtsWorkerEnv.srCommand->size, + egtsWorkerEnv.srCommand->act, + EGTS_TEST_MODE + ); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправлено подтверждения на запрос установки номера для" + " тестового вызова") + SystemDelayMs(2000); + EraGlonassUveos_setNewNumber( + env, + EGTS_ECALL_TEST_NUMBER, + egtsWorkerEnv.srCommand->data.newFallbackNumber.data, + egtsWorkerEnv.srCommand->data.newFallbackNumber.length + ); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Установлен новый номер для тестового вызова") + LoggerInfo( + LOGGER, + LOG_SIGN, + egtsWorkerEnv.srCommand->data.newFallbackNumber.data, + egtsWorkerEnv.srCommand->data.newFallbackNumber.length + ) + + return true; + + case EGTS_ECALL_SMS_FALLBACK_NUMBER: + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Получена команда на на установку номера для SMS (EGTS_ECALL_SMS_FALLBACK_NUMBER)") + EraGlonassUveos_EgtsSmsConfirmation(env, + egtsWorkerEnv.srCommand->cmdType, + egtsWorkerEnv.srCommand->cmdConfirmationType, + egtsWorkerEnv.srCommand->cmdId, + egtsWorkerEnv.srCommand->srcId, + egtsWorkerEnv.srCommand->address, + egtsWorkerEnv.srCommand->size, + egtsWorkerEnv.srCommand->act, + EGTS_TEST_MODE + + ); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправлено подтверждение на запрос установки номера для SMS") + SystemDelayMs(2000); + EraGlonassUveos_setNewNumber( + env, + EGTS_ECALL_SMS_FALLBACK_NUMBER, + egtsWorkerEnv.srCommand->data.newFallbackNumber.data, + egtsWorkerEnv.srCommand->data.newFallbackNumber.length + ); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Установлен новый номер для SMS") + LoggerInfo( + LOGGER, + LOG_SIGN, + egtsWorkerEnv.srCommand->data.newFallbackNumber.data, + egtsWorkerEnv.srCommand->data.newFallbackNumber.length + ) + + return true; + } + } + } + return false; +} \ No newline at end of file diff --git a/Src/EraGlonassUveos_EmergencyMode.c b/Src/EraGlonassUveos_EmergencyMode.c new file mode 100644 index 0000000..d1c1912 --- /dev/null +++ b/Src/EraGlonassUveos_EmergencyMode.c @@ -0,0 +1,686 @@ +// +// Created by xemon on 30.11.22. +// + +#include "EraGlonassUveos_Private.h" +//#include "UserInput.h" +#include "AsciiStringParsingUtils.h" +#include "egtsWorker.h" +#include "Rtc.h" + +#define LOGGER env->logger +#define LOG_SIGN "УВЭОС,ЭВ" +#define DEVTST_PLAY_SAMPLE(SAMPLE) AudioPlayer_PlayStatic(env->audioPlayer, SAMPLE, 5000); + +eEraGlonassUveos_EcallProcessingResult smsTransmitFl = ERA_GLONASS_UVEOS_SEND_FAIL; + +static void EraGlonassUveos_UpdateMsd(tEraGlonassUveos *env, eEcallTimeSourse timeSourse) { + EraGlonassUveosNavData nav; + uint32_t time; + + if (timeSourse == GNSS_TIME_SOURSE) { + NavDataProvider_GetTime(env->navDataProvider, &time); + } + if (timeSourse == RTC_TIME_SOURSE) { + RtcGet(env->timings.rtcIo, (time_t *) &time); + } + if (timeSourse == NOT_CHANGE_TIME) { + time = env->currentMsd->msd.MSD_Data.timestamp; + } + + NavDataProvider_GetNavData(env->navDataProvider, &nav, true); + EraGlonassMsdSetTimeStamp(&env->currentMsd->msd, time); + + if (nav.valid != 0) { + EraGlonassMsdSetPositionValue(&env->currentMsd->msd, nav.longitude, nav.latitude, nav.direction, nav.valid); + } else { + EraGlonassMsdNoGnssSetDefaults(&env->currentMsd->msd); + } + +} + +static void EraGlonassUveos_SignMsd(tEraGlonassUveos *env, eEcallActivationType type, bool test) { + EraGlonassMsdSetDataEmergencySituationFlags( + &env->currentMsd->msd, + env->currentMsd->msd.MSD_Data.msgId, + type, + test ? TEST_CALL : EMERGENCY_CALL + ); +} + +void EraGlonassUveos_CompileMsd(tEraGlonassUveos *env, tEraGlonassMsd *msd, tMsdEncoded *msdEncoded) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Собираем бинарный пакет МНД") + + msdEncoded->len = EraGlonassMsdEncode(msd, MSD_V_2, msdEncoded->data); + + char asciiMsd[msdEncoded->len * 2]; + size_t asciiMsdLen = 0; + vAsciiStringAddBytesAsHex(asciiMsd, &asciiMsdLen, msdEncoded->data, msdEncoded->len); + + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Бинарный пакет МНД сформирован: ") + LoggerInfo(LOGGER, LOG_SIGN, asciiMsd, asciiMsdLen) +} + + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingSms( + tEraGlonassUveos *env, + tMsdEncoded *msdEncoded +) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправка смс...") + if (EraGlonassUveos_EmergencySendMsdSmsTry(env, msdEncoded)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправленно по средствам СМС") + env->currentMsd->attemptsLeft = 0; + SystemDelayMs(100); + EraGlonassUveosDumper_ForceDump(env->dumper); + EraGlonassUveos_Indicate(env, UVEOS_STATUS_SMS_TRANSMIT); + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + return ERA_GLONASS_UVEOS_SMS_SENT; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Неудалось отпаравить МНД по средствам СМС") + return ERA_GLONASS_UVEOS_SEND_FAIL; + } +} + +void reSetMsdToPull(tEraGlonassUveos *env, const bool *wasNewSetMsd, const bool *wasResent, tMsdEncoded *msdEncoded) { + if ( + (*wasNewSetMsd == true) && + (*wasResent == false) && + (env->currentMsd->msd.MSD_Data.msgId > 1) + ) { + env->currentMsd->msd.MSD_Data.msgId--; + + EraGlonassUveos_UpdateMsd(env, RTC_TIME_SOURSE); + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + EraGlonassEcallProvider_SettingNewMsd(env->ecallProvider, msdEncoded->data, msdEncoded->len); + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Переотправка МНД по PULL запросу от оператора НЕ была выполнена, не получен URC об отправке") + } +} + +void setMsdToPull(tEraGlonassUveos *env, const bool *mndSendFlag, bool *wasNewSetMsd, bool *wasResent, + tMsdEncoded *msdEncoded) { + if ( + (*mndSendFlag == true) && + (*wasNewSetMsd == false) + ) { + + env->currentMsd->msd.MSD_Data.msgId++; + + EraGlonassUveos_UpdateMsd(env, RTC_TIME_SOURSE); + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + EraGlonassEcallProvider_SettingNewMsd(env->ecallProvider, msdEncoded->data, msdEncoded->len); + *wasNewSetMsd = true; + } else if (EraGlonassEcallProvider_IsMsdReSent(env->ecallProvider)) { + *wasNewSetMsd = false; + *wasResent = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Была выполнена переотправка МНД по PULL запросу от оператора, будет установлен новый МНД") + } +} + +static eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_EmergencyCallTry( + tEraGlonassUveos *env, + tMsdEncoded *msdEncoded, + eEcallActivationType activationType, + eEcallTestMode testMode, + uint32_t dialTimeoutEnd, + bool *mndSendFlag, + bool blocReg +) { + + eEraGlonassUveos_EcallProcessingResult callResult = ERA_GLONASS_UVEOS_CALL_FAIL; + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Пробуем совершить экстренный вызов") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_INITIATE); + } + + SystemDelayMs(500); + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + SystemDelayMs(500); + + if (!EraGlonassEcallProvider_Ecall( + env->ecallProvider, + msdEncoded->data, + msdEncoded->len, + env->settings->ECALL_TEST_NUMBER.data, + env->settings->ECALL_TEST_NUMBER.length, + activationType, + testMode, + blocReg + )) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Неудалось инициировать экстренный вызов") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + env->currentMsd->attemptsLeft--; + return ERA_GLONASS_UVEOS_CALL_FAIL; + } + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Экстренный вызов успешно инициирован") + tUserInputButtonEvent buttonEvent; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Дозвон") + + while (EraGlonassEcallProvider_IsDialing(env->ecallProvider)) { + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + if (env->settings->ECALL_MANUAL_CAN_CANCEL) { + while (UserButtons_GetNext(env->buttons, &buttonEvent, 0)) { + if (UserInputButtonEventIsBetween(buttonEvent, env->buttonsIds.additional, RAISE, 500, 4000)) { + EraGlonassEcallProvider_Hangup(env->ecallProvider); + LoggerInfoStatic(LOGGER, LOG_SIGN, ".") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Звонок прерван пользователем") + return ERA_GLONASS_UVEOS_CALL_USER_BREAK; + } + } + } + SystemDelayMs(500); + if (SystemGetMs() > dialTimeoutEnd) { + EraGlonassEcallProvider_Hangup(env->ecallProvider); + LoggerInfoStatic(LOGGER, LOG_SIGN, ".") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Звонок прерван, превышена общая продолжительность дозвона") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + return ERA_GLONASS_UVEOS_CALL_FAIL; + } + } + LoggerInfoStatic(LOGGER, LOG_SIGN, ".") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + } + uint32_t msdSendTimeout = SystemGetMs() + (env->settings->MSD_MAX_TRANSMISSION_TIME * 1000); + + if (EraGlonassEcallProvider_IsActive(env->ecallProvider)) { + DEVTST_PLAY_SAMPLE("audio_on") + } + + while (!EraGlonassEcallProvider_IsMsdSent(env->ecallProvider) && + EraGlonassEcallProvider_IsActive(env->ecallProvider) && + (msdSendTimeout > SystemGetMs())) { + + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + SystemDelayMs(500); + } + LoggerInfoStatic(LOGGER, LOG_SIGN, ".") + + if (EraGlonassEcallProvider_IsMsdSent(env->ecallProvider)) { + env->currentMsd->attemptsLeft = 0; + *mndSendFlag = true; + callResult = ERA_GLONASS_UVEOS_CALL_SUCCESS; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Отправка МНД...") + DEVTST_PLAY_SAMPLE("msd_on") + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД передан по средствам тонального модема") + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + if (!EraGlonassEcallProvider_IsActive(env->ecallProvider)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Вызов звершен принимающей стороной") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Превышено время передачи МНД тональным модемом") + callResult = ERA_GLONASS_UVEOS_SEND_FAIL; + } + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + } + + if(blocReg == false) { + if ((callResult == ERA_GLONASS_UVEOS_CALL_FAIL) && (*mndSendFlag == false)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД (цикл вызовов) ошибка установки соединения") + LoggerErrorStatic(LOGGER, LOG_SIGN, "Производиться проверка сети") + if (EraGlonassEcallProvider_CheckNetState(env->ecallProvider, 10000) == true) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть присутствует, попытка отправки МНД по средствам СМС") + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + if (EraGlonassUveos_ProcessingSms(env, msdEncoded) == ERA_GLONASS_UVEOS_SMS_SENT) { + *mndSendFlag = true; + callResult = ERA_GLONASS_UVEOS_CALL_SUCCESS; + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлен по средствам СМС") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось выполнить отправку СМС") + *mndSendFlag = false; + callResult = ERA_GLONASS_UVEOS_CALL_FAIL; + } + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть отсутствует_3") + } + } + + if ((callResult == ERA_GLONASS_UVEOS_SEND_FAIL) && (*mndSendFlag == false)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, + "Не удалось отправить МНД (цикл вызовов) ошибка передачи МНД по средствам тональной связи") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть присутствует, попытка отправки МНД по средсвам СМС") + + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + if (EraGlonassUveos_ProcessingSms(env, msdEncoded) == ERA_GLONASS_UVEOS_SMS_SENT) { + *mndSendFlag = true; + callResult = ERA_GLONASS_UVEOS_CALL_SUCCESS; + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлен по средствам СМС") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось выполнить отправку СМС") + *mndSendFlag = false; + callResult = ERA_GLONASS_UVEOS_SEND_FAIL; + } + } + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети запрещена текущей конфигурацией вызова") + } + + bool wasNewSetMsd = false; + bool wasResent = false; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Звонок") + uint64_t times = SystemGetMs(); + + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_ACTIVE); + } + + while (EraGlonassEcallProvider_IsActive(env->ecallProvider)) { + EraGlonassEcallProvider_CheckSms(env->ecallProvider); + EraGlonassEcallProvider_CheckShutdownIsBattary(env->ecallProvider); + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + if (times < SystemGetMs() && (wasNewSetMsd == true)) { +// setMsdToPull(env, mndSendFlag, &wasNewSetMsd, &wasResent, msdEncoded); + SystemDelayMs(1000); + times = SystemGetMs() + 5000; +// LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Установлен новый пакет МНД для PUL запроса") + } + } + + EraGlonassEcallProvider_CheckShutdownIsBattary(env->ecallProvider); +// reSetMsdToPull(env, &wasNewSetMsd, &wasResent, msdEncoded); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Звонок завершен") + EraGlonassUveosDumper_ForceDump(env->dumper); + return callResult; +} + +static void EraGlonassUveos_ClearEgtsBuffers(tEraGlonassUveos *env, tEgtsEncoded *egtsEncoded) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Очистка памяти под ЕГТС пакет...") + memset(egtsEncoded, '\0', sizeof(tEgtsEncoded)); // Clear +} + +static void EraGlonassUveos_PrepareEgtsData(tEraGlonassUveos *env, tMsdEncoded *msdEncoded, tEgtsEncoded *egtsEncoded) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируем ЕГТС пакет... ") + uint32_t timeNow; + NavDataProvider_GetTime(env->navDataProvider, &timeNow); + egtsEncoded->len = vEgtsPackMsdTransport( + 0x01, + egtsEncoded->data, + msdEncoded->data, + msdEncoded->len, + timeNow + ); + + char egtsHexStr[egtsEncoded->len * 2]; + size_t egtsHexStrLen = 0; + vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, egtsEncoded->data, egtsEncoded->len); + + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Бинарный пакет ЕГТС сформирован: ") + LoggerInfo(LOGGER, LOG_SIGN, egtsHexStr, egtsHexStrLen) +} + +static void +EraGlonassUveos_PrepareEgtsResponse(tEraGlonassUveos *env, uint16_t recNum, uint16_t crn, uint16_t cid, + tEgtsEncoded *egtsEncoded) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируем подтверждающий ЕГТС пакет... ") + uint32_t timeNow; + NavDataProvider_GetTime(env->navDataProvider, &timeNow); + + egtsEncoded->len = vEgtsPackEgtsResponse( + 0b0001, + egtsEncoded->data, + 0b0000, + recNum, + cid, + timeNow + ); + + char egtsHexStr[egtsEncoded->len * 2]; + size_t egtsHexStrLen = 0; + vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, egtsEncoded->data, egtsEncoded->len); + + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Бинарный подтверждающий пакет ЕГТС сформирован: ") + LoggerInfo(LOGGER, LOG_SIGN, egtsHexStr, egtsHexStrLen) +} + +static void EraGlonassUveos_PrepareEgtsCmdConfirmation( + tEraGlonassUveos *env, + uint16_t cmdType, + uint16_t cmdConfirType, + uint16_t cid, + uint16_t sid, + uint16_t acfe, + uint16_t chsfe, + uint16_t adr, + uint8_t sz, + uint8_t act, + uint16_t ccd, + uint32_t dt, + tEgtsEncoded *egtsEncoded +) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируем подтверждающий ЕГТС пакет... ") + uint32_t timeNow; + NavDataProvider_GetTime(env->navDataProvider, &timeNow); + + egtsEncoded->len = vEgtsPackSrCmdConfirmation( + egtsEncoded->data, + 0, + cmdType, + cmdConfirType, + cid, + sid, + acfe, + chsfe, + adr, + sz, + act, + ccd, + dt + ); + + + char egtsHexStr[egtsEncoded->len * 2]; + size_t egtsHexStrLen = 0; + vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, egtsEncoded->data, egtsEncoded->len); + + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Подтверждающий пакет ЕГТС сформирован: ") + LoggerInfo(LOGGER, LOG_SIGN, egtsHexStr, egtsHexStrLen) +} + +static bool EraGlonassUveos_SendEgtsSms(tEraGlonassUveos *env, tEgtsEncoded *egtsEncoded) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_SMS_TRANSMIT); + return EraGlonassSmsProvider_SendDataPdu( + env->smsProvider, + env->settings->ECALL_SMS_FALLBACK_NUMBER, + egtsEncoded->data, + egtsEncoded->len + ); +} + +static bool EraGlonassUveos_SendEgtsResponse(tEraGlonassUveos *env, uint16_t recNum, uint16_t crn, uint16_t cid) { + tEgtsEncoded egtsEncoded; + EraGlonassUveos_ClearEgtsBuffers(env, &egtsEncoded); + EraGlonassUveos_PrepareEgtsResponse(env, recNum, crn, cid, &egtsEncoded); + return EraGlonassUveos_SendEgtsSms(env, &egtsEncoded); +} + +static bool EraGlonassUveos_SendEgtsSmsConfirmation( + tEraGlonassUveos *env, + uint16_t cmdType, + uint16_t cmdConfirType, + uint16_t cid, + uint16_t sid, + uint16_t acfe, + uint16_t chsfe, + uint16_t adr, + uint8_t sz, + uint8_t act, + uint16_t ccd, + uint32_t dt +) { + tEgtsEncoded egtsEncoded; + EraGlonassUveos_ClearEgtsBuffers(env, &egtsEncoded); + EraGlonassUveos_PrepareEgtsCmdConfirmation(env, cmdType, cmdConfirType, cid, sid, acfe, chsfe, adr, sz, act, ccd, + dt, &egtsEncoded); + + return EraGlonassUveos_SendEgtsSms(env, &egtsEncoded); +} + +static bool EraGlonassUveos_EmergencySendMsdSmsTry(tEraGlonassUveos *env, tMsdEncoded *msdEncoded) { + tEgtsEncoded egtsEncoded; + EraGlonassUveos_ClearEgtsBuffers(env, &egtsEncoded); + EraGlonassUveos_PrepareEgtsData(env, msdEncoded, &egtsEncoded); + return EraGlonassUveos_SendEgtsSms(env, &egtsEncoded); +} + +bool EraGlonassUveos_EgtsSmsConfirmation( + tEraGlonassUveos *env, + uint8_t cmdType, + uint8_t cmdConfirmationType, + uint32_t cmdId, + uint32_t srcId, + uint16_t address, + uint8_t size, + uint8_t act, + uint16_t reqType +) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сборка ответа") + + if (EraGlonassUveos_SendEgtsSmsConfirmation( + env, + CT_COMCONF, + CC_OK, + cmdId, + srcId, + 0, + 0, + address, + size, + act, + reqType, + 0) + ) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ответ отправлен по средствам СМС") + return true; + + } else { + if (EraGlonassUveos_SendEgtsSmsConfirmation( + env, + CT_COMCONF, + CC_OK, + cmdId, + srcId, + 0, + 0, + address, + size, + act, + reqType, + 0) + ) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ответ отправлен по средствам СМС") + return true; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Неудалось отпаравить ответ по средствам СМС") + return false; + } + } +} + + +bool EraGlonassUveos_EgtsResponse(tEraGlonassUveos *env, uint16_t recNum, uint16_t crn, uint16_t cid) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сборка ответа response") + + if (EraGlonassUveos_SendEgtsResponse(env, recNum, crn, cid)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ответ отправлен по средствам СМС") + EraGlonassUveosDumper_ForceDump(env->dumper); + return true; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Неудалось отпаравить response по средствам СМС") + return false; + } +} + +bool EraGlonassUveos_ResentMsdTry(tEraGlonassUveos *env, tEraGlonassMsdTableItem *msdItem) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Переотправка МНД...") + tMsdEncoded msdEncoded; + + EraGlonassUveos_CompileMsd(env, &msdItem->msd, &msdEncoded); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправка смс...") + + if (EraGlonassUveos_EmergencySendMsdSmsTry(env, &msdEncoded)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправленно по средствам СМС") + msdItem->attemptsLeft = 0; + EraGlonassUveosDumper_ForceDump(env->dumper); + return true; + } else { + msdItem->attemptsLeft--; + LoggerErrorStatic(LOGGER, LOG_SIGN, "Неудалось отпаравить МНД по средствам СМС") + EraGlonassUveosDumper_ForceDump(env->dumper); + return false; + } +} + +void EraGlonassUveos_UpdateCurrentSettingsMsd(tEraGlonassUveos *env, eEcallTimeSourse timeSourse) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнавляем настройки...") + EraGlonassUveos_InvalidateSettings(env); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем МНД...") + EraGlonassUveos_UpdateMsd(env, timeSourse); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сохраняем изменения в ПЗУ") + EraGlonassUveosDumper_ForceDump(env->dumper); +} + +void EraGlonassUveos_GenCurrentMsd(tEraGlonassUveos *env, eEcallActivationType activationType, eEcallTestMode testMode, + eEcallTimeSourse timeSourse) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнавляем настройки...") + EraGlonassUveos_InvalidateSettings(env); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем МНД...") + EraGlonassUveos_UpdateMsd(env, timeSourse); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выделяем МНД ID в таблице") + EraGlonassUveos_SignMsd(env, activationType, testMode); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сохраняем изменения в ПЗУ") + EraGlonassUveosDumper_ForceDump(env->dumper); +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergency( + tEraGlonassUveos *env, + eEcallActivationType activationType, + eEcallTestMode testMode, + bool blocReg +) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка экстренной ситуации...") + + env->currentMsd->msd.MSD_Data.msgId = 1; + tMsdEncoded msdEncoded; + + EraGlonassUveos_GenCurrentMsd(env, activationType, testMode, RTC_TIME_SOURSE); + + uint16_t attemptsLeft = activationType == AUTOMATIC_ACTIVATION ? + env->settings->ECALL_AUTO_DIAL_ATTEMPTS : + env->settings->ECALL_MANUAL_DIAL_ATTEMPTS; + + uint32_t dialTimeout = SystemGetMs() + (env->settings->ECALL_DIAL_DURATION * 60 * 1000); + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_INITIATE); + } + eEraGlonassUveos_EcallProcessingResult resultSendEmergy = ERA_GLONASS_UVEOS_CALL_FAIL; + + bool pr_mndSendFlag = false; + + while (((SystemGetMs() < dialTimeout)) && (attemptsLeft)) { + + if ((pr_mndSendFlag) && (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_SUCCESS)) { + --attemptsLeft; + break; + } + --attemptsLeft; + + DEVTST_PLAY_SAMPLE("do_sos") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_DIALING); + } + + resultSendEmergy = EraGlonassUveos_EmergencyCallTry( + env, + &msdEncoded, + activationType, + testMode, + dialTimeout, + &pr_mndSendFlag, + blocReg + ); + + if (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_USER_BREAK) { + return resultSendEmergy; + } + + env->currentMsd->attemptsLeft--; + } + + if((blocReg == true) && (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_SUCCESS)){ + EraGlonassUveosDumper_ForceDump(env->dumper); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка экстренной ситуации завершена код 1") + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + return ERA_GLONASS_UVEOS_CALL_SUCCESS; + } + + if((blocReg == true) && (resultSendEmergy != ERA_GLONASS_UVEOS_CALL_SUCCESS)){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка вызова код 4") + if(resultSendEmergy == ERA_GLONASS_UVEOS_CALL_FAIL){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "ERA_GLONASS_UVEOS_CALL_FAIL") + } + if(resultSendEmergy == ERA_GLONASS_UVEOS_SMS_SENT){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "ERA_GLONASS_UVEOS_SMS_SENT") + } + if(resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "ERA_GLONASS_UVEOS_SEND_FAIL") + } + if(resultSendEmergy == ERA_GLONASS_UVEOS_TEST_CALL_NOT_ALLOWED){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "ERA_GLONASS_UVEOS_TEST_CALL_NOT_ALLOWED") + } + } + + if (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_SUCCESS) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Произведен успешный экстренный вызов") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Данные о вызове очищены из внутренней памяти") + + } else if ((resultSendEmergy == ERA_GLONASS_UVEOS_CALL_FAIL) || (resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, + "Не удалось совершить отправку МНД, производиться проверка сети и попытка отправки МНД по средсвам СМС") + if (EraGlonassEcallProvider_CheckNetState(env->ecallProvider, 5000) == true) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть присутствует") + DEVTST_PLAY_SAMPLE("msd_on") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, &msdEncoded); + resultSendEmergy = EraGlonassUveos_ProcessingSms(env, &msdEncoded); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть отсутствует") + } + + } + + if ((pr_mndSendFlag) || ((int) resultSendEmergy == ERA_GLONASS_UVEOS_SMS_SENT)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлено по средствам СМС") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_SMS_TRANSMIT); + SystemDelayMs(1000); + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + } + } + + if ((!pr_mndSendFlag) || ((int) resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД по средствам СМС") + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + } + + if ((resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL) || (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_FAIL)) { + env->currentMsd->attemptsLeft = env->settings->INT_MEM_TRANSMIT_ATTEMPTS; + } else { + env->currentMsd->attemptsLeft = 0; + } + + EraGlonassUveosDumper_ForceDump(env->dumper); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка экстренной ситуации завершена") + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + + return resultSendEmergy; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..215c8fa --- /dev/null +++ b/modular.json @@ -0,0 +1,47 @@ +{ + "dep": [ + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "UserButtonsInterface" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "UveosGostSettings" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "EraGlonassMsd" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "EraGlonassMsdTable" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "UveosEmergencyEventInterface" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "Legacy_EgtsEncoderDecoder" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "AudioPlayerInterface" + } + ], + "cmake": { + "inc_dirs": [ + "Inc/" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file