// // Created by xemon on 30.10.22. // #include #include #include "DeviceTesting.h" #include "UserInput.h" #include "DeviceTesting_TestsWithUser.h" #include "Adc.h" #include "EraGlonassMsd.h" #include "EraGlonassUveos.h" #include "Accel.h" #include "GsmWithGnss.h" #include "AsciiStringAssmeblingUtils.h" #define LOGGER env->logger #define LOG_SIGN "Тест." bool DeviceTesting_Init( tDeviceTesting *env, tUserInputButtonWatcher *UserInputButtonWatcher, tGpioPin *ignPin, tAdcIO *gnssAntAdc, tAdcIO *speakerAdc, tAdcIO *batteryAdc, tAccel *accel, tGsmWithGnss *gsmWithGnss, tAudioCodec *audioCodec, tLoggerInterface *logger, tAtCmd *gsm, tAudioPlayerInterface *audioPlayer, tAudioRecorderInterface *audioRecorder, tUserButtonsInterface *input, tUserIndication *indication, tEraGlonassUveos *ErGlUv, bool *antMode, tGpioPin *ring ) { env->UserInputButtonWatcher = UserInputButtonWatcher; env->logger = logger; env->audioPlayer = audioPlayer; env->audioRecorder = audioRecorder; env->input = input; env->indication = indication; env->ErGlUv = ErGlUv; env->accelDFI = &accel->accelDataFlow; env->pinIgnition = ignPin; env->ringPin = ring; env->antDiscript.externalAdc = gnssAntAdc; env->antDiscript.gsmAt = gsm; env->antDiscript.mode = antMode; env->gsmWithGnss = gsmWithGnss; DeviceTests_InitTestsTable(env, ignPin, speakerAdc, batteryAdc, gsm, audioCodec, accel, &env->antDiscript); InitThreadAtrStatic(&env->threadTest.attr, "Thread_Test", env->threadTest.controlBlock, env->threadTest.stack, osPriorityNormal); env->flagAutoTestSucsess = false; env->flagAcsessExitThread = (uint8_t)1; return true; } void DeviceTesting_StartTestThread(tDeviceTesting *env) { if (!env->threadTest.id) { env->threadTest.id = osThreadNew( (osThreadFunc_t) (DeviceTesting_ManualTestMode), (void *) (env), &env->threadTest.attr ); } } bool DeviceTesting_ExitTestMode(tDeviceTesting *env) { if (osThreadTerminate(env->threadTest.id) == osOK) { osDelay(2000); env->threadTest.id = NULL; env->flagAcsessExitThread = (uint8_t)1; return 1; } else { return 0; } } void DeviceTesting_ChekExit(tDeviceTesting *env) { AtGsm_Gsnss_GetNMEA_Pack(env->gsmWithGnss, 1000); SystemDelayMs(100); EraGlonassUveos_DoNothingModeDistance(env->ErGlUv, false); } bool DeviceTesting_RunUserTests(tDeviceTesting *env) { DeviceTesting_StartTestThread(env); for (;;) { if (EraGlonassUveos_IsAllowInCall(env->ErGlUv) && GpioPinGet(env->ringPin)) { if (DeviceTesting_ExitTestMode(env)) { EraGlonassUveos_DoNotingReset(env->ErGlUv); return 1; } } if (!GpioPinGet(env->pinIgnition) && (env->flagAcsessExitThread == 1)) { if (DeviceTesting_ExitTestMode(env)) { EraGlonassUveos_DoNotingReset(env->ErGlUv); return 1; } } if (env->flagAcsessExitThread == 2) { if (DeviceTesting_ExitTestMode(env)) { EraGlonassUveos_DoNotingReset(env->ErGlUv); return 1; } } if (env->ErGlUv->doNothing.mode == UVEOS_DO_NOTHING_DISABLED) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматический выход из режима пользовательского тестирования") if (DeviceTesting_ExitTestMode(env)) { EraGlonassUveos_DoNotingReset(env->ErGlUv); return 1; } } SystemDelayMs(500); } } void DeviceTesting_ManualTestMode(tDeviceTesting *env) { //запускаем режим тестирования с пользователем DeviceTesting_MainTestingMode(env); } //возвращает true в случае ошибки bool DeviceTesting_OnIgnitionWithoutGsm(tDeviceTesting *env) { DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_IGNITION_WITHOUT_GSM, 0); return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR); } //возвращает true в случае ошибки bool DeviceTesting_OnIgnitionAfterGsm(tDeviceTesting *env) { DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_IGNITION_AFTER_GSM, 0); return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR); } //возвращает true в случае ошибки bool DeviceTesting_Always(tDeviceTesting *env) { DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_ALWAYS, 0); // if ((DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR)) || (DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_NOT_CONNECTED)) || (DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_SHORT_CIRCUIT)) ) { return true; } else { return false; } } //возвращает true в случае ошибки bool DeviceTesting_Main(tDeviceTesting *env) { DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_MAIN, 0); return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR); } //возвращает true в случае ошибки bool DeviceTesting_Periodical(tDeviceTesting *env) { if (!env->testsTable.currentProcessIterationsLeft) { return false; } --env->testsTable.currentProcessIterationsLeft; LoggerInfoStatic(LOGGER, LOG_SIGN, "Режим самотестирования") SystemDelayMs(5000); DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_PERIODICAL, 1000); bool errors = DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR); if (errors) { for (uint16_t testIdx = 0; testIdx < env->testsTable.count; ++testIdx) { tTestDescriptor *test = env->testsTable.items + testIdx; if (test->result == DEVICE_TESTING_CODE_ERROR) { LoggerCnErrorStatic(LOGGER, LOG_SIGN, "Тест ") LoggerCnError(LOGGER, LOG_SIGN, test->name.str, test->name.length) LoggerErrorStatic(LOGGER, LOG_SIGN, " не пройден") } } } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Все тесты пройдены") } return errors; } bool DeviceTesting_UserTests(tDeviceTesting *env) { DeviceTesting_ChekExit(env); EraGlonassMsd_ClearDiagnostic(&env->tmsdDiagRes); //задаем режим и обновляем индикторы UserIndication_SetMode(env->indication, DEVICE_MODE_TESTING); EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.speakersFailure, DeviceTesting_TestAudioSpeaker(env)); DeviceTesting_ChekExit(env); EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.ignitionLineFailure, DeviceTesting_Ignition(env)); DeviceTesting_ChekExit(env); EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.micFailure, DeviceTesting_TestMic(env)); DeviceTesting_ChekExit(env); EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.uimFailure, DeviceTesting_Buttons(env)); DeviceTesting_ChekExit(env); //выключаем индикацию UserIndication_StopThread(env->indication); EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.statusIndicatorFailure, DeviceTesting_Indication(env)); DeviceTesting_ChekExit(env); //включаем индикацию UserIndication_StartThread(env->indication); return DeviceTesting_UserGetResult(env); } void DeviceTesting_AudioSysTestOk(tDeviceTesting *env) { SystemDelayMs(100); DEVTST_PLAY_SAMPLE("func") DEVTST_PLAY_SAMPLE("regularly") if (!env->flagAutoTestSucsess) { env->flagAutoTestSucsess = true; } } void DeviceTesting_AudioSysTestErr(tDeviceTesting *env) { SystemDelayMs(100); DEVTST_PLAY_SAMPLE("func") DEVTST_PLAY_SAMPLE("no") DEVTST_PLAY_SAMPLE("regularly") } void DeviceTesting_GetSystemTest(tDeviceTesting *env) { if (DeviceTestsTable_MakeTest(env->namedTests.firmware) == DEVICE_TESTING_CODE_PASSED) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование целостности ПО, вызванное пользователем прошло успешно") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.firmwareImageCorruption, false); DEVTST_PLAY_SAMPLE("ks_right") // DEVTST_PLAY_SAMPLE("po") // DEVTST_PLAY_SAMPLE("no") // DEVTST_PLAY_SAMPLE("violated") if (!env->flagAutoTestSucsess) { env->flagAutoTestSucsess = true; } // } else { // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при автоматическом тестировании целостности ПО") // DEVTST_PLAY_SAMPLE("ks_mistake") // DEVTST_PLAY_SAMPLE("integrity") // DEVTST_PLAY_SAMPLE("po") // DEVTST_PLAY_SAMPLE("no") // DEVTST_PLAY_SAMPLE("violated") } if (DeviceTestsTable_MakeTest(env->namedTests.gsm) != DEVICE_TESTING_CODE_PASSED) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка модема при автоматическом тестировании пользователем") DEVTST_PLAY_SAMPLE("modem") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.commModuleFailure, true); DeviceTesting_AudioSysTestErr(env); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование модема, вызванное пользователем прошло успешно") DEVTST_PLAY_SAMPLE("modem") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.commModuleFailure, false); DeviceTesting_AudioSysTestOk(env); } if (DeviceTestsTable_MakeTest(env->namedTests.accel) == DEVICE_TESTING_CODE_PASSED) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование акселеромерта, вызванное пользователем прошло успешно") DEVTST_PLAY_SAMPLE("axel") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.crashSensorFailure, false); DeviceTesting_AudioSysTestOk(env); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка акселеромерта при автоматическом тестировании пользователем") DEVTST_PLAY_SAMPLE("axel") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.crashSensorFailure, true); DeviceTesting_AudioSysTestErr(env); } if (DeviceTestsTable_MakeTest(env->namedTests.batteryCharge) != DEVICE_TESTING_CODE_ERROR) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование АКБ, вызванное пользователем прошло успешно") DEVTST_PLAY_SAMPLE("akb") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.batteryFailure, false); DeviceTesting_AudioSysTestOk(env); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка АКБ при автоматическом тестировании пользователем") DEVTST_PLAY_SAMPLE("akb") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.batteryFailure, true); DeviceTesting_AudioSysTestErr(env); } if ( (DeviceTestsTable_MakeTest(env->namedTests.gnssAnt) == DEVICE_TESTING_CODE_CONNECTED)|| (DeviceTestsTable_MakeTest(env->namedTests.gnssAnt) == DEVICE_TESTING_CODE_INPUT_ANTENA_OK) ) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование антены, вызванное пользователем прошло успешно") DEVTST_PLAY_SAMPLE("antenna") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.gnssAntennaFailure, false); DeviceTesting_AudioSysTestOk(env); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка антены при автоматическом тестировании пользователем") DEVTST_PLAY_SAMPLE("antenna") EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.gnssAntennaFailure, true); DeviceTesting_AudioSysTestErr(env); } if (DeviceTestsTable_MakeTest(env->namedTests.audioCodec) == DEVICE_TESTING_CODE_PASSED) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование аудиотракта, вызванное пользователем прошло успешно") DEVTST_PLAY_SAMPLE("auditract") DeviceTesting_AudioSysTestOk(env); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка аудиотракта при автоматическом тестировании пользователем") DEVTST_PLAY_SAMPLE("auditract") DeviceTesting_AudioSysTestErr(env); } } //возвращает true в случае ошибки void DeviceTesting_MainTestingMode(tDeviceTesting *env) { UserIndication_Uiu(env->indication, UIU_OFF); UserButtons_Clear(env->input); LoggerInfoStatic(LOGGER, LOG_SIGN, "Начало пользовательского тестирования") DEVTST_PLAY_SAMPLE("switching-to") DEVTST_PLAY_SAMPLE("mode") DEVTST_PLAY_SAMPLE("testing") bool userTestsOk = DeviceTesting_UserTests(env); LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполняются внутренние тесты") DeviceTesting_GetSystemTest(env); if (env->flagAutoTestSucsess) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Внутренние тесты завершены успешно") } DeviceTesting_ChekExit(env); if (userTestsOk && !env->flagAutoTestSucsess) { SystemDelayMs(500); LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка внутреннего теста") DEVTST_PLAY_SAMPLE("bug_internal_testing") } DeviceTesting_ChekExit(env); if (userTestsOk && env->flagAutoTestSucsess) { if (!DeviceTesting_Main(env)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Все тесты пройдены успешно") SystemDelayMs(500); DEVTST_PLAY_SAMPLE("testing") DEVTST_PLAY_SAMPLE("exit_good") } } DeviceTesting_ChekExit(env); UserInputButtonWatcher_Clear(env->UserInputButtonWatcher); LoggerInfoStatic(LOGGER, LOG_SIGN, "Начало тестирования вызова с передачей данных с результатами проверки") SystemDelayMs(2000); DeviceTesting_Ecall(env); LoggerInfoStatic(LOGGER, LOG_SIGN, "Тестовый вызов пройден") LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируется голосовой отчёт по тестовому вызову") DeviceTesting_ChekExit(env); DeviceTesting_GetEcalRes(env); if(env->ecallAddStatusRes == 1){ LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполняются вызов оператору 112") env->ErGlUv->currentMsd->msd.MSD_Data.msgId = 1; EraGlonassUveos_ManualEmergencyCall(env->ErGlUv, false); } DeviceTesting_ChekExit(env); LoggerInfoStatic(LOGGER, LOG_SIGN, "Голосовой отчёт по тестовому вызову выполнен") env->flagAcsessExitThread = (uint8_t) 2; uint32_t time = SystemGetMs() + 20000; while (1) { if(time < SystemGetMs()){ return ; } SystemDelayMs(20); } }