This commit is contained in:
cfif 2024-12-04 13:10:47 +03:00
commit ef6021a20d
11 changed files with 605 additions and 0 deletions

27
GsmSocketSlot.c Executable file
View File

@ -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;
}

25
Gsm_Serial.c Executable file
View File

@ -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;
}

24
Gsm_SockInt.c Executable file
View File

@ -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;
}

32
Gsm_SockInt.h Executable file
View File

@ -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

167
Gsm_SockInt_Open.c Executable file
View File

@ -0,0 +1,167 @@
//
// Created by cfif on 05.07.23.
//
#include <SystemDelayInterface.h>
#include <Gsm_SockInt.h>
#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;
}
*/

45
Gsm_SockInt_Read.c Executable file
View File

@ -0,0 +1,45 @@
//
// Created by cfif on 05.07.23.
//
#include <SystemDelayInterface.h>
#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;
}

76
Gsm_SockInt_Write.c Executable file
View File

@ -0,0 +1,76 @@
//
// Created by cfif on 05.07.23.
//
#include <SystemDelayInterface.h>
#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);
}

48
SocketInterface.h Executable file
View File

@ -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

88
SocketSerialPort_Telit.c Normal file
View File

@ -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 <CmsisRtosThreadUtils.h>
#include <stdlib.h>
#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);
}

63
SocketSerialPort_Telit.h Normal file
View File

@ -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 <SocketInterface.h>
#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

10
modular.json Normal file
View File

@ -0,0 +1,10 @@
{
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c"
]
}
}