#include // // Created by zemon on 05.04.23. // // // Created by xemon on 21.10.22. // #include "GsmWithGnss_Private.h" #include "AtGsm_GetTime.h" #include "Rtc.h" #include #include #include #include #include #include "ext_telematica.h" #define LOGGER env->logger #define LOG_SIGN "GSM&GNSS" EraGlonassUveosNavData location; void GsmWithGnss_resetInputCall(tGsmWithGnss *env) { env->urc.inputCall = false; } void GsmWithGnss_ResetRing(tGsmWithGnss *env) { env->urc.ring = false; } bool GsmWithGnss_IsRing(tGsmWithGnss *env) { return env->urc.ring; } void GsmWithGnss_resetMsd(tGsmWithGnss *env) { env->urc.msdSendResult = false; } void GsmWithGnss_Urc(tGsmWithGnss *env, tAtBuffer *buff) { // LoggerInfo(LOGGER, LOG_SIGN, buff->data, buff->len) if (AtBufferBeginWithStatic(buff, "+ECALL: SUCCEED_TO_TRANSMIT_MSD")) { env->urc.msdSendResult = true; LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, MSD доставлен.") } if (AtBufferBeginWithStatic(buff, "+ECALL:UNMUTE MSD transfer complete")) { env->urc.msdSendResult = true; LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, MSD доставлен..") } if (AtBufferBeginWithStatic(buff, "+ECALL: UNMUTE MSD transfer complete")) { env->urc.msdSendResult = true; LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, MSD доставлен...") } if (AtBufferBeginWithStatic(buff, "+ECALL: FAILED_TO_TRANSMIT_MSD")) { env->urc.msdSendResult = false; LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, ОШИБКА ДОСТАВКИ MSD.") } if (AtBufferBeginWithStatic(buff, " +ECALL: FAILED_TO_TRANSMIT_MSD")) { env->urc.msdSendResult = false; LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, ОШИБКА ДОСТАВКИ MSD по каналу тональной связи.") } if (AtBufferBeginWithStatic(buff, "VOICE CALL: BEGIN")) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, начало вызова средствами тональной связи код 1") env->urc.ring = true; } if (AtBufferBeginWithStatic(buff, "RING")) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, начало вызова средствами тональной связи код 2") env->urc.ring = true; } if (AtBufferBeginWithStatic(buff, "VOICE CALL: END:")) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, сброс вызова тональной связи") env->urc.ring = false; } if (AtBufferBeginWithStatic(buff, "+CREG: 0,1") || AtBufferBeginWithStatic(buff, "+CREG: 0,2")) { env->urc.netReg = true; // LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена URC, получена регистрация в сети.") } if (AtBufferBeginWithStatic(buff, "$GPRMC,")) { if (*env->enableGnssUpdate == true) { AtGsm_Gsnss_NavData_Processing(env, buff); AtGsm_Gsnss_GetLastActualNavData(env, &location, 1); } } if (AtBufferBeginWithStatic(buff, "#ECALLEV:0")) { env->urc.msdPull = true; } if (AtBufferBeginWithStatic(buff, "+CMTI: \"SM\"")) { env->urc.message = true; } if (EXT_ENV_ADR_TELE.META_EXT_ENV_TELE) EXT_ENV_ADR_TELE.tele_func(buff, TELE_MODULE_GSM_URC); } uint32_t GsmWithGnss_InvalidateGnssUserExternalAntenna(tGsmWithGnss *env, uint32_t currentState, uint32_t targetState) { AtGsm_Gsnss_Simcom7600_SetExternalLnaSupport( &env->gsmAt, targetState ? SIMCOM_SIM7600_EXTERNAL_LNA_NOT_SUPPORT : SIMCOM_SIM7600_EXTERNAL_LNA_SUPPORT ); return targetState; } bool GsmWithGnss_InvalidateNetworkEnable(tGsmWithGnss *env, uint32_t currentState, uint32_t targetState) { if (targetState) { if (!GsmWithGnss_WaitNetworkRegistration(env, 2000)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Сеть или сим-чип отсутствует, попытка регистрации_3..."); if (GsmWithGnss_NetworkSetStateInnaterups(env, 4, 10000) == AT_OK) { LoggerTraceStatic(LOGGER, LOG_SIGN, "Сеть присутствует") } else { LoggerErrorStatic(LOGGER, LOG_SIGN, "нет сети"); return false; } } else { LoggerErrorStatic(LOGGER, LOG_SIGN, "Регистрация в сети присутствует"); return true; } } else { if (osMutexAcquire(env->gsmAt.access, 1000) == osOK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Отключаем регистрацию в сети") AtGsm_OperatorSelectionDeregister(&env->gsmAt); osMutexRelease(env->gsmAt.access); return false; } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Подсистема контроля URC не смогла выполнить захват управления, повторная попытка захвата...") return true; } } return false; } AtCommandResult GsmWithGnss_NetworkReconnect(tAtCmd *env, uint8_t cuontReg) { AtCommandResult res = AT_ERROR; if (osMutexAcquire(env->access, 1000) == osOK) { for (uint8_t i = 0; i < cuontReg; i++) { res = AtGsm_OperatorSelectionAutomatic(env); SystemDelayMs(500); } osMutexRelease(env->access); return res; } return res; } AtCommandResult GsmWithGnss_NetworkSetStateInnaterups(tGsmWithGnss *env, uint8_t cuontReg, uint32_t timeOut) { if (GsmWithGnss_NetworkReconnect(&env->gsmAt, cuontReg) == AT_OK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание регистрации в сети"); if (GsmWithGnss_WaitNetworkRegistration(env, timeOut) == true) { LoggerTraceStatic(LOGGER, LOG_SIGN, "Сеть найдена") return AT_OK; } else { LoggerTraceStatic(LOGGER, LOG_SIGN, "Попытка регистрации в сети НЕ выполнена") return AT_ERROR; } } return AT_ERROR; } void GsmWithGnssInit( tGsmWithGnss *env, tString16 *smsCenter, uint16_t *gnssDataRateHz, tRtcIO *Rtc, bool *enableGnssUpdate, tAudioPlayer *audioPlayer, tAudioRecorder *audioRecorder ) { env->isRegToGSM = false; env->flBlockReg = false; env->enableGnssUpdate = enableGnssUpdate; env->smsCenter = smsCenter; env->gnss.dataRateHz = gnssDataRateHz; env->Rtc = Rtc; env->navDataProvider.env = env; env->navDataProvider.getNavData = (void *) GnssGetNavData; env->navDataProvider.getTime = (void *) GnssTaskGetTime; env->audioPlayer = audioPlayer; env->audioRecorder = audioRecorder; env->ecallProvider = (tEraGlonassEcallProvider) { .env = env, .settingNewMsd = (setNewMsd) GsmWithGnss_SetNewMSD, .ecall =(sendEcallCall) GsmWithGnss_Ecall, .isDialing =(eraGlonassEcallProviderCall) GsmWithGnss_isCallDialing, .isMsdSent =(eraGlonassEcallProviderCall) GsmWithGnss_isMsdSent, .isMsdReSent =(eraGlonassEcallProviderCall) GsmWithGnss_isMsdReSent, .isActiveOut =(eraGlonassEcallProviderCall) GsmWithGnss_isOutCallActive, .isActiveInp =(eraGlonassEcallProviderCall) GsmWithGnss_isInpCallActive, .hangup =(eraGlonassEcallProviderCall) GsmWithGnss_HangUp, .hangupEcl =(eraGlonassEcallProviderCall) GsmWithGnss_HangUpEcoll, .prepHenUp =(eraGlonassEcallProviderCall) AtGsmPrepHangCall, // .isNetworkState =(void*) GsmWithGnss_WaitNetworkRegistration, .isNetReg =(eraGlonassEcallProviderCall) GsmWithGnss_GetUrcIsNetReg, .resetUrcNetReg =(eraGlonassEcallProviderCall) GsmWithGnss_ResetUrcIsNetReg, .isNetworkReg =(void *) GsmWithGnss_InvalidateNetworkEnable }; env->smsProvider.env = env; env->smsProvider.sendDataPdu = (void *) GsmWithGnss_SendDataPduSms; if (osMutexAcquire(env->gsmAt.access, 1000) == osOK) { GsmWithGnss_ResetRing(env); LoggerInfoStatic(LOGGER, LOG_SIGN, "Сброс URC RING выполнен 1"); osMutexRelease(env->gsmAt.access); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата управления, сброс URC RING 1") } env->audioPlayerIO = AudioPlayerSimComSim7600E_GetInterface(env->audioPlayer); env->audioRecorderIO = AudioRecordSimComSim7600E_GetInterface(env->audioRecorder); ControllableSwitch_Init(&env->useInternalAntennaSwitch, env, GsmWithGnss_InvalidateGnssUserExternalAntenna); ControllableSwitch_Init(&env->enableNetworkSwitch, env, GsmWithGnss_InvalidateNetworkEnable); env->gnss.rmcAccess = osMutexNew(NULL); AtCmdSetUrcProcessor(&env->gsmAt, env, GsmWithGnss_Urc); InitThreadBlock(env->urcT, "gsm_urc", osPriorityNormal); env->busyThread = false; } _Noreturn void GsmWithGnss_urcThread_body(tGsmWithGnss *env) { for (;;) { if (osMutexAcquire(env->gsmAt.access, 5000) == osOK) { // LoggerInfoStatic(LOGGER, LOG_SIGN, "--URC processor мьютэкс RMC захвачен") //AtCmdProcessUnresolvedLines(&env->gsmAt); while (AtCmdReceiveNextLine(&env->gsmAt, 150) == AT_OK) { AtCmdProcessUnresolvedLine(&env->gsmAt); } osMutexRelease(env->gsmAt.access); // LoggerInfoStatic(LOGGER, LOG_SIGN, "--URC processor мьютэкс RMC освобождён") } else { // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (GsmWithGnss_urcThread_body)") } SystemDelayMs(40); } } bool GetMuxNavDataAcsess(tGsmWithGnss *env, tNmeaRmc *rmc) { if (osMutexAcquire(env->gsmAt.access, 1000) != osOK) { return false; } *rmc = env->gnss.currentRmc; osMutexRelease(env->gsmAt.access); return true; } void GsmWithGnss_startUrcThread(tGsmWithGnss *env) { /// urcEnv = env; ThreadBlock_Start(env->urcT, env, GsmWithGnss_urcThread_body); } void GsmWithGnss_UseInternalAntenna(tGsmWithGnss *env, bool value) { ControllableSwitch_Set(&env->useInternalAntennaSwitch, value); } void GsmWithGnss_SetNetworkRegistration(tGsmWithGnss *env, bool value) { ControllableSwitch_Set(&env->enableNetworkSwitch, value); } /* * */ bool GsmWithGnss_WaitNetworkRegistration(tGsmWithGnss *env, uint32_t timeReg) { uint32_t timeEnd = SystemGetMs() + timeReg; tAtGsm_NetworkRegistrationReportMode mode; while (timeEnd > SystemGetMs()) { if (!env->flBlockReg) { if (osMutexAcquire(env->gsmAt.access, 1000) == osOK) { if (AtGsm_NetworkRegistrationStatus(&env->gsmAt, &mode, &env->regState)) { if ( env->regState == AT_NETWORK_REGISTRATION_STATE_REGISTERED_HOME || env->regState == AT_NETWORK_REGISTRATION_STATE_REGISTERED_ROAMING ) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена регистрация") osMutexRelease(env->gsmAt.access); env->isRegToGSM = true; return true; } else { env->regState = AT_NETWORK_REGISTRATION_STATE_REGISTRATION_DENIED; osMutexRelease(env->gsmAt.access); env->isRegToGSM = false; return false; } } osMutexRelease(env->gsmAt.access); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_WaitNetworkRegistration)") } } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация запрещена настройками") env->isRegToGSM = true; return true; } SystemDelayMs(40); } env->isRegToGSM = false; return false; } void GsmWithGnss_SetNetworkRegistrationHard(tGsmWithGnss *env, bool value) { ControllableSwitch_SetHard(&env->enableNetworkSwitch, value); } bool GsmWaitFirstStartup(tGsmWithGnss *env) { volatile AtCommandResult res = AT_ERROR; uint32_t ttm = SystemGetMs() + 3000; if (osMutexAcquire(env->gsmAt.access, 1000) == osOK) { res = AtCmdWaitOk(&env->gsmAt, 1000, 10000); osMutexRelease(env->gsmAt.access); while (ttm > SystemGetMs()){ SystemDelayMs(50); } return res; } while (ttm > SystemGetMs()){ SystemDelayMs(50); } return res; } bool GsmWithGnss_IsGnssReady(tGsmWithGnss *env) { return (env->gnss.currentRmc.status == 'A') && (env->gnss.currentRmc.location.longitude) && (env->gnss.currentRmc.location.latitude); } void Gsm_WaitGetTimeAsBaseStation(tGsmWithGnss *env) { struct tm tm_time; SystemDelayMs(500); if (osMutexAcquire(env->gsmAt.access, 5000) == osOK) { memset(&tm_time, '\0', sizeof(tm_time)); AtGsm_GetTime(&env->gsmAt, &tm_time); time_t gsmTime = mktime(&tm_time); gsmTime &= 0xFFFFFFFF; // gsmTime -= 3600 * 3; LoggerFormatInfo(LOGGER, LOG_SIGN, "Получено время с GSM, временная метка: %u", gsmTime) if (gsmTime > 1734956049) { RtcSet(env->Rtc, &gsmTime); } osMutexRelease(env->gsmAt.access); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата управления WaitGetTime") } } void Gsm_SetManualModemPower( tGsmWithGnss *env, bool *mode, uint16_t *MODEM_POWER_FOR_LTE_MODE, uint16_t *MODEM_POWER_FOR_WCDMA_MODE, uint16_t *MODEM_POWER_FOR_GSM_MODE ){ if(*mode == true){ GsmWithGnssSetModemManualPowerMode(env, mode); GsmWithGnssSetModemLTEPowerMode(env, MODEM_POWER_FOR_LTE_MODE); GsmWithGnssSetModemWCDMAPowerMode(env, MODEM_POWER_FOR_WCDMA_MODE); GsmWithGnssSetModemGSMPowerMode(env, MODEM_POWER_FOR_GSM_MODE); } } void Gsm_WaitGsmBoot(tGsmWithGnss *env) { uint32_t time = SystemGetMs() + 20000; while (time > SystemGetMs()) { if (GsmWithGnssInitGnss(env) == AT_OK) { break; } SystemDelayMs(100); } } void RestartResiver(tGsmWithGnss *env, bool stat){ if (osMutexAcquire(env->gsmAt.access, 1000) == osOK) { uint32_t tm = SystemGetMs() + 2000; while (tm > SystemGetMs()){ SystemDelayMs(4); } AtCommandResult result = AT_ERROR; tm = SystemGetMs() + 4000; while (tm > SystemGetMs()){ result = AtGsm_Gsnss_Simcom7600_StartReceiver(&env->gsmAt, stat); if (result == AT_OK){ if(stat == false) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Остановка GNSS подсистемы выполнена"); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Запуск GNSS подсистемы выполнен"); } osMutexRelease(env->gsmAt.access); return; } SystemDelayMs(40); } osMutexRelease(env->gsmAt.access); LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при выполнении запуска/остановки GNSS подсистемы"); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата управления, остановка GNSS подсистемы") } } void StopResiver(tGsmWithGnss *env){ RestartResiver(env,false); } void StartResiver(tGsmWithGnss *env){ RestartResiver(env,true); } void HotStartGNSS(tGsmWithGnss *env){ if (osMutexAcquire(env->gsmAt.access, 2000) == osOK) { uint32_t tm = SystemGetMs() + 500; while (tm > SystemGetMs()){ SystemDelayMs(4); } AtCommandResult result = AT_ERROR; tm = SystemGetMs() + 4000; while (tm > SystemGetMs()){ result = AtGsm_Gsnss_Simcom7600_HotStartReceiver(&env->gsmAt); if (result == AT_OK){ LoggerInfoStatic(LOGGER, LOG_SIGN, "Горячий перезапуск GNSS выполнен"); osMutexRelease(env->gsmAt.access); return; } SystemDelayMs(40); } osMutexRelease(env->gsmAt.access); LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при выполнении горячего перезапуска GNSS"); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата управления, горячий старт GNSS подсистемы") } }