// // 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; uint8_t attemptsNotEndOfLine = 3; 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') { while (attemptsNotEndOfLine) { uint16_t limit = 0; if (env->rxBuffer.limit >= env->rxBuffer.len) { limit = env->rxBuffer.limit - env->rxBuffer.len; } uint16_t len = SerialPortReceiveTo( env->io, (uint8_t *) &env->rxBuffer.data[env->rxBuffer.len], limit, '\n', 5 ); env->rxBuffer.len += len; if (env->rxBuffer.data[env->rxBuffer.len - 1] == '\n') { break; } --attemptsNotEndOfLine; } } 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; }