From 1faef27395c57b020bdee0ee12af1bdee7b9bd63 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 2 Jun 2025 13:26:41 +0300 Subject: [PATCH] Init --- Inc/EraGlonassUveos.h | 183 +++++++++ Inc/EraGlonassUveos_Dumper.h | 17 + Inc/EraGlonassUveos_EcallProvider.h | 72 ++++ Inc/EraGlonassUveos_Indicatior.h | 31 ++ Inc/EraGlonassUveos_NavDataProvider.h | 30 ++ Inc/EraGlonassUveos_Private.h | 59 +++ Inc/EraGlonassUveos_SmsProvider.h | 20 + Src/EraGlonassUveos.c | 350 ++++++++++++++++ Src/EraGlonassUveos_DoNothingModes.c | 129 ++++++ Src/EraGlonassUveos_Egts.c | 476 ++++++++++++++++++++++ Src/EraGlonassUveos_EmergencyMode.c | 562 ++++++++++++++++++++++++++ modular.json | 57 +++ 12 files changed, 1986 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..b0b3ec6 --- /dev/null +++ b/Inc/EraGlonassUveos.h @@ -0,0 +1,183 @@ +// +// 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" +#include "AudioRecorderInterface.h" + +//#define AURUS_CAR_UI 1 + +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 { + uint8_t len; + uint8_t data[1280]; +} tEgtsEncodedR; + +typedef void (*tSimSelecror_func)(void *env, uint8_t thisSimChip); + +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; + tAudioRecorderInterface *audioRecorderIO; + tAudioPlayerInterface *audioPlayerIO; + uint32_t offsetToDistance; + bool fl_ecallState; + tSimSelecror_func simSelecror_func; + void *selecrorEnv; + bool fl_telematicaCipReady; + bool fl_audioHids; +} 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_setTelematicaChipState(tEraGlonassUveos *env, bool eValidCCID); + +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_IsStandbyTestTimer(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); + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ManualEmergencyCall(tEraGlonassUveos *env); + +void EraGlonassUveos_setNewNumber(tEraGlonassUveos *env, uint16_t target, char *number, uint8_t lenghtNum); + +bool EraGlonassUveos_updateInternalSoftware(tEraGlonassUveos *env, tDeviceStorage *storage) ; + +bool EraGlonassUveos_ProcessEgtsPacket(tEraGlonassUveos *env, tDeviceStorage *storage, uint8_t *binaryData, uint16_t dataSize) ; + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_TestEmergencyCall( + tEraGlonassUveos *env, tMSD_DiagnosticResult *diagnosticResult +); + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergencyEvent(tEraGlonassUveos *env, tUveosEmergencyEvent *event); + +void EraGlonassUveos_DoNotingTestingStarted(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); + +void EraGlonassUveos_EgtsMsdReq(tEraGlonassUveos *env); + +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); + +void EraGlonassUveos_SetTimings(tEraGlonassUveos *env); + +#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..0c89ddf --- /dev/null +++ b/Inc/EraGlonassUveos_EcallProvider.h @@ -0,0 +1,72 @@ +// +// 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 +); + +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 isActiveOut; + eraGlonassEcallProviderCall isActiveInp; + eraGlonassEcallProviderCall hangup; + eraGlonassEcallProviderCall hangupEcl; + eraGlonassEcallProviderCall prepHenUp; + eraGlonassEcallProviderCall resetUrcNetReg; +// eraGlonassEcallProviderCall isNetReg; + void (*checkSms)(void *env); + void (*delSms)(void *env); + bool (*isNetworkReg) (void *env, uint32_t state, bool mode); + bool (*isNetworkState) (void *env, uint16_t time); + bool (*isNetReg) (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) (ENV)->ecall((ENV)->env,MSD, MSD_LEN, PHONE, PHONE_LEN, ACTIVATION, MODE) +#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_IsActiveOut(ENV) (ENV)->isActiveOut((ENV)->env) +#define EraGlonassEcallProvider_IsActiveInput(ENV) (ENV)->isActiveInp((ENV)->env) +#define EraGlonassEcallProvider_Hangup(ENV) (ENV)->hangup((ENV)->env) +#define EraGlonassEcallProvider_HangupEcl(ENV) (ENV)->hangupEcl((ENV)->env) +#define EraGlonassEcallProvider_PrepHangup(ENV) (ENV)->prepHenUp((ENV)->env) +#define EraGlonassEcallProvider_CheckSms(ENV) (ENV)->checkSms((ENV)->smsEnv) +#define EraGlonassEcallProvider_DelSms(ENV) (ENV)->delSms((ENV)->smsEnv) +#define EraGlonassEcallProvider_CheckNetState(ENV, TIME) (ENV)->isNetworkState((ENV)->env,TIME) +#define EraGlonassEcallProvider_NetRegistration(ENV, MODE) (ENV)->isNetworkReg((ENV)->env,0,MODE) +#define EraGlonassEcallProvider_IsNetReg(ENV) (ENV)->isNetReg((ENV)->env) +#define EraGlonassEcallProvider_ResetUrcNetReg(ENV) (ENV)->isNetReg((ENV)->env) + +#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..c6373aa --- /dev/null +++ b/Inc/EraGlonassUveos_Indicatior.h @@ -0,0 +1,31 @@ +// +// 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, + UVEOS_STATUS_WAIT_NETWORK, + UVEOS_STATUS_SYSTEM_STARTUP, + UVEOS_STATUS_UNDEFINDET +} 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..7a6f225 --- /dev/null +++ b/Inc/EraGlonassUveos_Private.h @@ -0,0 +1,59 @@ +// +// 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 debugMode +); + +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_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); +bool EraGlonassUveos_EmergencySendMsdSmsTry(tEraGlonassUveos *env, tMsdEncoded *msdEncoded); +static bool EraGlonassUveos_SendEgtsSms(tEraGlonassUveos *env, tEgtsEncoded *egtsEncoded); +#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..41927f6 --- /dev/null +++ b/Src/EraGlonassUveos.c @@ -0,0 +1,350 @@ +// +// 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 *audioPlayerIO, + 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->audioPlayerIO = audioPlayerIO; + EraGlonassUveos_InvalidateSettings(env); + env->fl_ecallState = false; + env->fl_audioHids = true; +} +void EraGlonassUveos_setTelematicaChipState(tEraGlonassUveos *env, bool eValidCCID){ + env->fl_telematicaCipReady = eValidCCID; +} + +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 < SystemGetMs()) { + { + env->timings.lastInMemTransmit = env->timings.lastInMemTransmit + + (env->settings->INT_MEM_TRANSMIT_INTERVAL * 60 * 1000); + return true; + } + } + } + return false; +} + +// если установелнно время до которого мы должны находиться в сети +// и это время меньше текущего говорим что сеть нужна +bool EraGlonassUveos_IsStandby(tEraGlonassUveos *env) { + if((env->timings.requireNetwork > 0 ) && (env->timings.requireNetwork > SystemGetMs()) ){ + return true; + } + return false; +} + +bool EraGlonassUveos_IsStandbyTestTimer(tEraGlonassUveos *env) { + if ( + env->timings.lastTestCall && + ((env->timings.lastTestCall + (env->settings->TEST_REGISTRATION_PERIOD * 60 * 1000)) > SystemGetMs()) + ) { + return true; + } else { + 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; + } + + bool statIsNetwork = EraGlonassUveos_IsStandby(env); // timings.requireNetwork + bool statStandFulPower = EraGlonassUveos_IsAllowInCall(env); // timings.allowInCall + bool statTestTimer = EraGlonassUveos_IsStandbyTestTimer(env); + if ((statIsNetwork && statTestTimer) && (statStandFulPower) ) { + return true; + } + + return false; +} + + + +bool EraGlonassUveos_IsVinCorrect(tEraGlonassUveos *env) { + //todo похорошему нужно проверять vin на валидность, а так просто смотрим есть ли он вообще + if (memcmp(&env->settings->VIN.data, "00000000000000000", sizeof("00000000000000000") - 1) == 0) + return 0; + + 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, "Обнаружено не обработанное экстренное событие код 2") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Производится переотправка МНД") + if (EraGlonassUveos_ResentMsdTry(env, item)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД успешно переотправлен") + item->attemptsLeft = 0; + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + item->attemptsLeft --; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось переотправить МНД, продолжаются попытки") + } + } + } + + volatile uint16_t noSendMsdCount = EraGlonassMsdTable_GetNoSendDataCount(env->msdTable); + if (noSendMsdCount == 0){ + EraGlonassMsdTable_Init(env->msdTable); + EraGlonassUveosDumper_ForceDump(env->dumper); + 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); + uint8_t isChekCount = 0; + + for(; isChekCount < noSendMsdCount; isChekCount++){ + if(item != NULL) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружено не обработанное экстренное событие код 1") + tempAttemptsLeft = item->attemptsLeft; + EraGlonassMsdSetDataEmergencySituationFlags(&item->msd, item->msd.MSD_Data.msgId, AUTOMATIC_ACTIVATION, + EMERGENCY_CALL); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Производится переотправка МНД") + if (EraGlonassUveos_ResentMsdTry(env, item)) { + item->attemptsLeft = 0; + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлено по средствам СМС, количество попыток отправки текущего пакета установлено = 0") + sendThisMSDFlag = true; + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + item->attemptsLeft --; + sendThisMSDFlag = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД по средствам СМС, количество попыток отправки снижено на 1") + EraGlonassUveosDumper_ForceDump(env->dumper); + } + + if (!sendThisMSDFlag) { + item->attemptsLeft = tempAttemptsLeft; + } + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получение следующего не обработанного МНД...") + item = EraGlonassMsdTable_GetNoSendData(env->msdTable, NULL); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не обработанный МНД получен") + } + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Проверка итогов пересылки не обработанных МНД") + volatile uint8_t noSendCn = EraGlonassMsdTable_GetNoSendDataCount(env->msdTable); + if (noSendCn == 0){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не отправленные экстренные события обработаны полностью, данные из ПЗУ очищены") + EraGlonassMsdTable_Init(env->msdTable); + EraGlonassUveosDumper_ForceDump(env->dumper); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Остались не обработанные МНД в хранилище") + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка данных по не отправленным экстренным событиям выполнена") +} + +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); + if(env->settings->notGost.ECALL_TEST_MODE){ + env->timings.requireNetwork = SystemGetMs() + (env->settings->POST_TEST_REGISTRATION_TIME * 1000); + } else { + env->timings.requireNetwork = SystemGetMs() + (env->settings->NAD_DEREGISTRATION_TIME * 60 * 1000); + } +// env->timings.requireNetwork = SystemGetMs() + (env->settings->CALL_AUTO_ANSWER_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, env->settings->notGost.ECALL_DEBUG_MODE); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновляем время пребывания в сети и ожидания входящего вызова") + + return res; +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ManualEmergencyCall(tEraGlonassUveos *env) { + EraGlonassUveos_SetTimings(env); + eEraGlonassUveos_EcallProcessingResult res; + env->fl_ecallState = true; +// 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; + + res = EraGlonassUveos_ProcessingEmergency(env, MANUAL_ACTIVATION, env->settings->notGost.ECALL_TEST_MODE, env->settings->notGost.ECALL_DEBUG_MODE); + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление времени пребывания в сети и ожидания входящего вызова") + + EraGlonassUveos_SetTimings(env); + env->fl_ecallState = false; + return res; +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_TestEmergencyCall( + tEraGlonassUveos *env, tMSD_DiagnosticResult *diagnosticResult +) { + + if ( + env->timings.lastTestCall && + ((env->timings.lastTestCall + (env->settings->TEST_REGISTRATION_PERIOD * 60 * 1000)) > SystemGetMs()) + ) { + return ERA_GLONASS_UVEOS_TEST_CALL_NOT_ALLOWED; + } + 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, 0 + ); + + 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); + } +} diff --git a/Src/EraGlonassUveos_DoNothingModes.c b/Src/EraGlonassUveos_DoNothingModes.c new file mode 100644 index 0000000..484e323 --- /dev/null +++ b/Src/EraGlonassUveos_DoNothingModes.c @@ -0,0 +1,129 @@ +#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_DoNotingTestingStarted(tEraGlonassUveos *env) { + env->doNothing.mode = UVEOS_DO_NOTHING_TESTING; + NavDataProvider_GetNavData(env->navDataProvider, &env->doNothing.beginPosition, true); +} + +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, true); +} + +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 = 0; + uint32_t lonDistance = 0; + size_t str_len = 0; + char step[5] = {0}; + + 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) { + if(env->doNothing.beginPosition.valid<1){ + env->doNothing.beginPosition = now; + } + + 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..e4fd0e5 --- /dev/null +++ b/Src/EraGlonassUveos_Egts.c @@ -0,0 +1,476 @@ +// +// Created by xemon on 09.01.23. +// + + +#include "EraGlonassUveos_Private.h" +#include "egtsWorker.h" +//#include + +#define LOGGER env->logger +#define LOG_SIGN "УВЭОС,ЕГТС" + +void EraGlonassUveos_EgtsMsdReq(tEraGlonassUveos *env) { + volatile uint8_t noSendMsdCount = EraGlonassMsdTable_GetCount(env->msdTable); + tEraGlonassMsdTableItem *item = NULL; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Поиск МНД доступных для переотправки") + if(noSendMsdCount > 0) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Доступный МНД найдены, поиск крайних...") + item = EraGlonassMsdTable_GetLastMsd(env->msdTable, NULL); + } + + 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, "Переотправка МНД...") + if(EraGlonassUveos_ResentMsdTry(env, env->currentMsd)){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполнено успешно") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при переотправки") + } + + } 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, MANUAL_ACTIVATION, + EMERGENCY_CALL); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получение сгенерированного МНД...") + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отправка МНД...") + if(EraGlonassUveos_ResentMsdTry(env, env->currentMsd)){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполнено успешно") + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при переотправки") + } + } + + 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_updateInternalSoftware(tEraGlonassUveos *env, tDeviceStorage *storage) { + tVariableDescriptor *var; + + var = VariablesTable_GetByNameStatic(&storage->publicVariablesTable, "UPDATE_SERVER_CHECK_IN_ATTEMPTS"); + if (var!=NULL) { + *(uint32_t*)var->addr = 30; + } + + var = VariablesTable_GetByNameStatic(&storage->publicVariablesTable, "UPDATE_UVEOS_UPDATE"); + if (var!=NULL) { + *(uint8_t*)var->addr = 1; + EraGlonassUveosDumper_ForceDump(env->dumper); + return true; + } + return false; +} + +static void EraGlonassUveos_ClearEgtsBuffers(tEraGlonassUveos *env, tEgtsEncoded *egtsEncoded) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Очистка памяти под ЕГТС пакет...") + memset(egtsEncoded, '\0', sizeof(tEgtsEncoded)); // Clear +} + +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_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 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) +} + +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, "Ответ отправлен по средствам СМС 1") + return true; + + } else { + if (EraGlonassUveos_SendEgtsSmsConfirmation( + env, + CT_COMCONF, + CC_OK, + cmdId, + srcId, + 0, + 0, + address, + size, + act, + reqType, + 0) + ) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ответ отправлен по средствам СМС 2") + return true; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить ответ по средствам СМС") + return false; + } + } +} + +static void EraGlonassUveos_PrepareEgtsResponse(tEraGlonassUveos *env, uint16_t recNum, uint16_t crn, uint16_t cid, + tEgtsEncoded *egtsEncoded) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируем подтверждающий ЕГТС пакет... ") + uint64_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 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); +} + +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_ProcessEgtsPacket(tEraGlonassUveos *env, tDeviceStorage *storage, 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 false; + + 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); + } 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 false; + + 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, "Отправлено подтверждение код 1") + 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 false; + + case EGTS_UPDATE_SOFTWARE: + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Получена команда на на удаленное обновление встроенного ПО (EGTS_UPDATE_SOFTWARE)") + 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, "Отправлено подтверждение код 2") + SystemDelayMs(2000); + + if(env->fl_telematicaCipReady){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "СИМ 1 доступен") + env->simSelecror_func(env->selecrorEnv,1); + } else { + env->simSelecror_func(env->selecrorEnv,0); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Инициализация подсистемы, код 1") + } + + storage->runtime.EGTS_FLEET_ON = true; + SystemDelayMs(4000); + + bool resUpdateResult = EraGlonassUveos_updateInternalSoftware( + env, + storage + ); + + tVariableDescriptor *var; + if(resUpdateResult == true){ + uint32_t tmUpdateLimit = SystemGetMs() + 480000; // 8 минут + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Инициализация подсистемы, код 2") + if(storage->runtime.EGTS_FLEET_ON == true){ + storage->runtime.EGTS_FLEET_ON = false; + +// uint32_t tm = SystemGetMs()+5000; +// while ( (tm>SystemGetMs()) || (storage->runtime.telematicaCloseConnect == false) ) +// { +// SystemDelayMs(1); +// } + + ///* fix + for(uint8_t i = 0;i <50;i++){ + if(storage->runtime.telematicaCloseConnect == true){ + break; + } + SystemDelayMs(100); + + } + } + EraGlonassUveosDumper_ForceDump(env->dumper); + var = VariablesTable_GetByNameStatic(&storage->publicVariablesTable, "UPDATE_UVEOS_UPDATE"); + + while ( (*(uint8_t*)var->addr!=0) || ( tmUpdateLimit > SystemGetMs() ) ){ + SystemDelayMs(10); + } + } + + env->simSelecror_func(env->selecrorEnv,0); + return false; + } + } + } + return false; +} diff --git a/Src/EraGlonassUveos_EmergencyMode.c b/Src/EraGlonassUveos_EmergencyMode.c new file mode 100644 index 0000000..32c420f --- /dev/null +++ b/Src/EraGlonassUveos_EmergencyMode.c @@ -0,0 +1,562 @@ +// +// 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) \ + SystemDelayMs(150); \ + AudioPlayer_PlayStatic(env->audioPlayerIO, SAMPLE, 25*1000); + +#define DEVTST_PLAY_TONE(COUNT) \ + AudioPlayer_PlayStaticTone(env->audioPlayerIO,COUNT); + +eEraGlonassUveos_EcallProcessingResult smsTransmitFl = ERA_GLONASS_UVEOS_SEND_FAIL; + +void EraGlonassUveos_UpdateMsd(tEraGlonassUveos *env, eEcallTimeSourse timeSourse) { + EraGlonassUveosNavData nav; + time_t time; + + if (timeSourse == GNSS_TIME_SOURSE) { + NavDataProvider_GetTime(env->navDataProvider, (uint32_t*) &time); + } + if (timeSourse == RTC_TIME_SOURSE) { + RtcGet(env->timings.rtcIo, &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; + EraGlonassUveosDumper_ForceDump(env->dumper); + EraGlonassUveos_Indicate(env, UVEOS_STATUS_SMS_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 debugMode +) { + + eEraGlonassUveos_EcallProcessingResult callResult = ERA_GLONASS_UVEOS_CALL_FAIL; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Пробуем совершить экстренный вызов") + +// if(testMode != TEST_CALL) { +// EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_INITIATE); +// } + + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, msdEncoded); + + if (!EraGlonassEcallProvider_Ecall( + env->ecallProvider, + msdEncoded->data, + msdEncoded->len, + env->settings->ECALL_TEST_NUMBER.data, + env->settings->ECALL_TEST_NUMBER.length, + activationType, + testMode + )) { + 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 = {0}; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Дозвон") + while (EraGlonassEcallProvider_IsDialing(env->ecallProvider)) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_INITIATE); + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + if (env->settings->ECALL_MANUAL_CAN_CANCEL) { + while (UserButtons_GetNext(env->buttons, &buttonEvent, 0)) { + if (UserInputButtonEventIsBetween(buttonEvent, env->buttonsIds.emergensy, RAISE, 500, 4000)) { + EraGlonassEcallProvider_HangupEcl(env->ecallProvider); + LoggerInfoStatic(LOGGER, LOG_SIGN, ".") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Звонок прерван пользователем") + return ERA_GLONASS_UVEOS_CALL_USER_BREAK; + } + } + } + SystemDelayMs(500); + if (SystemGetMs() > dialTimeoutEnd) { + EraGlonassEcallProvider_HangupEcl(env->ecallProvider); + 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_IsActiveOut(env->ecallProvider)) { + #if (AURUS_CAR_UI == 0) + DEVTST_PLAY_SAMPLE("audio_on.mp3") + #endif + } + + bool fl = false; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Попытка отправки МНД...") + + +#if (AURUS_CAR_UI == 1) + DEVTST_PLAY_TONE(1) +#endif +#if (AURUS_CAR_UI == 0) + DEVTST_PLAY_SAMPLE("msd_send.mp3") +#endif + + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + while (!EraGlonassEcallProvider_IsMsdSent(env->ecallProvider) && + EraGlonassEcallProvider_IsActiveOut(env->ecallProvider) && + (msdSendTimeout > SystemGetMs())) { + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + SystemDelayMs(500); + if(fl == false){ + SystemDelayMs(4500); + fl = true; + } + } + if(!debugMode) { + if (EraGlonassEcallProvider_IsMsdSent(env->ecallProvider)) { + env->currentMsd->attemptsLeft = 0; + *mndSendFlag = true; + callResult = ERA_GLONASS_UVEOS_CALL_SUCCESS; + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД передан по средствам тонального модема") + } else { + if (!EraGlonassEcallProvider_IsActiveOut(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 ((callResult == ERA_GLONASS_UVEOS_CALL_FAIL) && (*mndSendFlag == false)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД (цикл вызовов) ошибка установки соединения") + LoggerErrorStatic(LOGGER, LOG_SIGN, + "Производиться проверка сети для передачи МНД по альтернативному каналу связи") + if (EraGlonassEcallProvider_CheckNetState(env->ecallProvider, 20000) == 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; + } + + EraGlonassEcallProvider_DelSms(env->ecallProvider); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть отсутствует") + } + } + + 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) { + EraGlonassEcallProvider_DelSms(env->ecallProvider); + *mndSendFlag = true; + callResult = ERA_GLONASS_UVEOS_CALL_SUCCESS; + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлен по средствам СМС") + } else { + EraGlonassEcallProvider_DelSms(env->ecallProvider); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Не удалось выполнить отправку СМС") + *mndSendFlag = false; + callResult = ERA_GLONASS_UVEOS_SEND_FAIL; + } + } + } + + bool wasNewSetMsd = false; + bool wasResent = false; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Звонок") + uint64_t times = SystemGetMs(); + + +if(EraGlonassEcallProvider_IsActiveOut(env->ecallProvider)){ + #if (AURUS_CAR_UI == 1) + DEVTST_PLAY_TONE(2) + if(testMode == TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_TESTING_BEGIN); + } else { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_ACTIVE); + } + #endif + #if (AURUS_CAR_UI == 0) + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_ACTIVE); + #endif +} + + + while (EraGlonassEcallProvider_IsActiveOut(env->ecallProvider)) { + EraGlonassEcallProvider_CheckSms(env->ecallProvider); + LoggerCnInfoStatic(LOGGER, LOG_SIGN, ".") + if (times < SystemGetMs() && (wasNewSetMsd == true)) { + setMsdToPull(env, mndSendFlag, &wasNewSetMsd, &wasResent, msdEncoded); + times = SystemGetMs() + 5000; + LoggerCnInfoStatic(LOGGER, LOG_SIGN, "Установлен новый пакет МНД для PUL запроса") + } + SystemDelayMs(500); + } + + reSetMsdToPull(env, &wasNewSetMsd, &wasResent, msdEncoded); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Звонок завершен") + return callResult; +} + + + + + + + + + + + +///===================================================================================================================== +///===================================================================================================================== +///===================================================================================================================== +///===================================================================================================================== +///===================================================================================================================== + + + +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)) { + EraGlonassEcallProvider_DelSms(env->ecallProvider); + LoggerInfoStatic(LOGGER, LOG_SIGN, "МНД отправлено по средствам СМС") + EraGlonassUveosDumper_ForceDump(env->dumper); + return true; + } else { + EraGlonassEcallProvider_DelSms(env->ecallProvider); + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД по средствам СМС PERIODICAL") + 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); +} + +void EraGlonassUveos_ClearSms(tEraGlonassUveos *env){ + uint32_t t = SystemGetMs() + 1252; + while (t > SystemGetMs()){ + EraGlonassEcallProvider_DelSms(env->ecallProvider); + SystemDelayMs(50); + } +} + +uint16_t getAttemptsLeft(tEraGlonassUveos *env, eEcallActivationType activationType){ + if(activationType == AUTOMATIC_ACTIVATION){ + return env->settings->ECALL_AUTO_DIAL_ATTEMPTS; + } else if(activationType == MANUAL_ACTIVATION){ + return env->settings->ECALL_MANUAL_DIAL_ATTEMPTS; + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "==== ВНИМАНИЕ, КОЛИЧЕСТВО ПОПЫТОК ВЫЗОВОВ НЕ СКОНВИГУРИРОВАНО, БУДЕТ ВЫПОЛНЕНА 1 ПОПЫТКА!!! ====") + return 1; + } +} + +eEraGlonassUveos_EcallProcessingResult EraGlonassUveos_ProcessingEmergency( + tEraGlonassUveos *env, + eEcallActivationType activationType, + eEcallTestMode testMode, + bool debugMode +) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обработка экстреной ситуации...") + env->currentMsd->msd.MSD_Data.msgId = 1; + tMsdEncoded msdEncoded; + + EraGlonassUveos_GenCurrentMsd(env, activationType, testMode, RTC_TIME_SOURSE); + uint16_t attemptsLeft = getAttemptsLeft(env, activationType); + env->currentMsd->attemptsLeft = env->settings->INT_MEM_TRANSMIT_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; + bool fl_audio = false; + + while (((SystemGetMs() < dialTimeout)) && (attemptsLeft > 0)) { + + if(fl_audio == true) { +#if (AURUS_CAR_UI == 1) + if(testMode != TEST_CALL) { + DEVTST_PLAY_SAMPLE("emerCool_aurus.mp3") + } +#endif +#if (AURUS_CAR_UI == 0) + DEVTST_PLAY_SAMPLE("ecall_on.mp3") +#endif + } + fl_audio = true; + +// if(testMode != TEST_CALL) { +// EraGlonassUveos_Indicate(env, UVEOS_STATUS_DIALING); +// } + +// EraGlonassUveos_Indicate(env, UVEOS_STATUS_WAIT_NETWORK); +// bool isReg = EraGlonassEcallProvider_NetRegistration(env->ecallProvider,1); +// if(isReg == false) +// { +// EraGlonassEcallProvider_NetRegistration(env->ecallProvider,1); +// SystemDelayMs(2000); +// } + + resultSendEmergy = EraGlonassUveos_EmergencyCallTry( + env, + &msdEncoded, + activationType, + testMode, + dialTimeout, + &pr_mndSendFlag, + debugMode + ); + EraGlonassEcallProvider_HangupEcl(env->ecallProvider); + if(debugMode) { + return resultSendEmergy; + } + + if (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_USER_BREAK) { + return resultSendEmergy; + } + + if ((pr_mndSendFlag) && (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_SUCCESS)) { + --attemptsLeft; + break; + } + --attemptsLeft; + EraGlonassEcallProvider_HangupEcl(env->ecallProvider); + EraGlonassUveosDumper_ForceDump(env->dumper); + env->currentMsd->msd.MSD_Data.msgId++; + if(env->currentMsd->msd.MSD_Data.msgId == (getAttemptsLeft(env, activationType)) +1 ) { + env->currentMsd->msd.MSD_Data.msgId = getAttemptsLeft(env, activationType); + } + dialTimeout = SystemGetMs() + (env->settings->ECALL_DIAL_DURATION * 60 * 1000); + } + if(debugMode) { + return resultSendEmergy; + } + if (resultSendEmergy == ERA_GLONASS_UVEOS_CALL_SUCCESS) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Произведен успешный экстренный вызов") + + EraGlonassUveos_ClearSms(env); + LoggerInfoStatic(LOGGER, LOG_SIGN, "СМС пакеты очищены из памяти коммуникационного модуля") + env->currentMsd->attemptsLeft = 0; + if(testMode != TEST_CALL) { + EraGlonassUveosDumper_ForceDump(env->dumper); + } + env->currentMsd = EraGlonassMsdTable_GetNextFree(env->msdTable); + return resultSendEmergy; + } else if ((resultSendEmergy == ERA_GLONASS_UVEOS_CALL_FAIL) || (resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, + "Не удалось совершить отправку МНД, производиться проверка сети и попытка отправки МНД по средствам СМС") +// bool isReg = EraGlonassEcallProvider_NetRegistration(env->ecallProvider,1); + if (EraGlonassEcallProvider_CheckNetState(env->ecallProvider, 5) == true) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть присутствует") + +#if (AURUS_CAR_UI == 1) + DEVTST_PLAY_TONE(1) +#endif +#if (AURUS_CAR_UI == 0) + DEVTST_PLAY_SAMPLE("msd_send.mp3") +#endif + + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + EraGlonassUveos_CompileMsd(env, &env->currentMsd->msd, &msdEncoded); + resultSendEmergy = EraGlonassUveos_ProcessingSms(env, &msdEncoded); + } else { + bool isReg = EraGlonassEcallProvider_NetRegistration(env->ecallProvider,1); + if(isReg){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть присутствует") + +#if (AURUS_CAR_UI == 1) + DEVTST_PLAY_TONE(1) +#endif +#if (AURUS_CAR_UI == 0) + DEVTST_PLAY_SAMPLE("msd_send.mp3") +#endif + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_CALL_FAILURE); + } + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + 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, "МНД отправлено по средствам СМС") + env->currentMsd->msd.MSD_Data.msgId ++; + if(testMode != TEST_CALL) { + EraGlonassUveos_Indicate(env, UVEOS_STATUS_MSD_TRANSMIT); + } + } + + if ((!pr_mndSendFlag) || ((int) resultSendEmergy == ERA_GLONASS_UVEOS_SEND_FAIL)) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Не удалось отправить МНД по средствам СМС ECALL") + 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; + } + + EraGlonassUveos_ClearSms(env); + if(testMode != TEST_CALL) { + EraGlonassUveosDumper_ForceDump(env->dumper); + } + + 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..52afc25 --- /dev/null +++ b/modular.json @@ -0,0 +1,57 @@ +{ + "dep": [ + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "UserButtonsInterface" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "UveosGostSettings" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "EraGlonassMsd" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "EraGlonassMsdTable" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "UveosEmergencyEventInterface" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "Legacy_EgtsEncoderDecoder_ForUveos" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "AudioPlayerInterface" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "LoggerInterface" + }, + { + "type": "git", + "provider": "Smart_Components_Aurus", + "repo": "Rtc" + } + ], + "cmake": { + "inc_dirs": [ + "Inc/" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file