commit 6f8d09077b7ab61e8bec16192d4159135d712333 Author: cfif Date: Mon May 26 14:41:46 2025 +0300 Init diff --git a/Inc/AtCmdBase.h b/Inc/AtCmdBase.h new file mode 100644 index 0000000..352fe5f --- /dev/null +++ b/Inc/AtCmdBase.h @@ -0,0 +1,48 @@ +// +// Created by xemon on 09.09.22. +// + +#ifndef GSMAT_GSMATCOMMANDRESULT_H +#define GSMAT_GSMATCOMMANDRESULT_H + +#include +#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 diff --git a/Inc/AtCmdCommon.h b/Inc/AtCmdCommon.h new file mode 100644 index 0000000..e7cab11 --- /dev/null +++ b/Inc/AtCmdCommon.h @@ -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 diff --git a/Inc/AtCmdCommonProtected.h b/Inc/AtCmdCommonProtected.h new file mode 100644 index 0000000..32e5455 --- /dev/null +++ b/Inc/AtCmdCommonProtected.h @@ -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 diff --git a/Src/AtCmdCommon.c b/Src/AtCmdCommon.c new file mode 100644 index 0000000..dc44a73 --- /dev/null +++ b/Src/AtCmdCommon.c @@ -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; +} + diff --git a/Src/AtCmdCommonProtected.c b/Src/AtCmdCommonProtected.c new file mode 100644 index 0000000..262f1b5 --- /dev/null +++ b/Src/AtCmdCommonProtected.c @@ -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); +} \ No newline at end of file diff --git a/Src/AtCmdCommonRxUtils.c b/Src/AtCmdCommonRxUtils.c new file mode 100644 index 0000000..0eba850 --- /dev/null +++ b/Src/AtCmdCommonRxUtils.c @@ -0,0 +1,132 @@ +// +// Created by xemon on 07.09.22. +// + +#include +#include +#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; +} + diff --git a/Src/AtCmdCommonTxUtils.c b/Src/AtCmdCommonTxUtils.c new file mode 100644 index 0000000..c3898df --- /dev/null +++ b/Src/AtCmdCommonTxUtils.c @@ -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); +} diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..4fd9bb1 --- /dev/null +++ b/modular.json @@ -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" + ] + } +} \ No newline at end of file