// // 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; }