314 lines
13 KiB
C
314 lines
13 KiB
C
//
|
||
// 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, 0);
|
||
|
||
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);
|
||
}
|
||
} |