From 3594ed4a2f463adb1c04f93aa519062ce9796384 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 2 Jun 2025 14:32:56 +0300 Subject: [PATCH] Init --- GsmSocketSlot.c | 28 +++++ GsmSocketTimeouts.h | 17 +++ GsmWithGnss.c | 232 ++++++++++++++++++++++++++++++++++++++++ GsmWithGnss.h | 71 ++++++++++++ GsmWithGnss_Info.c | 67 ++++++++++++ GsmWithGnss_Info.h | 17 +++ Gsm_SSL_SockInt.c | 23 ++++ Gsm_SSL_SockInt.h | 27 +++++ Gsm_Serial.c | 20 ++++ Gsm_SockInt.c | 23 ++++ Gsm_SockInt.h | 27 +++++ Gsm_SockInt_Open.c | 90 ++++++++++++++++ Gsm_SockInt_Read.c | 45 ++++++++ Gsm_SockInt_SSL_Open.c | 109 +++++++++++++++++++ Gsm_SockInt_SSL_Read.c | 44 ++++++++ Gsm_SockInt_SSL_Write.c | 72 +++++++++++++ Gsm_SockInt_Write.c | 88 +++++++++++++++ SocketInterface.h | 49 +++++++++ modular.json | 10 ++ 19 files changed, 1059 insertions(+) create mode 100644 GsmSocketSlot.c create mode 100644 GsmSocketTimeouts.h create mode 100644 GsmWithGnss.c create mode 100644 GsmWithGnss.h create mode 100644 GsmWithGnss_Info.c create mode 100644 GsmWithGnss_Info.h create mode 100644 Gsm_SSL_SockInt.c create mode 100644 Gsm_SSL_SockInt.h create mode 100644 Gsm_Serial.c create mode 100644 Gsm_SockInt.c create mode 100644 Gsm_SockInt.h create mode 100644 Gsm_SockInt_Open.c create mode 100644 Gsm_SockInt_Read.c create mode 100644 Gsm_SockInt_SSL_Open.c create mode 100644 Gsm_SockInt_SSL_Read.c create mode 100644 Gsm_SockInt_SSL_Write.c create mode 100644 Gsm_SockInt_Write.c create mode 100644 SocketInterface.h create mode 100644 modular.json diff --git a/GsmSocketSlot.c b/GsmSocketSlot.c new file mode 100644 index 0000000..306621a --- /dev/null +++ b/GsmSocketSlot.c @@ -0,0 +1,28 @@ +// +// Created by cfif on 05.07.23. +// + +#include "GsmWithGnss.h" +#include "memory.h" +#include "ext_telematica.h" + +void GsmSocketSlot_Init(tGsmSocketSlot *slot, uint32_t bufLen) { + memset(slot, 0, sizeof(tGsmSocketSlot)); + slot->rxDataQueue = osMessageQueueNew(bufLen, 1, NULL); + asm("nop"); +} + +void GsmSocketSlot_Set(tGsmSocketSlot *slot, eSocketType type, char *addr, size_t addrSize, uint16_t port) { + String32Copy(&slot->addr, addr, addrSize); + slot->port = port; + slot->type = type; +} + +void GsmSocketSlot_Clear(tGsmSocketSlot *slot) { + osMessageQueueReset(slot->rxDataQueue); + slot->addr.length = 0; +} + +bool GsmSocketSlot_IsClear(tGsmSocketSlot *slot) { + return slot->addr.length == 0; +} diff --git a/GsmSocketTimeouts.h b/GsmSocketTimeouts.h new file mode 100644 index 0000000..8746969 --- /dev/null +++ b/GsmSocketTimeouts.h @@ -0,0 +1,17 @@ +// +// Created by cfif on 19.07.2024. +// + +#ifndef SMART_COMPONENTS_TELEMATICA_GSMSOCKETTIMEOUTS_H +#define SMART_COMPONENTS_TELEMATICA_GSMSOCKETTIMEOUTS_H + +//#define defaultSocketTimeout 2000 +//#define defaultSocketOpenTimeout 4000 + +#define defaultSocketTimeout 20000 +#define defaultSocketOpenTimeout 20000 + +#define defaultSocketTransmiteTimeout 4000 + + +#endif //SMART_COMPONENTS_TELEMATICA_GSMSOCKETTIMEOUTS_H diff --git a/GsmWithGnss.c b/GsmWithGnss.c new file mode 100644 index 0000000..e2a6d8f --- /dev/null +++ b/GsmWithGnss.c @@ -0,0 +1,232 @@ +// +// Created by cfif on 20.06.2024. +// +#include "GsmWithGnss.h" +#include +#include "string.h" +#include "AsciiStringParsingUtils.h" +#include "Gsm_SockInt.h" +#include "SystemMutexCmsis.h" +#include "ext_telematica.h" +#include "Gsm_SSL_SockInt.h" + +extern tGsmWithGnss gsmWithGnss; + +#define LOGGER &env->slog->logger +#define LOG_SIGN "EGTS_GSM" + +static void rxGsm(tGsmWithGnss *env, osMessageQueueId_t rxDataQueue) { + if (AtCmdReceiveNextLine(env->gsmAt, 2000) == AT_OK) { + if (AtCmdRxBeginWithStatic(env->gsmAt, "+IPD")) { + uint16_t len = iAsciiStringParseUnsignedLongDecimalNumber( + env->gsmAt->rxBuffer.data + 4, env->gsmAt->rxBuffer.data + env->gsmAt->rxBuffer.len - 1 + ); + + uint16_t bufferLen = SerialPortReceive(env->gsmAt->io, env->bufLog, len, 2000); + + memset(env->bufLogHexString, 0, sizeof(env->bufLogHexString)); + size_t lenLog = 0; + vAsciiStringAddBytesAsHex(env->bufLogHexString, &lenLog, (uint8_t *) env->bufLog, bufferLen); + LoggerFormatInfo(LOGGER, LOG_SIGN, "FROM (%d): %s", bufferLen, env->bufLogHexString); + + if (bufferLen == len) { + for (uint16_t i = 0; i < bufferLen; ++i) { + osMessageQueuePut(rxDataQueue, &env->bufLog[i], 0x0, 0U); + } + } else { + LoggerFormatInfo(LOGGER, LOG_SIGN, "NO_FROM %d != %d", bufferLen, len); + } + + } else { + LoggerFormatTrace(LOGGER, LOG_SIGN, "Не получен +IPD") + } + } +} + +static void rxGsmSSL(tGsmWithGnss *env, osMessageQueueId_t rxDataQueue) { + + uint16_t len = iAsciiStringParseUnsignedLongDecimalNumber( + env->gsmAt->rxBuffer.data + sizeof("+CCHRECV: DATA,X"), + env->gsmAt->rxBuffer.data + env->gsmAt->rxBuffer.len - 1 + ); + + + uint16_t bufferLen = SerialPortReceive(env->gsmAt->io, env->bufLog, len, 2000); + +// memset(env->bufLogHexString, 0, sizeof(env->bufLogHexString)); +// size_t lenLog = 0; + +// if (bufferLen < 100) { +// vAsciiStringAddBytesAsHex(env->bufLogHexString, &lenLog, (uint8_t *) env->bufLog, bufferLen); +// LoggerFormatInfo(LOGGER, LOG_SIGN, "FROM (%d): %s", bufferLen, env->bufLogHexString); +// } else { +// vAsciiStringAddBytesAsHex(env->bufLogHexString, &lenLog, (uint8_t *) env->bufLog, 100); +// LoggerFormatInfo(LOGGER, LOG_SIGN, "FROM CUTE (%d): %s ...", bufferLen, env->bufLogHexString); +// } + + if (bufferLen == len) { + for (uint16_t i = 0; i < bufferLen; ++i) { + osStatus_t status = osMessageQueuePut(rxDataQueue, &env->bufLog[i], 0x0, 0U); + + if (status != osOK) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "Ошибка добавления в очередь %d", status); + } + + } + } else { + LoggerFormatInfo(LOGGER, LOG_SIGN, "NO_FROM %d != %d", bufferLen, len); + } + +} + +void GsmWithGnssTelematica_Urc(tAtBuffer *buff) { + + if (AtBufferBeginWithStatic(buff, "+CCH_PEER_CLOSED")) { + LoggerInfoStatic(&gsmWithGnss.slog->logger, LOG_SIGN, "Обнаружен разрыв соединения") + gsmWithGnss.isDisconnect = true; + } + + if (AtBufferBeginWithStatic(buff, "$GPGGA,")) { + gsmWithGnss.isNav = true; + + if (osMutexAcquire(gsmWithGnss.gnssRmcGga.rmcAccess, 2000) == osOK) { + bNmea0183ParseGGA(buff->data + 7, buff->len - 7, &gsmWithGnss.gnssRmcGga.currentGgaRmc); + gsmWithGnss.gnssRmcGga.isGGA_Active = true; + osMutexRelease(gsmWithGnss.gnssRmcGga.rmcAccess); + } + + return; + } + + if (AtBufferBeginWithStatic(buff, "$GPRMC,")) { + + if (osMutexAcquire(gsmWithGnss.gnssRmcGga.rmcAccess, 2000) == osOK) { + + if (bNmea0183IsRmcString(buff->data, buff->len)) { + if (bNmea0183IsValidString(buff->data, buff->len)) { + bNmea0183ParseRMC(buff->data + 7, buff->len - 7, &gsmWithGnss.gnssRmcGga.currentRmc); + gsmWithGnss.gnssRmcGga.isRMC_Active = true; + + gsmWithGnss.gnssRmcGga.gsmWithGnssTimeStamp.status = gsmWithGnss.gnssRmcGga.currentRmc.status; + memcpy(&gsmWithGnss.gnssRmcGga.gsmWithGnssTimeStamp.date, &gsmWithGnss.gnssRmcGga.currentRmc.date, + sizeof(tNmeaDateRmc)); + memcpy(&gsmWithGnss.gnssRmcGga.gsmWithGnssTimeStamp.time, &gsmWithGnss.gnssRmcGga.currentRmc.time, + sizeof(tNmeaTimeRmc)); + + } + } + + osMutexRelease(gsmWithGnss.gnssRmcGga.rmcAccess); + } + + return; + } + + + if (AtBufferBeginWithStatic(buff, "+CCHRECV: DATA")) { + uint8_t linkNum = iAsciiStringParseUnsignedLongDecimalNumber( + gsmWithGnss.gsmAt->rxBuffer.data + sizeof("+CCHRECV: DATA"), + gsmWithGnss.gsmAt->rxBuffer.data + sizeof("+CCHRECV: DATA") + 1 + ); + + tGsmSocketSlot *slot = gsmWithGnss.slots + linkNum; + + if (!GsmSocketSlot_IsClear(slot)) { + rxGsmSSL(&gsmWithGnss, slot->rxDataQueue); + return; + } else { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Соединение не создано") + } + + return; + } + + if (AtBufferBeginWithStatic(buff, "RECV FROM:")) { + + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + tGsmSocketSlot *slot = gsmWithGnss.slots + i; + if (!GsmSocketSlot_IsClear(slot)) { + if (memcmp(slot->addr.data, buff->data + sizeof("RECV FROM:") - 1, slot->addr.length) == 0) { + rxGsm(&gsmWithGnss, slot->rxDataQueue); + return; + } else { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Не совпадает адрес получателя") + } + } + } + + return; + } + +} + +int32_t GnssGgaGetAlt(tGsmWithGnss *env) { + int32_t Alt = 0; + + if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) { + Alt = (int32_t) env->gnssRmcGga.currentGgaRmc.altitude; + osMutexRelease(env->gnssRmcGga.rmcAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата доступа GnssGgaGetAlt") + } + + return Alt; +} + +uint8_t GnssGgaGetSat(tGsmWithGnss *env) { + uint8_t countSats = 0; + + if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) { + countSats = env->gnssRmcGga.currentGgaRmc.sats; + osMutexRelease(env->gnssRmcGga.rmcAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата доступа GnssGgaGetSat") + } + + return countSats; +} + + +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") + } + +} + +/* +void Gnss_GetFullNavData(tGsmWithGnss *env, tNmeaRmc *nmeaRmc) { + + if (osMutexAcquire(EXT_ENV_TELE.gnss.rmcAccess, 2000) == osOK) { + + memcpy(nmeaRmc, EXT_ENV_TELE.gnss.currentRmc, sizeof(tNmeaRmc)); + + osMutexRelease(EXT_ENV_TELE.gnss.rmcAccess); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gnss_GetFullNavData)") + } + +} +*/ + + +void GsmWithGnssInit(tGsmWithGnss *env) { + + env->slog = EXT_ENV_TELE.loggerToSerialPort; + env->gsmAt = EXT_ENV_TELE.gsmAt; + env->Rtc = EXT_ENV_TELE.rtcIO; + + env->gnssRmcGga.isRMC_Active = true; + env->gnssRmcGga.isGGA_Active = true; + + env->gnssRmcGga.rmcAccess = osMutexNew(NULL); + + Gsm_SSL_InitSocket(env,1024*12); + Gsm_InitIO(env); +} \ No newline at end of file diff --git a/GsmWithGnss.h b/GsmWithGnss.h new file mode 100644 index 0000000..15bbfef --- /dev/null +++ b/GsmWithGnss.h @@ -0,0 +1,71 @@ +// +// Created by cfif on 20.06.2024. +// + +#ifndef SMART_COMPONENTS_GSMWITHGNSS_H +#define SMART_COMPONENTS_GSMWITHGNSS_H + +#include "cmsis_os2.h" +#include "SerialPortIO.h" +#include "BaseTypes.h" +#include "SocketInterface.h" +#include "AtGsmSimComA7600.h" +#include "LoggerToSerialPort.h" +#include "Nmea0183Parser.h" +#include "SystemMutexCmsis.h" +#include "GsmSocketTimeouts.h" + +typedef struct { + uint8_t contextId; + tString32 addr; + uint16_t port; + tString16 portStr; + osMessageQueueId_t rxDataQueue; + eSocketType type; +} tGsmSocketSlot; + +#define GSM_SLOTS_COUNT 1 + +typedef struct { + char status; + tNmeaDateRmc date; + tNmeaTimeRmc time; +} tGsmWithGnssTimeStamp; + +typedef struct { + tAtCmd *gsmAt; + tRtcIO *Rtc; + tLoggerToSerialPort *slog; + + struct { + SystemMutexCmsis rmcAccess; + tNmeaGga currentGgaRmc; + tNmeaRmc currentRmc; + bool isRMC_Active; + bool isGGA_Active; + tGsmWithGnssTimeStamp gsmWithGnssTimeStamp; + } gnssRmcGga; + + uint8_t bufLog[2048]; + char bufLogHexString[260]; + + tGsmSocketSlot slots[256]; + tSocketInterface socketIO; + tSerialPortIO srvIo; + + bool isNav; + bool isDisconnect; + + uint8_t codeResultOpen; + +} tGsmWithGnss; + +void GsmWithGnssInit(tGsmWithGnss *env); + +uint8_t GnssGgaGetSat(tGsmWithGnss *env); + +int32_t GnssGgaGetAlt(tGsmWithGnss *env); + +void Gnss_GetFullNavData(tGsmWithGnss *env, tNmeaRmc *nmeaRmc); + +#endif //SMART_COMPONENTS_GSMWITHGNSS_H diff --git a/GsmWithGnss_Info.c b/GsmWithGnss_Info.c new file mode 100644 index 0000000..8a1e492 --- /dev/null +++ b/GsmWithGnss_Info.c @@ -0,0 +1,67 @@ +// +// Created by cfif on 07.06.2024. +// +#include "GsmWithGnss_Info.h" +#include "AtCmdCommonProtected.h" + + +#define LOGGER &env->slog->logger +#define LOG_SIGN "GSM&GNSS" + +uint8_t EpsNetworkRegistrationStatus(tGsmWithGnss *env) { + + uint8_t status = 0; + + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + + AtGsm_EpsNetworkRegistrationStatus( + env->gsmAt, + &status + ); + + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (EpsNetworkRegistrationStatus)") + } + + return status; +} + +uint8_t QuerySignalQuality(tGsmWithGnss *env) { + + uint8_t rssi = 0; + + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + + AtGsm_QuerySignalQuality( + env->gsmAt, + &rssi + ); + + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (QuerySignalQuality)") + } + + return rssi; +} + +AtCommandResult AtGsm_Gsnss_Simcom7600_SetConfigureStaticRMCThreadStop(tAtCmd *env) { + AtCmdTxClear(env); + AtCmdSendStatic(env, "AT+CGPSINFOCFG=1,0\r\n"); + return AtCmdOkErrAnswer(env, 2000); +} + +void SetConfigureStaticRMCThreadStop(tGsmWithGnss *env) { + + uint8_t rssi = 0; + + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + + AtGsm_Gsnss_Simcom7600_SetConfigureStaticRMCThreadStop(env->gsmAt); + + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (SetConfigureStaticRMCThreadStop)") + } +} \ No newline at end of file diff --git a/GsmWithGnss_Info.h b/GsmWithGnss_Info.h new file mode 100644 index 0000000..e1472be --- /dev/null +++ b/GsmWithGnss_Info.h @@ -0,0 +1,17 @@ +// +// Created by cfif on 07.06.2024. +// + +#ifndef SMART_COMPONENTS_GSMWITHGNSS_INFO_H +#define SMART_COMPONENTS_GSMWITHGNSS_INFO_H + +#include "GsmWithGnss.h" +#include "AtGsmEpsNetworkRegistrationStatus.h" +#include "AtGsmQuerySignalQuality.h" + +//eAtGsm_EpsNetworkRegistrationStatus EpsNetworkRegistrationStatus(tGsmWithGnss *env); +uint8_t EpsNetworkRegistrationStatus(tGsmWithGnss *env); +uint8_t QuerySignalQuality(tGsmWithGnss *env); +void SetConfigureStaticRMCThreadStop(tGsmWithGnss *env); + +#endif //SMART_COMPONENTS_GSMWITHGNSS_INFO_H diff --git a/Gsm_SSL_SockInt.c b/Gsm_SSL_SockInt.c new file mode 100644 index 0000000..df2cd5d --- /dev/null +++ b/Gsm_SSL_SockInt.c @@ -0,0 +1,23 @@ +// +// Created by cfif on 24.05.2024. +// +#include "Gsm_SockInt.h" +#include "Gsm_SSL_SockInt.h" + +void Gsm_SSL_InitSocket(tGsmWithGnss *env,uint16_t bufSize) { + + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + GsmSocketSlot_Init(env->slots + i, bufSize); + env->slots[i].contextId = i; + } + + GsmSocketSlot_Init(env->slots + SOCKET_WRONG_CONTEXT, 1); + env->slots[SOCKET_WRONG_CONTEXT].contextId = SOCKET_WRONG_CONTEXT; + + env->socketIO.env = env; + env->socketIO.open = (void *) Gsm_Socket_SSL_open; + env->socketIO.send = (void *) Gsm_Socket_SSL_send; + env->socketIO.read = (void *) Gsm_Socket_SSL_read; + env->socketIO.close = (void *) Gsm_Socket_SSL_close; + env->socketIO.status = (void *) Gsm_Socket_SSL_status; +} \ No newline at end of file diff --git a/Gsm_SSL_SockInt.h b/Gsm_SSL_SockInt.h new file mode 100644 index 0000000..20ce272 --- /dev/null +++ b/Gsm_SSL_SockInt.h @@ -0,0 +1,27 @@ +// +// Created by cfif on 24.05.2024. +// + +#ifndef SMART_COMPONENTS_GSM_SSL_SOCKINT_H +#define SMART_COMPONENTS_GSM_SSL_SOCKINT_H + +#include "GsmWithGnss.h" + +void Gsm_Socket_SSL_close(tGsmWithGnss *env, uint8_t contextId); + +uint8_t Gsm_Socket_SSL_open(tGsmWithGnss *env, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port, uint32_t timeout); + +size_t Gsm_Socket_SSL_read(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +size_t Gsm_Socket_SSL_send(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +eSocketStatus Gsm_Socket_SSL_status(tGsmWithGnss *env, uint8_t contextId); + +void GsmSocketSlot_SSL_Init(tGsmSocketSlot *slot, uint16_t bufLen); +void GsmSocketSlot_SSL_Set(tGsmSocketSlot *slot, eSocketType type, char *addr, size_t addrSize, uint16_t port); +void GsmSocketSlot_SSL_Clear(tGsmSocketSlot *slot); +bool GsmSocketSlot_SSL_IsClear(tGsmSocketSlot *slot); +void Gsm_SSL_InitSocket(tGsmWithGnss *env,uint16_t bufSize); +void Gsm_InitIO(tGsmWithGnss *env); + +#endif //SMART_COMPONENTS_GSM_SSL_SOCKINT_H diff --git a/Gsm_Serial.c b/Gsm_Serial.c new file mode 100644 index 0000000..db54791 --- /dev/null +++ b/Gsm_Serial.c @@ -0,0 +1,20 @@ +// +// Created by cfif on 05.07.23. +// +#include "GsmWithGnss.h" + +static uint16_t Gsm_SrvSerialPortReceive(tGsmWithGnss *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return SocketInterface_read(&env->socketIO, 0, data, size, timeout); +} + + +static uint16_t Gsm_SrvSerialPortTransmit(tGsmWithGnss *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return SocketInterface_send(&env->socketIO, 0, data, size, timeout); +} + +void Gsm_InitIO(tGsmWithGnss *env) { + env->srvIo.env = env; + env->srvIo.receive = (void *) Gsm_SrvSerialPortReceive; + env->srvIo.transmit = (void *) Gsm_SrvSerialPortTransmit; +} + diff --git a/Gsm_SockInt.c b/Gsm_SockInt.c new file mode 100644 index 0000000..44e3c60 --- /dev/null +++ b/Gsm_SockInt.c @@ -0,0 +1,23 @@ +// +// Created by cfif on 05.07.23. +// + +#include "Gsm_SockInt.h" + +void Gsm_InitSocket(tGsmWithGnss *env) { + + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + GsmSocketSlot_Init(env->slots + i, 2048); + env->slots[i].contextId = i; + } + + GsmSocketSlot_Init(env->slots + SOCKET_WRONG_CONTEXT, 1); + env->slots[SOCKET_WRONG_CONTEXT].contextId = SOCKET_WRONG_CONTEXT; + + env->socketIO.env = env; + env->socketIO.open = (void *) Gsm_Socket_open; + env->socketIO.send = (void *) Gsm_Socket_send; + env->socketIO.read = (void *) Gsm_Socket_read; + env->socketIO.close = (void *) Gsm_Socket_close; + env->socketIO.status = (void *) Gsm_Socket_status; +} \ No newline at end of file diff --git a/Gsm_SockInt.h b/Gsm_SockInt.h new file mode 100644 index 0000000..e278435 --- /dev/null +++ b/Gsm_SockInt.h @@ -0,0 +1,27 @@ +// +// Created by cfif on 05.07.23. +// + +#ifndef SMART_COMPONENTS_GSM_SOCKINT_H +#define SMART_COMPONENTS_GSM_SOCKINT_H + +#include "GsmWithGnss.h" + +void Gsm_Socket_close(tGsmWithGnss *env, uint8_t contextId); + +uint8_t Gsm_Socket_open(tGsmWithGnss *env, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port, uint32_t timeout); + +size_t Gsm_Socket_read(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +size_t Gsm_Socket_send(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +eSocketStatus Gsm_Socket_status(tGsmWithGnss *env, uint8_t contextId); + +void GsmSocketSlot_Init(tGsmSocketSlot *slot, uint32_t bufLen); +void GsmSocketSlot_Set(tGsmSocketSlot *slot, eSocketType type, char *addr, size_t addrSize, uint16_t port); +void GsmSocketSlot_Clear(tGsmSocketSlot *slot); +bool GsmSocketSlot_IsClear(tGsmSocketSlot *slot); +void Gsm_InitSocket(tGsmWithGnss *env); +void Gsm_InitIO(tGsmWithGnss *env); + +#endif //SMART_COMPONENTS_GSM_SOCKINT_H diff --git a/Gsm_SockInt_Open.c b/Gsm_SockInt_Open.c new file mode 100644 index 0000000..e72c6c0 --- /dev/null +++ b/Gsm_SockInt_Open.c @@ -0,0 +1,90 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "GsmWithGnss.h" +#include "AtGsmSimComA7600.h" +#include "Gsm_SockInt.h" + +#define LOG_SIGN "GSM SOCK" +#define LOGGER &env->slog->logger + +tGsmSocketSlot *Gsm_getFreeSlot(tGsmWithGnss *env) { + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + if (GsmSocketSlot_IsClear(env->slots + i)) { + return env->slots + i; + } + } + return NULL; +} + +static bool Gsm_StayConnected_socket( + tGsmWithGnss *env, uint8_t idx, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port +) { + bool connected = false; + AtGsmSimComA7600_HasConnection(env->gsmAt, idx, &connected); + if (connected) { + return true; + } else { + if (AtGsmSimComA7600_HasIp(env->gsmAt) != AT_OK) { + AtGsmSimComA7600_StartSocketService(env->gsmAt); + } + return AtGsmSimComA7600_EstablishConnection( + env->gsmAt, + idx, + type == eSocketType_TCP ? eAtGsmSimComA7600_IpType_TCP : eAtGsmSimComA7600_IpType_UDP, + addr, + addrSize, + port, + type == eSocketType_TCP ? 0 : port +// "193.232.47.4", 30197 + ) == AT_OK; + } +} + +uint8_t Gsm_Socket_open(tGsmWithGnss *env, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port, uint32_t timeout) { + uint8_t res = SOCKET_WRONG_CONTEXT; + + if (osMutexAcquire(env->gsmAt->access, timeout) == osOK) { + tGsmSocketSlot *slot = Gsm_getFreeSlot(env); + if (slot) { + if (Gsm_StayConnected_socket(env, slot->contextId, type, clientType, addr, addrSize, port)) { + GsmSocketSlot_Set(slot, type, addr, addrSize, port); + res = slot->contextId; + } else { + res = SOCKET_WRONG_CONTEXT; + } + } + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_open)") + } + return res; +} + +void Gsm_Socket_close(tGsmWithGnss *env, uint8_t contextId) { + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + if (contextId != SOCKET_WRONG_CONTEXT) { + AtGsmSimComA7600_CloseConnection(env->gsmAt, contextId); + GsmSocketSlot_Clear(env->slots + contextId); + } else { + asm("nop"); + } + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_close)") + } +} + + +eSocketStatus Gsm_Socket_status(tGsmWithGnss *env, uint8_t contextId) { + bool connected = false; + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + AtGsmSimComA7600_HasConnection(env->gsmAt, contextId, &connected); + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_status)") + } + + return connected ? eSocketStatus_Connected : eSocketStatus_Disconnected; +} diff --git a/Gsm_SockInt_Read.c b/Gsm_SockInt_Read.c new file mode 100644 index 0000000..248db93 --- /dev/null +++ b/Gsm_SockInt_Read.c @@ -0,0 +1,45 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "GsmWithGnss.h" + + +static uint16_t vSerialPortReceiveQueue(osMessageQueueId_t queueId, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t received = 0; + if (timeout) { + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + leftMs = endMs - SystemGetMs(); + if (osMessageQueueGet(queueId, data, NULL, leftMs) == osOK) { + --size; + ++received; + ++data; + } + } + + } else { + while (size) { + if (osMessageQueueGet(queueId, data, NULL, 0) == osOK) { + --size; + ++received; + ++data; + } else { + return received; + } + } + } + + return received; +} + + +size_t Gsm_Socket_read(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout) { + if (contextId == 255) + return 0; + + size_t len = vSerialPortReceiveQueue(env->slots[contextId].rxDataQueue, data, size, timeout); + return len; +} diff --git a/Gsm_SockInt_SSL_Open.c b/Gsm_SockInt_SSL_Open.c new file mode 100644 index 0000000..f262dc5 --- /dev/null +++ b/Gsm_SockInt_SSL_Open.c @@ -0,0 +1,109 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "GsmWithGnss.h" +#include "AtGsmSimComA7600.h" +#include "Gsm_SockInt.h" +#include "Gsm_SockInt.h" + +#define LOG_SIGN "GSM SSL" +#define LOGGER &env->slog->logger + +tGsmSocketSlot *Gsm_SSL_getFreeSlot(tGsmWithGnss *env) { + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + if (GsmSocketSlot_IsClear(env->slots + i)) { + return env->slots + i; + } + } + return NULL; +} + +static bool Gsm_StayConnected_SSL_socket( + tGsmWithGnss *env, uint8_t idx, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port +) { + bool connected = false; + AtCommandResult result = AtGsmSimComA7600_SSL_HasConnection(env->gsmAt, idx, &connected); + + if (result != AT_OK) { + result = AtGsmSimComA7600_SSL_HasConnection(env->gsmAt, idx, &connected); + } + + if (connected) { + return true; + } else { +// if (AtGsmSimComA7600_SSL_HasIp(&env->gsmAt) != AT_OK) { + AtGsmSimComA7600_SSL_StartSocketService(env->gsmAt); + AtGsmSimComA7600_SSL_SetContext(env->gsmAt, idx, 2); +// } + + env->codeResultOpen = 0; + + AtCommandResult resultOpen = AtGsmSimComA7600_SSL_EstablishConnection( + env->gsmAt, + idx, + addr, + addrSize, + port, + clientType, + &env->codeResultOpen + //eAtGsmSimComA7600_SslType_TCP + // eAtGsmSimComA7600_SslType_TLS + ) == AT_OK; + + + return resultOpen; + } +} + +uint8_t Gsm_Socket_SSL_open(tGsmWithGnss *env, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port, uint32_t timeout) { + uint8_t res = SOCKET_WRONG_CONTEXT; + + if (osMutexAcquire(env->gsmAt->access, timeout) == osOK) { + tGsmSocketSlot *slot = Gsm_SSL_getFreeSlot(env); + if (slot) { + if (Gsm_StayConnected_SSL_socket(env, slot->contextId, type, clientType, addr, addrSize, port)) { + GsmSocketSlot_Set(slot, type, addr, addrSize, port); + res = slot->contextId; + } else { + res = SOCKET_WRONG_CONTEXT; + } + } + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_SSL_open)") + } + return res; +} + +void Gsm_Socket_SSL_close(tGsmWithGnss *env, uint8_t contextId) { + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + if ((contextId != SOCKET_WRONG_CONTEXT) /*&& (contextId != 0)*/) { + AtGsmSimComA7600_SSL_CloseConnection(env->gsmAt, contextId); + GsmSocketSlot_Clear(env->slots + contextId); + } else { + asm("nop"); + } + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_SSL_close)") + } +} + + +eSocketStatus Gsm_Socket_SSL_status(tGsmWithGnss *env, uint8_t contextId) { + bool connected = false; + if (osMutexAcquire(env->gsmAt->access, defaultSocketTimeout) == osOK) { + AtCommandResult result = AtGsmSimComA7600_SSL_HasConnection(env->gsmAt, contextId, &connected); + + if (result != AT_OK) { + result = AtGsmSimComA7600_SSL_HasConnection(env->gsmAt, contextId, &connected); + } + + osMutexRelease(env->gsmAt->access); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_Socket_SSL_status)") + } + + return connected ? eSocketStatus_Connected : eSocketStatus_Disconnected; +} diff --git a/Gsm_SockInt_SSL_Read.c b/Gsm_SockInt_SSL_Read.c new file mode 100644 index 0000000..8480c47 --- /dev/null +++ b/Gsm_SockInt_SSL_Read.c @@ -0,0 +1,44 @@ +// +// Created by cfif on 24.05.2024. +// +#include +#include "GsmWithGnss.h" + +static uint16_t vSerialPortReceiveQueue(osMessageQueueId_t queueId, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t received = 0; + if (timeout) { + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + leftMs = endMs - SystemGetMs(); + if (osMessageQueueGet(queueId, data, NULL, leftMs) == osOK) { + --size; + ++received; + ++data; + } + } + + } else { + while (size) { + if (osMessageQueueGet(queueId, data, NULL, 0) == osOK) { + --size; + ++received; + ++data; + } else { + return received; + } + } + } + + return received; +} + + +size_t Gsm_Socket_SSL_read(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout) { + if (contextId == 255) + return 0; + + size_t len = vSerialPortReceiveQueue(env->slots[contextId].rxDataQueue, data, size, timeout); + return len; +} diff --git a/Gsm_SockInt_SSL_Write.c b/Gsm_SockInt_SSL_Write.c new file mode 100644 index 0000000..1a89d6f --- /dev/null +++ b/Gsm_SockInt_SSL_Write.c @@ -0,0 +1,72 @@ +// +// Created by cfif on 24.05.2024. +// +#include "GsmWithGnss.h" +#include "AtGsmSimComA7600.h" + + +#define LOG_SIGN "GSM SOCK" +#define LOGGER &env->slog->logger + +static uint16_t +Gsm_SrvSerialPortTransmit_SSL_Dir( + tGsmWithGnss *env, + tGsmSocketSlot *slot, + uint8_t *data, + uint16_t size, + uint32_t timeout +) { + + if (AtGsmSimComA7600_SSL_SocketSendData(env->gsmAt, slot->contextId, data, size, timeout) == AT_OK) { + return size; + } + + return 0; +} + +/* +static uint16_t Gsm_transmit(tGsm *env, uint8_t contextId, uint8_t *data, uint16_t size, uint32_t timeout) { + if (!size) { + return 0; + } + + uint32_t end = SystemGetMs() + timeout; + if (osMutexAcquire(env->deviceAccess, timeout) == osOK) { + uint32_t sendTimeout = timeout == SystemWaitForever ? 10 * 1000 : end - SystemGetMs(); + + uint16_t res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, sendTimeout); + + osMutexRelease(env->deviceAccess); + return res; + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_transmit)") + return 0; + } + +} + */ + +static uint16_t Gsm_SSL_transmit(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, uint16_t size, uint32_t timeout) { + if (!size) { + return 0; + } + +// uint32_t end = SystemGetMs() + timeout; + if (osMutexAcquire(env->gsmAt->access, timeout) == osOK) { +// uint32_t sendTimeout = timeout == SystemWaitForever ? 2000 : end - SystemGetMs(); + + uint16_t res = Gsm_SrvSerialPortTransmit_SSL_Dir(env, env->slots + contextId, data, size, timeout); + + osMutexRelease(env->gsmAt->access); + return res; + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_transmit)") + return 0; + } + +} + + +size_t Gsm_Socket_SSL_send(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout) { + return Gsm_SSL_transmit(env, contextId, data, size, timeout); +} diff --git a/Gsm_SockInt_Write.c b/Gsm_SockInt_Write.c new file mode 100644 index 0000000..a02c349 --- /dev/null +++ b/Gsm_SockInt_Write.c @@ -0,0 +1,88 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "GsmWithGnss.h" +#include "AtGsmSimComA7600.h" + + +#define LOG_SIGN "GSM SOCK" +#define LOGGER &env->slog->logger + +static uint16_t +Gsm_SrvSerialPortTransmit_Dir( + tGsmWithGnss *env, + tGsmSocketSlot *slot, + uint8_t *data, + uint16_t size, + uint32_t timeout +) { + + if (slot->type == eSocketType_TCP) { + if (AtGsmSimComA7600_SocketSendData(env->gsmAt, slot->contextId, data, size, timeout) == AT_OK) { + return size; + } + } else if (slot->type == eSocketType_UDP) { + if (AtGsmSimComA7600_SocketSendDataUdp( + env->gsmAt, + slot->contextId, + data, + size, + slot->addr.data, + slot->addr.length, + slot->port, + timeout + ) == AT_OK) { + return size; + } + } + + return 0; +} + +/* +static uint16_t Gsm_transmit(tGsm *env, uint8_t contextId, uint8_t *data, uint16_t size, uint32_t timeout) { + if (!size) { + return 0; + } + + uint32_t end = SystemGetMs() + timeout; + if (osMutexAcquire(env->deviceAccess, timeout) == osOK) { + uint32_t sendTimeout = timeout == SystemWaitForever ? 10 * 1000 : end - SystemGetMs(); + + uint16_t res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, sendTimeout); + + osMutexRelease(env->deviceAccess); + return res; + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_transmit)") + return 0; + } + +} + */ + +static uint16_t Gsm_transmit(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, uint16_t size, uint32_t timeout) { + if (!size) { + return 0; + } + +// uint32_t end = SystemGetMs() + timeout; + if (osMutexAcquire(env->gsmAt->access, timeout) == osOK) { +// uint32_t sendTimeout = timeout == SystemWaitForever ? 2000 : end - SystemGetMs(); + + uint16_t res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, timeout); + + osMutexRelease(env->gsmAt->access); + return res; + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа (Gsm_transmit)") + return 0; + } + +} + + +size_t Gsm_Socket_send(tGsmWithGnss *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout) { + return Gsm_transmit(env, contextId, data, size, timeout); +} diff --git a/SocketInterface.h b/SocketInterface.h new file mode 100644 index 0000000..5cab1c4 --- /dev/null +++ b/SocketInterface.h @@ -0,0 +1,49 @@ +// +// Created by cfif on 21.05.23. +// + +#ifndef SMART_COMPONENTS_SOCKETINTERFACE_H +#define SMART_COMPONENTS_SOCKETINTERFACE_H + +#include "stdint.h" +#include "stddef.h" +#include "stdbool.h" +#include "AtGsmSimComSSLType.h" + +typedef enum { + eSocketType_UDP, + eSocketType_TCP, +} eSocketType; + +typedef enum { + eSocketStatus_Connected, + eSocketStatus_Disconnected, +} eSocketStatus; + +typedef struct { + + void *env; + + uint8_t (*open)(void *env, eSocketType type, eAtGsmSimComA7600_SSL_Type clientType, char *addr, size_t addrSize, uint16_t port, uint32_t timeout); + + size_t (*send)(void *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + + size_t (*read)(void *env, uint8_t contextId, uint8_t *data, size_t sizeLimit, uint32_t timeout); + + eSocketStatus (*status)(void *env, uint8_t contextId); + + void (*close)(void *env, uint8_t contextId); + +} tSocketInterface; + +#define SOCKET_WRONG_CONTEXT 0xFF + +#define SocketInterface_open(ENV, TYPE, CLIENT_TYPE, ADDR, ADDR_SIZE, PORT, TIMEOUT) (ENV)->open((ENV)->env,TYPE, CLIENT_TYPE, ADDR, ADDR_SIZE, PORT, TIMEOUT) +#define SocketInterface_send(ENV, ID, DATA, SIZE, TIMEOUT) (ENV)->send((ENV)->env, ID, DATA, SIZE, TIMEOUT) +#define SocketInterface_read(ENV, ID, DATA, SIZE, TIMEOUT) (ENV)->read((ENV)->env, ID, DATA, SIZE, TIMEOUT) +#define SocketInterface_status(ENV, ID) (ENV)->status((ENV)->env, ID) + +#define SocketInterface_openStatic(ENV, TYPE, ADDR, PORT, TIMEOUT) SocketInterface_open(ENV,TYPE, ADDR, sizeof(ADDR)-1 , PORT, TIMEOUT) +#define SocketInterface_close(ENV, ID) (ENV)->close((ENV)->env, ID) + +#endif //SMART_COMPONENTS_SOCKETINTERFACE_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..0f78556 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "*.c" + ] + } +} \ No newline at end of file