SMART_COMPONENTS_Gsm_Sim7600E/GsmWithGnss.c

465 lines
17 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.

#include <sys/cdefs.h>
//
// 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 <AtCmdCommonProtected.h>
#include <AudioPlayerSimComSim7600E.h>
#include <AudioRecorderSimComSim7600E.h>
#include <SystemDelayInterface.h>
#include <memory.h>
#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 подсистемы")
}
}