215 lines
6.6 KiB
C
215 lines
6.6 KiB
C
//
|
|
// Created by xemon on 02.09.22.
|
|
//
|
|
|
|
//#include <Log.h>
|
|
#include <memory.h>
|
|
#include "SerialPort.h"
|
|
#include "SystemDelayInterface.h"
|
|
#include "AsciiStringAssmeblingUtils.h"
|
|
#include "NmeaACPParser.h"
|
|
#include "GsmWithGnss.h"
|
|
#include "AtGsmTelitLe910.h"
|
|
#include "AtCmdCommonProtected.h"
|
|
#include "AtGsmSms_DeleteAll.h"
|
|
#include "Nmea0183Parser.h"
|
|
#include "Rtc.h"
|
|
|
|
#define LOGGER env->logger
|
|
#define LOG_SIGN "GSM&GNSSOPS"
|
|
|
|
time_t gnssTime;
|
|
bool fl_rtcIsUsed = false;
|
|
#define GWG_IER(FUNC) {A}
|
|
|
|
|
|
AtCommandResult GsmWithGnssInitGnss(tGsmWithGnss *env) {
|
|
AT_INOKR(AtGsmTelitLe910_GnssSwitchOnRestoreParam(&env->gsmAt))
|
|
SystemDelayMs(200);
|
|
AT_INOKR(AtGsmTelitLe910_Gnss_ClearNvramGnssBuf(&env->gsmAt));
|
|
SystemDelayMs(200);
|
|
AT_INOKR(AtGsmTelitLe910_Gnss_ClearStaticBufFix(&env->gsmAt));
|
|
SystemDelayMs(200);
|
|
// AT_INOKR(AtGsmTelitLe910_Gnss_AGPSup(&env->gsmAt,2));
|
|
// SystemDelayMs(1000);
|
|
AT_INOKR(AtGsmTelitLe910_Gnss_ReStartReceiver(&env->gsmAt, 1));
|
|
SystemDelayMs(200);
|
|
AT_INOKR(AtGsmTelitLe910_SIMCardDetect(&env->gsmAt));
|
|
SystemDelayMs(200);
|
|
return AT_OK;
|
|
}
|
|
|
|
void AtGsm_Gsnss_NavData_Incorrect(tGsmWithGnss *env) {
|
|
env->gnss.currentRmc.status = 'V';
|
|
}
|
|
|
|
void AtGsm_Gsnss_NavData_Processing(tGsmWithGnss *env) {
|
|
// Поиск строки RMC
|
|
|
|
// char Data[] = "$GPRMC,122118.00,A,5500.000013,N,03700.002305,E,0.0,0.0,180119,8.5,E,A,V*49";
|
|
// bNmea0183ParseRMC(Data + 7, sizeof(Data)- 7, &env->gnss.currentRmc);
|
|
// env->gnss.success = true;
|
|
|
|
if (bNmea0183IsRmcString(env->gsmAt.rxBuffer.data, env->gsmAt.rxBuffer.len)) {
|
|
if (bNmea0183IsValidString(env->gsmAt.rxBuffer.data, env->gsmAt.rxBuffer.len)) {
|
|
bNmea0183ParseRMC(env->gsmAt.rxBuffer.data + 7, env->gsmAt.rxBuffer.len - 7, &env->gnss.currentRmc);
|
|
|
|
env->gnss.success = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef UVEOS_ADD_TELEMATICA
|
|
void Gnss_GetFullNavData(tGsmWithGnss *env, tNmeaRmc *nmeaRmc) {
|
|
|
|
if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) {
|
|
|
|
memcpy(nmeaRmc, &env->gnssRmcGga.currentRmc, sizeof(tNmeaRmc));
|
|
|
|
osMutexRelease(env->gnssRmcGga.rmcAccess);
|
|
} else {
|
|
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата доступа Gnss_GetFullNavData")
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void GsmWithGnss_GetNevData(tGsmWithGnss *env, uint32_t timeout) {
|
|
|
|
GsmWithGnss_StartRMCThread(&env->gsmAt);
|
|
|
|
uint32_t endTimeout = SystemGetMs() + timeout;
|
|
env->gnss.currentRmc.time.second = 0;
|
|
while (endTimeout > SystemGetMs()) {
|
|
AtCmdProcessUnresolvedLines(&env->gsmAt);
|
|
if (env->gnss.currentRmc.time.second != 0) {
|
|
GsmWithGnss_StopRMCThread(&env->gsmAt);
|
|
osMutexRelease(env->gsmAt.access);
|
|
return;
|
|
}
|
|
SystemDelayMs(2);
|
|
}
|
|
GsmWithGnss_StopRMCThread(&env->gsmAt);
|
|
|
|
}
|
|
|
|
|
|
void AtGsm_Gsnss_GetNMEA_Pack(tGsmWithGnss *env, uint32_t timeout) {
|
|
env->gnss.currentAcp.status = 0;
|
|
char acpString[256];
|
|
size_t aspStringLen;
|
|
|
|
xAtGsmTelitLe910_Gnss_GetAcquiredPositionNMEA(&env->gsmAt, acpString, &aspStringLen, timeout);
|
|
|
|
if (bNmeaACPString(acpString, aspStringLen, &env->gnss.currentAcp)) {
|
|
if (bNmeaACPParse(acpString, aspStringLen, &env->gnss.currentAcp) && aspStringLen > 24) {
|
|
|
|
#ifdef USE_GSM_AND_GNSS_SIMCOM
|
|
if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) {
|
|
memcpy(&env->gnssRmcGga.currentRmc, &env->gnss.currentAcp, sizeof(env->gnss.currentAcp));
|
|
osMutexRelease(env->gnssRmcGga.rmcAccess);
|
|
}
|
|
|
|
if (env->gnssRmcGga.currentRmc.time.second != 0) {
|
|
if (env->isRtcACP == false) {
|
|
|
|
time_t timestamp;
|
|
timestamp = iNmea0183TimestampFromRmc(&env->gnssRmcGga.currentRmc);
|
|
|
|
if (timestamp > 1733817613) {
|
|
env->isRtcACP = true;
|
|
RtcSet(env->Rtc, ×tamp);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
env->gnss.success = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
char convertDecToMilliArcSec(double dec, int32_t *mArcs, double *gradus) {
|
|
int deg = 0, min = 0;
|
|
double sec = 0.0;
|
|
double _dec = dec;
|
|
|
|
deg = (int) (_dec / 100);
|
|
min = (int) (_dec) - (deg * 100);
|
|
|
|
sec = (double) (_dec - min - 100 * deg) * 60.0;
|
|
|
|
if (gradus != NULL) *gradus = deg + min / 60.0 + sec / 3600.0;
|
|
|
|
if (mArcs != NULL) *mArcs = (int) (deg * 3600 + min * 60) * 1000 + (int) (sec * 1000);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void NmeaRMCLocationToLocationACP(tNmeaLocationAcp *nmea, EraGlonassUveosNavData *gnss) {
|
|
convertDecToMilliArcSec(nmea->latitude, &gnss->latitude, NULL);
|
|
convertDecToMilliArcSec(nmea->longitude, &gnss->longitude, NULL);
|
|
}
|
|
|
|
void NmeaRMCLocationToLocationRMC(tNmeaLocationRmc *nmea, EraGlonassUveosNavData *gnss) {
|
|
convertDecToMilliArcSec(nmea->latitude, &gnss->latitude, NULL);
|
|
convertDecToMilliArcSec(nmea->longitude, &gnss->longitude, NULL);
|
|
}
|
|
|
|
void GnssTaskGetTime(tGsmWithGnss *env, uint32_t *timestamp) {
|
|
*timestamp = iNmea0183TimestampFromRmc(&env->gnss.currentRmc);
|
|
}
|
|
|
|
void GnssSetRTC(tGsmWithGnss *env) {
|
|
if (env->gnss.currentRmc.time.second != 0) {
|
|
if (!fl_rtcIsUsed) {
|
|
GnssTaskGetTime(env, (uint32_t *) &gnssTime);
|
|
RtcSet(env->Rtc, &gnssTime);
|
|
fl_rtcIsUsed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AtGsm_Gsnss_GetLastActualNavData(tGsmWithGnss *env, EraGlonassUveosNavData *location, bool locSourse) {
|
|
if (locSourse == 1) {
|
|
if (env->gnss.currentRmc.status == 'A') {
|
|
env->gnss.prevRmc = env->gnss.currentRmc;
|
|
location->valid = 2;
|
|
} else {
|
|
if (env->gnss.prevRmc.status == 'A') {
|
|
env->gnss.currentRmc = env->gnss.prevRmc;
|
|
env->gnss.currentRmc.status = 'V';
|
|
location->valid = 1;
|
|
} else if (env->gnss.prevRmc.location.latitude < 1) {
|
|
env->gnss.currentRmc.status = 'V';
|
|
location->valid = 0;
|
|
}
|
|
}
|
|
} else {
|
|
if (env->gnss.currentAcp.status == 'A') {
|
|
location->valid = 1;
|
|
} else {
|
|
location->valid = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GnssGetNavData(tGsmWithGnss *env, EraGlonassUveosNavData *location, bool locSourse) {
|
|
|
|
GnssSetRTC(env);
|
|
|
|
AtGsm_Gsnss_GetLastActualNavData(env, location, locSourse);
|
|
|
|
if (locSourse == 1) {
|
|
NmeaRMCLocationToLocationRMC(&env->gnss.currentRmc.location, location);
|
|
location->direction = (uint16_t) env->gnss.currentRmc.headingAngle;
|
|
} else {
|
|
NmeaRMCLocationToLocationACP(&env->gnss.currentAcp.location, location);
|
|
location->direction = (uint16_t) env->gnss.currentAcp.course;
|
|
}
|
|
}
|
|
|