465 lines
17 KiB
C
465 lines
17 KiB
C
#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 подсистемы")
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|