commit ef6021a20dbc4d4ff7f4ab80eeb1f21b8272508d Author: cfif Date: Wed Dec 4 13:10:47 2024 +0300 Init diff --git a/GsmSocketSlot.c b/GsmSocketSlot.c new file mode 100755 index 0000000..5438d15 --- /dev/null +++ b/GsmSocketSlot.c @@ -0,0 +1,27 @@ +// +// Created by cfif on 05.07.23. +// + +#include "memory.h" +#include "SocketSerialPort_Telit.h" + +void GsmSocketSlot_Init(tGsmSocketSlot *slot, uint16_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/Gsm_Serial.c b/Gsm_Serial.c new file mode 100755 index 0000000..f6ee23a --- /dev/null +++ b/Gsm_Serial.c @@ -0,0 +1,25 @@ +// +// Created by cfif on 05.07.23. +// +#include "SocketInterface.h" +#include "SocketSerialPort_Telit.h" + +static uint16_t Gsm_SrvSerialPortReceive(tSocketGsm *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return SocketInterface_read(&env->socketIO, 1, data, size, timeout); +} + + +static uint16_t Gsm_SrvSerialPortTransmit(tSocketGsm *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return SocketInterface_send(&env->socketIO, 1, data, size, timeout); +} + +tSerialPortIO GsmSocket_InitIO(tSocketGsm *env) { + tSerialPortIO io = { + .env = env, + .receive = (SerialPortIOTransaction) Gsm_SrvSerialPortReceive, + .transmit = (SerialPortIOTransaction) Gsm_SrvSerialPortTransmit + }; + + return io; +} + diff --git a/Gsm_SockInt.c b/Gsm_SockInt.c new file mode 100755 index 0000000..95007fd --- /dev/null +++ b/Gsm_SockInt.c @@ -0,0 +1,24 @@ +// +// Created by xemon on 05.07.23. +// + +#include "Gsm_SockInt.h" + +void Gsm_InitSocket(tSocketGsm *env) { + + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + GsmSocketSlot_Init(env->slots + i, 1500); + 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 100755 index 0000000..0a3b05d --- /dev/null +++ b/Gsm_SockInt.h @@ -0,0 +1,32 @@ +// +// Created by cfif on 05.07.23. +// + +#ifndef SOCKET_TELIT_INT_H +#define SOCKET_TELIT_INT_H + +#include "SocketSerialPort_Telit.h" + +void GsmSocketSlot_Init(tGsmSocketSlot *slot, uint16_t bufLen); + +void Gsm_InitSocket(tSocketGsm *env); + +tSerialPortIO GsmSocket_InitIO(tSocketGsm *env); + +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_Socket_close(tSocketGsm *env, uint8_t contextId); + +uint8_t Gsm_Socket_open(tSocketGsm *env, eSocketType type, char *addr, size_t addrSize, uint16_t port, uint32_t timeout); + +size_t Gsm_Socket_read(tSocketGsm *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +size_t Gsm_Socket_send(tSocketGsm *env, uint8_t contextId, uint8_t *data, size_t size, uint32_t timeout); + +eSocketStatus Gsm_Socket_status(tSocketGsm *env, uint8_t contextId); + +#endif //SOCKET_TELIT_INT_H diff --git a/Gsm_SockInt_Open.c b/Gsm_SockInt_Open.c new file mode 100755 index 0000000..74d808b --- /dev/null +++ b/Gsm_SockInt_Open.c @@ -0,0 +1,167 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include +#include "SocketInterface.h" +#include "SocketSerialPort_Telit.h" +#include "AtGsmTelitLe910_Socket.h" + +#define LOG_SIGN "GSM SOCK" +#define LOGGER &env->slog->logger + +tGsmSocketSlot *Gsm_getFreeSlot(tSocketGsm *env) { + for (uint8_t i = 1; i < GSM_SLOTS_COUNT; ++i) { + if (GsmSocketSlot_IsClear(env->slots + i)) { + return env->slots + i; + } + } + return NULL; +} + +static bool Gsm_Configuration_socket( + tSocketGsm *env, + uint8_t cid, + uint8_t idx, + uint16_t pktSz, + uint16_t inactivityTimeout, + uint16_t connectionTimeout, + uint16_t sendingTimeout +) { + +} + +static bool Gsm_StayConnected_socket( + tSocketGsm *env, uint8_t idx, eSocketType type, char *addr, size_t addrSize, uint16_t port +) { + bool connected = false; + AtGsmTelitLe910_HasConnection(env->gsmAt, idx, &connected); + if (connected) { + return true; + } else { +// if (AtGsmSimComA7600_HasIp(&env->gsmAt) != AT_OK) { +// AtGsmSimComA7600_StartSocketService(&env->gsmAt); +// } + + return AtGsmTelitLe910_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; + } +} + +/* +static bool Gsm_StayConnected_socket( + tGsm *env, uint8_t idx, eSocketType type, 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(tSocketGsm *env, eSocketType type, char *addr, size_t addrSize, uint16_t port, uint32_t timeout) { + uint8_t res = SOCKET_WRONG_CONTEXT; + + if (osMutexAcquire(env->access, timeout) == osOK) { + tGsmSocketSlot *slot = Gsm_getFreeSlot(env); + if (slot) { + if (Gsm_StayConnected_socket(env, slot->contextId, type, addr, addrSize, port)) { + GsmSocketSlot_Set(slot, type, addr, addrSize, port); + res = slot->contextId; + } else { + res = SOCKET_WRONG_CONTEXT; + } + } + + osMutexRelease(env->access); + } else { + LoggerInfoStatic(env->logger, env->loggerTaskName, "Ошибка доступа (Gsm_Socket_open)") + } + + +// AtCmd_RunSafe(&env->gsmAt, timeout, { +// tGsmSocketSlot *slot = Gsm_getFreeSlot(env); +// if (slot) { +// if (Gsm_StayConnected_socket(env, slot->contextId, type, addr, addrSize, port)) { +// GsmSocketSlot_Set(slot, type, addr, addrSize, port); +// res = slot->contextId; +// } else { +// res = SOCKET_WRONG_CONTEXT; +// } +// } +// }) + + return res; +} + +void Gsm_Socket_close(tSocketGsm *env, uint8_t contextId) { + + if (osMutexAcquire(env->access, 2000) == osOK) { + if (contextId != SOCKET_WRONG_CONTEXT) { + AtGsmTelitLe910_CloseConnection(env->gsmAt, contextId); + GsmSocketSlot_Clear(env->slots + contextId); + } else { + asm("nop"); + } + osMutexRelease(env->access); + } else { + LoggerInfoStatic(env->logger, env->loggerTaskName, "Ошибка доступа (Gsm_Socket_close)") + } + +// AtCmd_RunSafe(&env->gsmAt, 2000, { +// AtGsmTelitLe910_CloseConnection(&env->gsmAt, contextId); +// GsmSocketSlot_Clear(env->slots + contextId); +// }); + +} + + +eSocketStatus Gsm_Socket_status(tSocketGsm *env, uint8_t contextId) { + bool connected = false; + + if (osMutexAcquire(env->access, 2000) == osOK) { + AtGsmTelitLe910_HasConnection(env->gsmAt, contextId, &connected); + osMutexRelease(env->access); + } else { + LoggerInfoStatic(env->logger, env->loggerTaskName, "Ошибка доступа (Gsm_Socket_status)") + } + +// AtCmd_RunSafe(&env->gsmAt, 2000, { +// AtGsmTelitLe910_HasConnection(&env->gsmAt, contextId, &connected); +// }); + return connected ? eSocketStatus_Connected : eSocketStatus_Disconnected; +} +/* +eSocketStatus Gsm_Socket_status(tGsm *env, uint8_t contextId) { + bool connected = false; + if (osMutexAcquire(env->deviceAccess, 2000) == osOK) { + AtGsmSimComA7600_HasConnection(&env->gsmAt, contextId, &connected); + osMutexRelease(env->deviceAccess); + } + return connected ? eSocketStatus_Connected : eSocketStatus_Disconnected; +} +*/ diff --git a/Gsm_SockInt_Read.c b/Gsm_SockInt_Read.c new file mode 100755 index 0000000..aa0b6d0 --- /dev/null +++ b/Gsm_SockInt_Read.c @@ -0,0 +1,45 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "SocketSerialPort_Telit.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(tSocketGsm *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_Write.c b/Gsm_SockInt_Write.c new file mode 100755 index 0000000..b9e92f3 --- /dev/null +++ b/Gsm_SockInt_Write.c @@ -0,0 +1,76 @@ +// +// Created by cfif on 05.07.23. +// +#include +#include "SocketSerialPort_Telit.h" +#include "AtGsmTelitLe910_SocketSendData.h" + +static uint16_t +Gsm_SrvSerialPortTransmit_Dir( + tSocketGsm *env, + tGsmSocketSlot *slot, + uint8_t *data, + uint16_t size, + uint32_t timeout +) { + + if (slot->type == eSocketType_TCP) { + if (AtGsmTelitLe910_SocketSendData(env->gsmAt, slot->contextId, data, size, timeout) == AT_OK) { + return size; + } + } else if (slot->type == eSocketType_UDP) { + if (AtGsmTelitLe910_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(tSocketGsm *env, uint8_t contextId, uint8_t *data, uint16_t size, uint32_t timeout) { + if (!size) { + return 0; + } +/* + uint32_t end = SystemGetMs() + timeout; + uint16_t res = 0; + + + uint32_t sendTimeout = timeout == SystemWaitForever ? 10 * 1000 : end - SystemGetMs(); + + if (osMutexAcquire(env->access, sendTimeout) == osOK) { + res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, sendTimeout); + osMutexRelease(env->access); + } +*/ + uint16_t res = 0; + + if (osMutexAcquire(env->access, timeout) == osOK) { + res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, timeout); + osMutexRelease(env->access); + } else { + LoggerInfoStatic(env->logger, env->loggerTaskName, "Ошибка доступа (Gsm_transmit)") + } + + +// AtCmd_RunSafe(&env->gsmAt, timeout, { +// uint32_t sendTimeout = timeout == SystemWaitForever ? 10 * 1000 : end - SystemGetMs(); +// res = Gsm_SrvSerialPortTransmit_Dir(env, env->slots + contextId, data, size, sendTimeout); +// }); + + return res; +} + +size_t Gsm_Socket_send(tSocketGsm *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 100755 index 0000000..a98f31d --- /dev/null +++ b/SocketInterface.h @@ -0,0 +1,48 @@ +// +// Created by cfif on 21.05.23. +// + +#ifndef SOCKET_TELIT_INTERFACE_H +#define SOCKET_TELIT_INTERFACE_H + +#include "stdint.h" +#include "stddef.h" +#include "stdbool.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, 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, ADDR, ADDR_SIZE, PORT, TIMEOUT) (ENV)->open((ENV)->env,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, strlen(ADDR), PORT, TIMEOUT) +#define SocketInterface_close(ENV, ID) (ENV)->close((ENV)->env, ID) + +#endif //SOCKET_TELIT_INTERFACE_H diff --git a/SocketSerialPort_Telit.c b/SocketSerialPort_Telit.c new file mode 100644 index 0000000..9c8c23c --- /dev/null +++ b/SocketSerialPort_Telit.c @@ -0,0 +1,88 @@ +// +// Created by cfif on 20.03.2024. +// +#include "SocketSerialPort_Telit.h" +#include "AtCmdCommonProtected.h" +#include "AtGsmTelitLe910_Socket.h" +#include "AtGsmTelitLe910_SocketReadData.h" +#include +#include +#include "string.h" +#include "SystemDelayInterface.h" +#include "Gsm_SockInt.h" +#include "AtGsmOperatorSelection.h" +#include "AtGsm_NetworkRegistrationStatus.h" + +#define STRSZ(STR) STR,(sizeof(STR)-1) + +//const char APN[] = "internet.tele2.ru"; +//const char APN[] = "internet.mts.ru"; + + + +static void rxGsm(tAtCmd *env, osMessageQueueId_t rxDataQueue, uint8_t id) { +/* + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SRECV="); + AtCmdTxAddDecimalIntWithLimit(env, id, 1); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, 1500, 4); + AtCmdTxSendLn(env); +*/ + uint8_t dataRead[1500]; + uint32_t len; + + xAtGsmTelit_ReadSocket(env, id, dataRead, sizeof(dataRead), &len); + + for (uint32_t i = 0; i < len; ++i) { + osMessageQueuePut(rxDataQueue, &dataRead[i], 0x0, 0U); + } +} + +void SocketSocketGsm_UrcProcessor_SRING(tSocketGsm *env, tAtBuffer *buff) { + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + tGsmSocketSlot *slot = &env->slots[i];//env->slots + i; + + char pattern[3]; + pattern[0] = 0; + pattern[1] = 0; + pattern[2] = 0; + + utoa(slot->contextId, pattern, 10); + + if (!GsmSocketSlot_IsClear(slot)) { + char id = buff->data[sizeof("SRING: ") - 1]; + if (id == pattern[0]) { + rxGsm(env->gsmAt, slot->rxDataQueue, slot->contextId); + return; + } + } + } +} + +void SocketSocketGsm_UrcProcessor_NO_CARRIER(tSocketGsm *env, tAtBuffer *buff) { + for (uint8_t i = 0; i < GSM_SLOTS_COUNT; ++i) { + tGsmSocketSlot *slot = &env->slots[i];//env->slots + i; + + if (!GsmSocketSlot_IsClear(slot)) { + SocketInterface_close(&env->socketIO, 0); + } + } + +} + +void SocketSocketGsm_Init(tSocketGsm *env, tAtCmd *gsmAt, tString32 *ipServ, uint16_t portServ, osMutexId_t access) { + + env->gsmAt = gsmAt; + env->access = access; + + memset(env->ipServ, 0, sizeof(env->ipServ)); + memcpy(env->ipServ, ipServ->data, ipServ->length); + + env->portServ = portServ; + + Gsm_InitSocket(env); + +} + + diff --git a/SocketSerialPort_Telit.h b/SocketSerialPort_Telit.h new file mode 100644 index 0000000..cec928d --- /dev/null +++ b/SocketSerialPort_Telit.h @@ -0,0 +1,63 @@ +// +// Created by cfif on 20.03.2024. +// + +#ifndef WATER_BLACKBOX2_BSD_SOCKETSERIALPORT_TELIT_H +#define WATER_BLACKBOX2_BSD_SOCKETSERIALPORT_TELIT_H + +#include "AtCmdCommonProtected.h" +#include +#include "BaseTypes.h" +#include "LoggerInterface.h" +#include "SystemMutexInterface.h" +#include "FreeRTOS.h" + +#define GSM_SLOTS_COUNT 2 + +typedef struct { + uint8_t contextId; + tString32 addr; + uint16_t port; + tString16 portStr; + osMessageQueueId_t rxDataQueue; + eSocketType type; +} tGsmSocketSlot; +/* +typedef struct { + char ipServ[64]; + uint16_t portServ; + + tAtCmd *gsmAt; + osMutexId_t access; + + tGsmSocketSlot slots[GSM_SLOTS_COUNT]; + tSocketInterface socketIO; + tSerialPortIO srvIo; +} tSocketGsm; +*/ + +typedef struct { + + tAtCmd *gsmAt; + + osMutexId_t access; + + tLoggerInterface *logger; + char *loggerTaskName; + + tGsmSocketSlot slots[256]; + tSocketInterface socketIO; + tSerialPortIO srvIo; + + char ipServ[64]; + uint16_t portServ; + +} tSocketGsm; + +void SocketSocketGsm_Init(tSocketGsm *env, tAtCmd *gsmAt, tString32 *ipServ, uint16_t portServ, osMutexId_t access); +void Main_SocketGsm_StartThread(tSocketGsm *env); +void Main_SocketGsmUrc_StartThread(tSocketGsm *env); +void SocketSocketGsm_UrcProcessor_SRING(tSocketGsm *env, tAtBuffer *buff); +void SocketSocketGsm_UrcProcessor_NO_CARRIER(tSocketGsm *env, tAtBuffer *buff); + +#endif //WATER_BLACKBOX2_BSD_SOCKETSERIALPORT_TELIT_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..0dd1901 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file