351 lines
15 KiB
C
351 lines
15 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 *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);
|
||
}
|
||
}
|