This commit is contained in:
cfif 2025-05-26 14:41:46 +03:00
commit 6f8d09077b
8 changed files with 448 additions and 0 deletions

48
Inc/AtCmdBase.h Normal file
View File

@ -0,0 +1,48 @@
//
// Created by xemon on 09.09.22.
//
#ifndef GSMAT_GSMATCOMMANDRESULT_H
#define GSMAT_GSMATCOMMANDRESULT_H
#include <SystemMutexInterface.h>
#include "SerialPort.h"
#include "stddef.h"
typedef enum {
AT_BUSY = -3,
AT_TIMEOUT = -2,
AT_NONE = -1,
AT_ERROR = 0,
AT_OK = 1,
} AtCommandResult;
typedef struct {
size_t len;
char *data;
size_t limit;
} tAtBuffer;
typedef struct {
void *env;
void (*process)(void *env, tAtBuffer *buffer);
} tAtCmdUrcProcessor;
#define AtCmdUrcProcessor_Process(ENV, BUFF) (ENV)->process((ENV)->env,BUFF)
typedef struct {
tSerialPortIO *io;
tAtBuffer txBuffer;
tAtBuffer rxBuffer;
uint32_t stdTxTimeout;
uint32_t stdRxTimeout;
tAtCmdUrcProcessor urcProcessor;
tSystemMutexInterface *access;
} tAtCmd;
#endif //GSMAT_GSMATCOMMANDRESULT_H

69
Inc/AtCmdCommon.h Normal file
View File

@ -0,0 +1,69 @@
//
// Created by xemon on 07.09.22.
//
#ifndef GSMCOMMONAT_GSMCOMMONAT_H
#define GSMCOMMONAT_GSMCOMMONAT_H
#include "stdint.h"
#include "stddef.h"
#include "SerialPort.h"
#include "AtCmdBase.h"
void AtCmdInit(
tAtCmd *env,
tSerialPortIO *io,
uint8_t *txBuffer,
size_t txBufferSize,
uint8_t *rxBuffer,
size_t rxBufferSize,
uint32_t stdTxTimeout,
uint32_t stdRxTimeout
);
AtCommandResult AtCmd(tAtCmd *env);
AtCommandResult AtCmdWaitOk(tAtCmd *env, uint32_t retryInterval, uint32_t timeout);
AtCommandResult AtCmdWaitPrefix(tAtCmd *env, uint16_t timeout, char *line, size_t lineLen);
AtCommandResult AtCmdWaitChar(tAtCmd *env, uint16_t timeout, char line);
#define AtCmdWaitPrefixStatic(ENV, TIMEOUT, STR) AtCmdWaitPrefix(ENV,TIMEOUT,STR, sizeof(STR)-1)
void AtCmdSetUrcProcessor(tAtCmd *env, void *urcProcEnv, void *urcProcFunc);
void AtCmdClearUrcProcessor(tAtCmd *env);
void AtCmdSetAccessMutex(tAtCmd *env, tSystemMutexInterface *accessMutex);
void AtCmdClearAccessMutex(tAtCmd *env);
void AtCmdProcessUnresolvedLine(tAtCmd *env);
void AtCmdProcessUnresolvedLines(tAtCmd *env);
//Тут все просто
//ENV - это наш tAtCmd*
//PAYLOAD - это код который будет безопасно выполнен
//TIMEOUT - время ожидания мьютекса, если оно пройдет то PAYLOAD не выполнится
//(таймаут внутри payload работает отдельно)
#define AtCmd_RunSafe(ENV, TIMEOUT, PAYLOAD) \
{ \
if((ENV)->access){ \
if (SystemMutex_acquire((ENV)->access, TIMEOUT) == true) { \
{PAYLOAD} \
SystemMutex_release((ENV)->access); \
}else{ \
\
} \
}else{ \
{PAYLOAD} \
} \
}
//#include "AtGsmListCurrentCalls.h"
#include "AtGsmErrorLogLevel.h"
#endif //GSMCOMMONAT_GSMCOMMONAT_H

View File

@ -0,0 +1,63 @@
//
// Created by xemon on 07.09.22.
//
#ifndef GSMCOMMONAT_GSMCOMMONATPRIVATE_H
#define GSMCOMMONAT_GSMCOMMONATPRIVATE_H
#include "AtCmdCommon.h"
#include "AsciiStringAssmeblingUtils.h"
void AtCmdPrepare(tAtCmd *env);
#define AtCmdSendStatic(env, STR) SerialPortTransmit((env)->io, (uint8_t *) (STR), sizeof (STR)-1, (env)->stdTxTimeout)
#define AtCmdSend(env, STR, LEN) SerialPortTransmit((env)->io, (uint8_t *) (STR), LEN, (env)->stdTxTimeout)
//tx buffer operations
#define AtCmdTxPrint(ENV, FMT, ...) debug_printf((ENV)->io, FMT, ##__VA_ARGS__);
#define AtCmdTxClear(env) vAsciiStringClean((env)->txBuffer.data, &(env)->txBuffer.len)
#define AtCmdTxAdd(env, STR, LEN) vAsciiStringAdd((env)->txBuffer.data, &(env)->txBuffer.len, STR,LEN)
#define AtCmdTxAddStatic(env, STR) vAsciiStringAddStatic((env)->txBuffer.data, &(env)->txBuffer.len, STR)
#define AtCmdTxAddByteHex(env, BYTE) vAsciiStringAddByteAsHex((env)->txBuffer.data, &(env)->txBuffer.len, BYTE)
#define AtCmdTxAddChar(env, CHAR) vAsciiStringAddChar((env)->txBuffer.data, &(env)->txBuffer.len, CHAR)
#define AtCmdTxAddDecimalInt(env, INT, DIGITS) vAsciiStringAddDecimalInt((env)->txBuffer.data, &(env)->txBuffer.len, INT,DIGITS)
#define AtCmdTxAddDecimalIntWithLimit(env, INT, DIGITS) vAsciiStringAddDecimalIntWithLimit((env)->txBuffer.data, &(env)->txBuffer.len, INT,DIGITS)
void AtCmdTxSendLn(tAtCmd *env);
//rx methods
#define AtCmdRxClear(env) vAsciiStringClean((env)->rxBuffer.data, &(env)->rxBuffer.len)
#define AtCmdRxReadRAW(ENV, BUF, LEN, TIMEOUT) SerialPortReceive((env)->io, BUF, LEN, TIMEOUT)
bool AtBufferBeginWith(tAtBuffer *env, char *str, size_t strLen);
#define AtBufferBeginWithStatic(ENV, STR) AtBufferBeginWith(ENV,STR,sizeof(STR)-1)
bool AtCmdRxBeginWith(tAtCmd *env, char *str, size_t strLen);
#define AtCmdRxBeginWithStatic(ENV, STR) AtCmdRxBeginWith(ENV,STR,sizeof(STR)-1)
bool AtCmdRxIsCompleteLine(tAtCmd *env);
//complex rx methods
AtCommandResult AtCmdReceiveNextLine(tAtCmd *env, uint16_t timeout);
AtCommandResult AtCmdOkErrAnswer(tAtCmd *env, uint16_t timeout);
AtCommandResult AtCmdReceiveNextChar(tAtCmd *env, uint16_t timeout);
AtCommandResult AtCmdReceiveChar(tAtCmd *env, uint16_t timeout);
AtCommandResult AtGsmTelitLe910_SIMCardDetect(tAtCmd *env);
extern const char AT_ESC_STR[2];
//if not ok return - если не все хорошо возвращаем результат от FUNC
#define AT_INOKR(FUNC) { AtCommandResult result = FUNC; if(result != AT_OK) return result; }
#endif //GSMCOMMONAT_GSMCOMMONATPRIVATE_H

51
Src/AtCmdCommon.c Normal file
View File

@ -0,0 +1,51 @@
//
// Created by xemon on 07.09.22.
//
#include "AtCmdCommonProtected.h"
#include "SystemDelayInterface.h"
void AtCmdInit(
tAtCmd *env,
tSerialPortIO *io,
uint8_t *txBuffer,
size_t txBufferSize,
uint8_t *rxBuffer,
size_t rxBufferSize,
uint32_t stdTxTimeout,
uint32_t stdRxTimeout
) {
env->io = io;
env->rxBuffer.data = (char *) rxBuffer;
env->rxBuffer.limit = rxBufferSize;
env->txBuffer.data = (char *) txBuffer;
env->txBuffer.limit = txBufferSize;
vAsciiStringInit(env->txBuffer.data, &env->txBuffer.len, env->txBuffer.limit);
vAsciiStringInit(env->rxBuffer.data, &env->rxBuffer.len, env->rxBuffer.limit);
env->stdRxTimeout = stdRxTimeout;
env->stdTxTimeout = stdTxTimeout;
env->urcProcessor.process = NULL;
}
AtCommandResult AtCmd(tAtCmd *env) {
AtCmdPrepare(env);
AtCmdSendStatic(env, "AT\r\n");
return AtCmdOkErrAnswer(env, env->stdRxTimeout);
}
AtCommandResult AtCmdWaitOk(tAtCmd *env, uint32_t retryInterval, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while (endMs > SystemGetMs()) {
if (AtCmd(env) == AT_OK) {
return AT_OK;
} else {
SystemDelayMs(retryInterval);
}
}
return AT_TIMEOUT;
}

View File

@ -0,0 +1,40 @@
//
// Created by xemon on 28.11.22.
//
#include "AtCmdCommonProtected.h"
const char AT_ESC_STR[2] = {0x1A, 0x00};
void AtCmdProcessUnresolvedLine(tAtCmd *env) {
if (env->urcProcessor.process) {
AtCmdUrcProcessor_Process(&env->urcProcessor, &env->rxBuffer);
}
}
void AtCmdProcessUnresolvedLines(tAtCmd *env) {
while (AtCmdReceiveNextLine(env, 10) == AT_OK) {
AtCmdProcessUnresolvedLine(env);
}
}
void AtCmdSetUrcProcessor(tAtCmd *env, void *urcProcEnv, void *urcProcFunc) {
env->urcProcessor.env = urcProcEnv;
env->urcProcessor.process = urcProcFunc;
}
void AtCmdClearUrcProcessor(tAtCmd *env) {
env->urcProcessor.process = NULL;
}
void AtCmdSetAccessMutex(tAtCmd *env, tSystemMutexInterface *accessMutex) {
env->access = accessMutex;
}
void AtCmdClearAccessMutex(tAtCmd *env) {
env->access = NULL;
}
void AtCmdPrepare(tAtCmd *env) {
AtCmdProcessUnresolvedLines(env);
}

132
Src/AtCmdCommonRxUtils.c Normal file
View File

@ -0,0 +1,132 @@
//
// Created by xemon on 07.09.22.
//
#include <stdbool.h>
#include <memory.h>
#include "AtCmdCommonProtected.h"
#include "SystemDelayInterface.h"
#ifdef __linux__
#include "strnstr.h"
#endif
AtCommandResult AtCmdReceiveNextChar(tAtCmd *env, uint16_t timeout) {
uint8_t received = SerialPortReceive(
env->io, (uint8_t *) env->rxBuffer.data + env->rxBuffer.len, 1, timeout
);
if (received) {
++env->rxBuffer.len;
return AT_OK;
}
return AT_TIMEOUT;
}
AtCommandResult AtCmdReceiveChar(tAtCmd *env, uint16_t timeout) {
AtCmdRxClear(env);
return AtCmdReceiveNextChar(env, timeout);
}
AtCommandResult AtCmdReceiveNextLine(tAtCmd *env, uint16_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while (endMs > SystemGetMs()) {
AtCmdRxClear(env);
env->rxBuffer.len = SerialPortReceiveTo(
env->io, (uint8_t *) env->rxBuffer.data, env->rxBuffer.limit, '\n', timeout
);
if (env->rxBuffer.len == 0) {
return AT_TIMEOUT;
}
if (env->rxBuffer.data[0] == '\n') {
continue;
}
if (env->rxBuffer.data[env->rxBuffer.len - 1] != '\n') {
return AT_ERROR;
}
return AT_OK;
}
return AT_TIMEOUT;
}
bool AtBufferEndWith(tAtBuffer *env, char simb) {
if (!env->len)
return false;
return env->data[env->len - 1] == simb;
}
bool AtBufferBeginWith(tAtBuffer *env, char *str, size_t strLen) {
if (strLen > env->len)
return false;
return memcmp(env->data, str, strLen) == 0;
}
bool AtCmdRxIsCompleteLine(tAtCmd *env) {
return AtBufferEndWith(&env->rxBuffer, '\n');
}
bool AtCmdRxBeginWith(tAtCmd *env, char *str, size_t strLen) {
return AtBufferBeginWith(&env->rxBuffer, str, strLen);
}
AtCommandResult AtCmdOkErrAnswer(tAtCmd *env, uint16_t timeout) {
uint32_t leftMs;
uint32_t endMs = SystemGetMs() + timeout;
while (endMs > SystemGetMs()) {
leftMs = endMs - SystemGetMs();
if ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) {
if (AtCmdRxBeginWithStatic(env, "OK"))return AT_OK;
if (AtCmdRxBeginWithStatic(env, "ERROR"))return AT_ERROR;
AtCmdProcessUnresolvedLine(env);
}
}
return AT_TIMEOUT;
}
AtCommandResult AtCmdWaitPrefix(tAtCmd *env, uint16_t timeout, char *line, size_t lineLen) {
uint32_t leftMs;
uint32_t endMs = SystemGetMs() + timeout;
while (endMs > SystemGetMs()) {
leftMs = endMs - SystemGetMs();
if ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) {
if (AtCmdRxBeginWith(env, line, lineLen)) {
return AT_OK;
} else {
AtCmdProcessUnresolvedLine(env);
AtCmdRxClear(env);
}
}
}
return AT_TIMEOUT;
}
AtCommandResult AtCmdWaitChar(tAtCmd *env, uint16_t timeout, char line) {
uint32_t end = SystemGetMs() + timeout;
while (SystemGetMs() < end) {
if (AtCmdReceiveChar(env, end - SystemGetMs()) == AT_OK) {
if (*env->rxBuffer.data == line) {
return AT_OK;
}
}
}
return AT_TIMEOUT;
}

11
Src/AtCmdCommonTxUtils.c Normal file
View File

@ -0,0 +1,11 @@
//
// Created by xemon on 07.09.22.
//
#include "AtCmdCommonProtected.h"
#include "SystemDelayInterface.h"
void AtCmdTxSendLn(tAtCmd *env) {
AtCmdTxAddStatic(env, "\r\n");
AtCmdSend(env, env->txBuffer.data, env->txBuffer.len);
}

34
modular.json Normal file
View File

@ -0,0 +1,34 @@
{
"dep": [
{
"type": "git",
"provider": "GONEC_NEW",
"repo": "SerialPort"
},
{
"type": "git",
"provider": "GONEC_NEW",
"repo": "AsciiStringAssemblingUtils"
},
{
"type": "git",
"provider": "GONEC_NEW",
"repo": "AsciiStringParsingUtils"
},
{
"type": "git",
"provider": "GONEC_NEW",
"repo": "SystemSyncInterface"
}
],
"cmake": {
"inc_dirs": [
"Inc",
"AtCommandsInc"
],
"srcs": [
"Src/**.c",
"AtCommandsSrc/**.c"
]
}
}