EraGlonassUveos/Src/EraGlonassUveos_Egts.c

477 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by xemon on 09.01.23.
//
#include "EraGlonassUveos_Private.h"
#include "egtsWorker.h"
//#include <egtsWorker.h>
#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;
}