From 5be52a5a18969f17785f9b9f8ff5ae47d5460440 Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 24 Jan 2025 13:22:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20=D0=BE=D1=80?= =?UTF-8?q?=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20GONEC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/AtModemGonec.h | 214 +++++ Src/AtModemGonec.c | 2129 ++++++++++++++++++++++++++++++++++++++++++++ modular.json | 22 + 3 files changed, 2365 insertions(+) create mode 100644 Inc/AtModemGonec.h create mode 100644 Src/AtModemGonec.c create mode 100644 modular.json diff --git a/Inc/AtModemGonec.h b/Inc/AtModemGonec.h new file mode 100644 index 0000000..502a6fd --- /dev/null +++ b/Inc/AtModemGonec.h @@ -0,0 +1,214 @@ +// +// Created by cfif on 25.01.23. +// + +#ifndef GONEC_MODEM_GONEC_H +#define GONEC_MODEM_GONEC_H + +#include +#include "AtCmdCommonProtected.h" +#include "AsciiStringParsingUtils.h" +#include "AtGsm_NetworkRegistrationStatus.h" +#include "time.h" + +AtCommandResult AtModem_Get_PerDown(tAtCmd *env, uint32_t *param); + +AtCommandResult AtModem_PerDown(tAtCmd *env, uint32_t type); + +AtCommandResult AtModem_TransmitterPWR(tAtCmd *env, uint32_t pwr1, uint32_t pwr2, uint32_t pwr3, uint32_t pwr4); + +AtCommandResult AtModem_Get_TransmitterPWR(tAtCmd *env, uint32_t *pwr1, uint32_t *pwr2, uint32_t *pwr3, uint32_t *pwr4); + +AtCommandResult AtModem_LogExtended(tAtCmd *env, uint32_t en); + +AtCommandResult AtModem_Get_LogExtended(tAtCmd *env, uint32_t *en); + +AtCommandResult AtModem_LogEnable(tAtCmd *env, uint32_t en); + +AtCommandResult AtModem_Get_LogEnable(tAtCmd *env, uint32_t *en); + + +// Выбор параметра мощности +AtCommandResult AtModem_SelectPWR(tAtCmd *env, uint32_t pwr); + +AtCommandResult AtModem_Get_SelectPWR(tAtCmd *env, uint32_t *pwr); + +/* +AtCommandResult AtModem_Get_TransmitterPWR1(tAtCmd *env, uint32_t *param); +AtCommandResult AtModem_Get_TransmitterPWR2(tAtCmd *env, uint32_t *param); +AtCommandResult AtModem_Get_TransmitterPWR3(tAtCmd *env, uint32_t *param); +AtCommandResult AtModem_Get_TransmitterPWR4(tAtCmd *env, uint32_t *param); + +AtCommandResult AtModem_TransmitterPWR1(tAtCmd *env, uint32_t type); +AtCommandResult AtModem_TransmitterPWR2(tAtCmd *env, uint32_t type); +AtCommandResult AtModem_TransmitterPWR3(tAtCmd *env, uint32_t type); +AtCommandResult AtModem_TransmitterPWR4(tAtCmd *env, uint32_t type); +*/ + +// Запись прошивки крипто-платы +AtCommandResult AtModem_CryptoSend(tAtCmd *env, uint8_t *pBuf, uint32_t crc, uint32_t offset, uint32_t size); + +// +AtCommandResult AtModem_DelTasi(tAtCmd *env, uint32_t param); + +AtCommandResult AtModem_Get_DelTasi(tAtCmd *env, uint32_t *param); + +// Останов ожидания маркерного сигнала +AtCommandResult AtModem_Stop(tAtCmd *env); + +// Запуск ожидания маркерного сигнала +AtCommandResult AtModem_Start(tAtCmd *env); + +// Останов задачи приема +AtCommandResult AtModem_StopRecvTask(tAtCmd *env); + +// Запуск задачи приема +AtCommandResult AtModem_StartRecvTask(tAtCmd *env); + + +// Запрос слотов приема +AtCommandResult AtModem_Get_Recv_Slot(tAtCmd *env, uint8_t id[], uint8_t status[], uint8_t count); + +// Очистка слота приема +AtCommandResult AtModem_Clear_Recv_Slot(tAtCmd *env, char *id); + +// Чтение данных из слота +AtCommandResult AtModem_Read_Recv_Slot(tAtCmd *env, uint16_t id, uint32_t *size, uint8_t *pBuf); + +// Ввод сетевого адреса модема +AtCommandResult AtModem_NetAddress(tAtCmd *env, uint32_t adr); + +AtCommandResult AtModem_Get_NetAddress(tAtCmd *env, uint32_t *param); + + +// Запуск прошивки +AtCommandResult AtModem_RunModemOrCrypto(tAtCmd *env); + +// Ввод каналов ожидания маркерного сигнала +AtCommandResult AtModem_MarkerCh(tAtCmd *env, uint32_t mc1, uint32_t mc2); + +AtCommandResult AtModem_Get_MarkerCh(tAtCmd *env, uint32_t *mc1, uint32_t *mc2); + +// Ввод тип адреса 1 - почта; 2 - гонец +AtCommandResult AtModem_AddressType(tAtCmd *env, uint32_t type); + +AtCommandResult AtModem_Get_AddressType(tAtCmd *env, uint32_t *param); + +// +AtCommandResult +AtModem_Region(tAtCmd *env, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, + uint32_t p8); + +AtCommandResult +AtModem_Get_Region(tAtCmd *env, uint32_t *p1, uint32_t *p2, uint32_t *p3, uint32_t *p4, uint32_t *p5, uint32_t *p6, + uint32_t *p7, + uint32_t *p8); + +// Установка скоростей +AtCommandResult AtModem_RxTxBitrate(tAtCmd *env, uint32_t s1, uint32_t s2, uint32_t s3, uint32_t s4); + +AtCommandResult AtModem_Get_RxTxBitrate(tAtCmd *env, uint32_t *s1, uint32_t *s2, uint32_t *s3, uint32_t *s4); + +// Установка приоритета +AtCommandResult AtModem_Priority(tAtCmd *env, uint32_t prior); + +AtCommandResult AtModem_Get_Priority(tAtCmd *env, uint32_t *param); + +AtCommandResult AtModem_RestrictSc(tAtCmd *env, char *banned); + +AtCommandResult AtModem_Get_RestrictSc(tAtCmd *env, char *param, size_t len); + +// Установка региона +AtCommandResult AtModem_RegRegion(tAtCmd *env, uint32_t region); + +AtCommandResult AtModem_Get_RegRegion(tAtCmd *env, uint32_t *param); + +// +AtCommandResult AtModem_RegTime(tAtCmd *env, uint32_t time); + +AtCommandResult AtModem_Get_RegTime(tAtCmd *env, uint32_t *param); + +// +AtCommandResult AtModem_DateTime(tAtCmd *env, time_t *timestamp); + +// Загрузка ключей +AtCommandResult AtModem_SetKey(tAtCmd *env, uint32_t key_num, char *buf, size_t buf_len); + +// Проверка ключа +AtCommandResult AtModem_CheckKey(tAtCmd *env, uint32_t key_num); + +// Запись текущих настроек и ключей +AtCommandResult AtModem_WriteMem(tAtCmd *env); + + +// Запрос слотов +AtCommandResult AtModem_Get_Slot(tAtCmd *env, uint8_t id[], uint8_t status[], uint8_t count); + +// Запись данных в слот +AtCommandResult AtModem_Write_Slot(tAtCmd *env, uint32_t id, uint32_t addressAT, uint32_t addressEND, uint32_t urgency, + uint32_t confirmation, uint32_t size, uint8_t *pBuf); + +// Очистка слота +AtCommandResult AtModem_Clear_Slot(tAtCmd *env, char *id); + + +// Запрос состояния регистрации +AtCommandResult AtModem_RegStatus(tAtCmd *env, uint8_t *status); + +// Останов регистрации +AtCommandResult AtModem_StopRegTask(tAtCmd *env); + +// Останов задачи передачи +AtCommandResult AtModem_StopSendTask(tAtCmd *env); + +// Запуск задачи передачи +AtCommandResult AtModem_StartSendTask(tAtCmd *env); + +// Запуск получения альманаха +AtCommandResult AtModem_AlmaRun(tAtCmd *env); + +// Останов получения альманаха +AtCommandResult AtModem_AlmaStop(tAtCmd *env); + + +// Чтения состояния получения альманаха +AtCommandResult AtModem_Get_AlmaRun(tAtCmd *env, uint8_t *run); + +// Запрос состояния получения альманаха +AtCommandResult AtModem_AlmaStatus(tAtCmd *env, uint8_t *status); + +// Чтение пакета альманаха +AtCommandResult AtModem_Read_Alma(tAtCmd *env, uint32_t *size, uint8_t *pBuf); + +// Очистка пакета альманаха +AtCommandResult AtModem_Clear_Alma(tAtCmd *env); + +// Получение логов +AtCommandResult +AtModem_Get_Log(tAtCmd *env, int32_t *rssi, int32_t *temp, uint32_t *pwramp, uint32_t *state, uint32_t *wasreboot, uint32_t *size, + uint8_t *pBuf); + + +// Запуск регистрации +AtCommandResult AtModem_StartRegTask(tAtCmd *env); + +// Координаты +AtCommandResult AtModem_Coord(tAtCmd *env, int latitude, int longitude); + +AtCommandResult +AtModem_Get_Version(tAtCmd *env, char *versionModem, uint8_t *sizeModem, char *versionCrypto, uint8_t *sizeCrypto); + + +AtCommandResult AtModem_TestAFU(tAtCmd *env); + +AtCommandResult AtModem_TestAPO(tAtCmd *env); + +AtCommandResult AtModem_Reg(tAtCmd *env, char *banned); + +AtCommandResult AtModem_Get_Reg(tAtCmd *env, char *banned, size_t len); + +AtCommandResult AtModem_MaxDist(tAtCmd *env, uint32_t dist); + +AtCommandResult AtModem_Get_MaxDist(tAtCmd *env, uint32_t *param); + +#endif //GONEC_MODEM_GONEC_H diff --git a/Src/AtModemGonec.c b/Src/AtModemGonec.c new file mode 100644 index 0000000..90053ae --- /dev/null +++ b/Src/AtModemGonec.c @@ -0,0 +1,2129 @@ +// +// Created by cfif on 25.01.23. +// +#include "AtModemGonec.h" +#include "stdlib.h" +#include "time.h" +#include "string.h" + +// Запись прошивки крипто-платы +AtCommandResult AtModem_CryptoSend(tAtCmd *env, uint8_t *pBuf, uint32_t crc, uint32_t offset, uint32_t size) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT+WRITE="); + AtCmdTxAddDecimalIntWithLimit(env, crc, 10); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, offset, 3); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, size, 4); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, ">")) { + AtCmdRxClear(env); + + AtCmdSend(env, pBuf, size); + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Останов ожидания маркерного сигнала +AtCommandResult AtModem_Stop(tAtCmd *env) { + + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STOP"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запуск ожидания маркерного сигнала +AtCommandResult AtModem_Start(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#START"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Останов задачи передачи +AtCommandResult AtModem_StopSendTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STOPSENDTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запуск задачи передачи +AtCommandResult AtModem_StartSendTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STARTSENDTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Останов задачи приема +AtCommandResult AtModem_StopRecvTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STOPRECVTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запуск задачи приема +AtCommandResult AtModem_StartRecvTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STARTRECVTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запуск регистрации +AtCommandResult AtModem_StartRegTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STARTREGTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Останов регистрации +AtCommandResult AtModem_StopRegTask(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STOPREGTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Запуск прошивки +AtCommandResult AtModem_RunModemOrCrypto(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT+RUN"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Координаты +AtCommandResult AtModem_Coord(tAtCmd *env, int latitude, int longitude) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETCOORD="); + AtCmdTxAddDecimalIntWithLimit(env, latitude, 4); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, longitude, 4); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// +AtCommandResult AtModem_DelTasi(tAtCmd *env, uint32_t param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#DELTASI="); + AtCmdTxAddDecimalIntWithLimit(env, param, 2); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_DelTasi(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#DELTASI=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#DELTASI: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#DELTASI:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Ввод сетевого адреса модема +AtCommandResult AtModem_NetAddress(tAtCmd *env, uint32_t adr) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#NETADDRESS="); + AtCmdTxAddDecimalIntWithLimit(env, adr, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +AtCommandResult AtModem_Get_NetAddress(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#NETADDRESS=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#NETADDRESS: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#NETADDRESS:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Ввод каналов ожидания маркерного сигнала +AtCommandResult AtModem_MarkerCh(tAtCmd *env, uint32_t mc1, uint32_t mc2) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#MARKERCH="); + AtCmdTxAddDecimalIntWithLimit(env, mc1, 3); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, mc2, 3); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +AtCommandResult AtModem_Get_MarkerCh(tAtCmd *env, uint32_t *mc1, uint32_t *mc2) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#MARKERCH=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#MARKERCH: ")) { + isNotFound = false; + + char *front; + char *div = env->rxBuffer.data + sizeof("#MARKERCH:") - 1; + char *end = div + env->rxBuffer.len; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *mc1 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *mc2 = atoi(front); + } + + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Разрешние расширенных логов +AtCommandResult AtModem_LogExtended(tAtCmd *env, uint32_t en) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SYSLOGENABLE="); + AtCmdTxAddDecimalIntWithLimit(env, en, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_LogExtended(tAtCmd *env, uint32_t *en) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SYSLOGENABLE=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SYSLOGENABLE: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SYSLOGENABLE:"); + *en = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Выбор параметра мощности +AtCommandResult AtModem_SelectPWR(tAtCmd *env, uint32_t pwr) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SELECTPWR="); + AtCmdTxAddDecimalIntWithLimit(env, pwr, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_SelectPWR(tAtCmd *env, uint32_t *pwr) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SELECTPWR=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SELECTPWR: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SELECTPWR:"); + *pwr = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Разрешние логов модема +AtCommandResult AtModem_LogEnable(tAtCmd *env, uint32_t en) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#LOGENABLE="); + AtCmdTxAddDecimalIntWithLimit(env, en, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_LogEnable(tAtCmd *env, uint32_t *en) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#LOGENABLE=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#LOGENABLE: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#LOGENABLE:"); + *en = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Коррекция передатчика +AtCommandResult AtModem_TransmitterPWR(tAtCmd *env, uint32_t pwr1, uint32_t pwr2, uint32_t pwr3, uint32_t pwr4) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR="); + AtCmdTxAddDecimalIntWithLimit(env, pwr1, 5); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, pwr2, 5); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, pwr3, 5); + AtCmdTxAddStatic(env, ","); + AtCmdTxAddDecimalIntWithLimit(env, pwr4, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult +AtModem_Get_TransmitterPWR(tAtCmd *env, uint32_t *pwr1, uint32_t *pwr2, uint32_t *pwr3, uint32_t *pwr4) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SETUPPWR: ")) { + isNotFound = false; + + char *front; + char *div = env->rxBuffer.data + sizeof("#SETUPPWR:") - 1; + char *end = div + env->rxBuffer.len; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *pwr1 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *pwr2 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *pwr3 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *pwr4 = atoi(front); + } + + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +/* +AtCommandResult AtModem_TransmitterPWR1(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR1="); + AtCmdTxAddDecimalIntWithLimit(env, type, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_TransmitterPWR2(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR2="); + AtCmdTxAddDecimalIntWithLimit(env, type, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_TransmitterPWR3(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR3="); + AtCmdTxAddDecimalIntWithLimit(env, type, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_TransmitterPWR4(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR4="); + AtCmdTxAddDecimalIntWithLimit(env, type, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} +*/ + +AtCommandResult AtModem_TestAFU(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#TESTAFU"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +AtCommandResult AtModem_TestAPO(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#RSSIAPO"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Ввод тип адреса 1 - почта; 2 - гонец +AtCommandResult AtModem_AddressType(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#ADDRESSTYPE="); + AtCmdTxAddDecimalIntWithLimit(env, type, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_AddressType(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#ADDRESSTYPE=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#ADDRESSTYPE: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#ADDRESSTYPE:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +AtCommandResult AtModem_PerDown(tAtCmd *env, uint32_t type) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#PERDOWN="); + AtCmdTxAddDecimalIntWithLimit(env, type, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_PerDown(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#PERDOWN=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#PERDOWN: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#PERDOWN:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +/* +AtCommandResult AtModem_Get_TransmitterPWR1(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR1=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SETUPPWR1: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SETUPPWR1:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +AtCommandResult AtModem_Get_TransmitterPWR2(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR2=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SETUPPWR2: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SETUPPWR2:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +AtCommandResult AtModem_Get_TransmitterPWR3(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR3=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SETUPPWR3: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SETUPPWR3:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +AtCommandResult AtModem_Get_TransmitterPWR4(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETUPPWR4=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SETUPPWR4: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#SETUPPWR4:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} +*/ + +// +AtCommandResult +AtModem_Region(tAtCmd *env, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, + uint32_t p8) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGION="); + + AtCmdTxAddDecimalIntWithLimit(env, p1, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p2, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p3, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p4, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p5, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p6, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p7, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, p8, 1); + + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +AtCommandResult +AtModem_Get_Region(tAtCmd *env, uint32_t *p1, uint32_t *p2, uint32_t *p3, uint32_t *p4, uint32_t *p5, uint32_t *p6, + uint32_t *p7, + uint32_t *p8) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGION=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#REGION: ")) { + isNotFound = false; + + char *front; + char *div = env->rxBuffer.data + sizeof("#REGION:") - 1; + char *end = div + env->rxBuffer.len; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p1 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p2 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p3 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p4 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p5 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p6 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p7 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *p8 = atoi(front); + } + + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Установка скоростей +AtCommandResult +AtModem_RxTxBitrate(tAtCmd *env, uint32_t s1, uint32_t s2, uint32_t s3, uint32_t s4) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#RXTXBITRATE="); + + AtCmdTxAddDecimalIntWithLimit(env, s1, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, s2, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, s3, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, s4, 1); + + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_RxTxBitrate(tAtCmd *env, uint32_t *s1, uint32_t *s2, uint32_t *s3, uint32_t *s4) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#RXTXBITRATE=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#RXTXBITRATE: ")) { + isNotFound = false; + + char *front; + char *div = env->rxBuffer.data + sizeof("#RXTXBITRATE:") - 1; + char *end = div + env->rxBuffer.len; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *s1 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *s2 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *s3 = atoi(front); + } + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *s4 = atoi(front); + } + + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Установка приоритета +AtCommandResult AtModem_Priority(tAtCmd *env, uint32_t prior) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#PRIORITY="); + AtCmdTxAddDecimalIntWithLimit(env, prior, 1); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_Priority(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#PRIORITY=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#PRIORITY: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#PRIORITY:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +AtCommandResult AtModem_RestrictSc(tAtCmd *env, char *banned) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#RESTRICTSC="); + AtCmdTxAdd(env, banned, strlen(banned)); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_RestrictSc(tAtCmd *env, char *banned, size_t len) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#RESTRICTSC=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#RESTRICTSC:")) { + isNotFound = false; + + volatile int b = sizeof("#RESTRICTSC:"); + + char *start = env->rxBuffer.data + sizeof("#RESTRICTSC:"); + if (env->rxBuffer.len > sizeof("#RESTRICTSC:") + 2) { + memcpy(banned, start, env->rxBuffer.len - sizeof("#RESTRICTSC:") - 2); + } + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +AtCommandResult AtModem_Reg(tAtCmd *env, char *banned) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGION="); + AtCmdTxAdd(env, banned, strlen(banned)); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +AtCommandResult AtModem_Get_Reg(tAtCmd *env, char *banned, size_t len) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGION=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#REGION:")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#REGION:"); + if (env->rxBuffer.len > sizeof("#REGION:") + 2) { + memcpy(banned, start, env->rxBuffer.len - sizeof("#REGION:") - 2); + } + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +AtCommandResult AtModem_MaxDist(tAtCmd *env, uint32_t dist) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#MAXDIST="); + AtCmdTxAddDecimalIntWithLimit(env, dist, 5); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_MaxDist(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#MAXDIST=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#MAXDIST: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#MAXDIST:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Установка региона +AtCommandResult AtModem_RegRegion(tAtCmd *env, uint32_t region) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGREGION="); + AtCmdTxAddDecimalIntWithLimit(env, region, 2); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_RegRegion(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGREGION=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#REGREGION: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#REGREGION:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// +AtCommandResult AtModem_RegTime(tAtCmd *env, uint32_t time) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGTIME="); + AtCmdTxAddDecimalIntWithLimit(env, time, 6); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +AtCommandResult AtModem_Get_RegTime(tAtCmd *env, uint32_t *param) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#REGTIME=?"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#REGTIME: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#REGTIME:"); + *param = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// +AtCommandResult AtModem_DateTime(tAtCmd *env, time_t *timestamp) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#DATETIME="); + + struct tm dateTime; + gmtime_r(timestamp, &dateTime); + + char buf[32]; + strftime(buf, sizeof(buf), "%d-%m-%Y,%T", &dateTime); + + AtCmdTxAdd(env, buf, strlen(buf)); + + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Загрузка ключей +AtCommandResult AtModem_SetKey(tAtCmd *env, uint32_t key_num, char *buf, size_t buf_len) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#SETKEY="); + AtCmdTxAddDecimalIntWithLimit(env, key_num, 2); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, ">")) { + AtCmdRxClear(env); + AtCmdSend(env, buf, buf_len); + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else if (AtCmdRxBeginWithStatic(env, "ERROR CRC")) { + AtCmdRxClear(env); + return AT_ERROR; + } else if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_TIMEOUT; + +} + +// Проверка ключа +AtCommandResult AtModem_CheckKey(tAtCmd *env, uint32_t key_num) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#CHECKKEY="); + AtCmdTxAddDecimalIntWithLimit(env, key_num, 2); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + } else if (AtCmdRxBeginWithStatic(env, "ERROR CRC")) { + AtCmdRxClear(env); + return AT_ERROR; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_TIMEOUT; +} + +// Запись текущих настроек и ключей +AtCommandResult AtModem_WriteMem(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdSendStatic(env, "AT#WRITEMEM\r\n"); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запрос слотов +AtCommandResult AtModem_Get_Slot(tAtCmd *env, uint8_t id[], uint8_t status[], uint8_t count) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#GETSENDSTATUS"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#SENDSTATUS: ")) { + + char *front; + char *div = env->rxBuffer.data + sizeof("#SENDSTATUS:") - 1; + char *end = div + env->rxBuffer.len; + + for (int i = 0; i < 16; ++i) { + + *id = i + 1; + *status = 0; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *status = atoi(front); + } + + ++id; + ++status; + } + AtCmdRxClear(env); + continue; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +#include "SerialPorts.h" + +void vSerialPortSendDMA( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA, + dma_channel_type *DMA_CHANNEL, + dmamux_channel_type *DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type DMAMUX_DMAREQ_ID, + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN + +); + +// Запись данных в слот +AtCommandResult AtModem_Write_Slot(tAtCmd *env, uint32_t id, uint32_t addressAT, uint32_t addressEND, uint32_t urgency, + uint32_t confirmation, uint32_t size, uint8_t *pBuf) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#WRITEPKT="); + AtCmdTxAddDecimalIntWithLimit(env, id, 2); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, addressAT, 8); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, addressEND, 8); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, urgency, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, confirmation, 1); + AtCmdTxAddStatic(env, ","); + + AtCmdTxAddDecimalIntWithLimit(env, size, 4); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, ">")) { + AtCmdRxClear(env); + AtCmdSend(env, pBuf, size); + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Очистка слота передачи +AtCommandResult AtModem_Clear_Slot(tAtCmd *env, char *id) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#DELSENDPKT="); + AtCmdTxAdd(env, id, strlen(id)); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Чтение данных из слота +AtCommandResult AtModem_Read_Recv_Slot(tAtCmd *env, uint16_t id, uint32_t *size, uint8_t *pBuf) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#READPKT="); + AtCmdTxAddDecimalIntWithLimit(env, id, 2); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "#READPKT: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#READPKT:")]; + + *size = atoi(pSize); // Размер сообщения + AtCmdRxClear(env); // Очистка приемного буфера + + if ((*size < 0) || (*size > 1300)) { + return AT_ERROR; + } + + AtCmdRxReadRAW(env, pBuf, *size, env->stdRxTimeout); // Чтение данных сообщения + continue; + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Запрос слотов приема +AtCommandResult AtModem_Get_Recv_Slot(tAtCmd *env, uint8_t id[], uint8_t status[], uint8_t count) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#GETRECVSTATUS"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#RECVSTATUS: ")) { + + char *front; + char *div = env->rxBuffer.data + sizeof("#RECVSTATUS:") - 1; + char *end = div + env->rxBuffer.len; + + for (int i = 0; i < 16; ++i) { + + *id = i + 1; + *status = 0; + + if (iAsciiStringMoveToNextParsingBlock(&front, &div, end, ',')) { + *status = atoi(front); + } + + ++id; + ++status; + } + AtCmdRxClear(env); + continue; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Очистка слота приема +AtCommandResult AtModem_Clear_Recv_Slot(tAtCmd *env, char *id) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#DELRECVPKT="); + AtCmdTxAdd(env, id, strlen(id)); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Запуск получения альманаха +AtCommandResult AtModem_AlmaRun(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STARTALMANACTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + +// Останов получения альманаха +AtCommandResult AtModem_AlmaStop(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STOPALMANACTASK"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Чтения состояния получения альманаха +AtCommandResult AtModem_Get_AlmaRun(tAtCmd *env, uint8_t *run) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#STATUSALMANACTASK"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#STATUSALMANACTASK: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#STATUSALMANACTASK:"); + *run = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Запрос состояния получения альманаха +AtCommandResult AtModem_AlmaStatus(tAtCmd *env, uint8_t *status) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#GETRESALMANACTASK"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#RESALMANACTASK: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#RESALMANACTASK:"); + *status = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Запрос состояния регистрации +AtCommandResult AtModem_RegStatus(tAtCmd *env, uint8_t *status) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#GETREGSTATUS"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + bool isNotFound = true; + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + if (isNotFound) + return AT_ERROR; + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#REGSTATUS: ")) { + isNotFound = false; + + char *start = env->rxBuffer.data + sizeof("#REGSTATUS:"); + *status = atoi(start); + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + + +// Чтение пакета альманаха +AtCommandResult AtModem_Read_Alma(tAtCmd *env, uint32_t *size, uint8_t *pBuf) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#ALMAREAD"); + AtCmdTxSendLn(env); + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "#ALMAREAD: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#ALMAREAD:")]; + *size = atoi(pSize); + AtCmdRxClear(env); + + if ((*size < 0) || (*size > 1300)) { + return AT_ERROR; + } + + AtCmdRxReadRAW(env, pBuf, *size, env->stdRxTimeout); + + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} + +// Очистка пакета альманаха +AtCommandResult AtModem_Clear_Alma(tAtCmd *env) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#ALMACLEAR"); + AtCmdTxSendLn(env); + + return AtCmdOkErrAnswer(env, env->stdRxTimeout); +} + + +// Получение логов +AtCommandResult +AtModem_Get_Log(tAtCmd *env, int32_t *rssi, int32_t *temp, uint32_t *pwramp, uint32_t *state, uint32_t *wasreboot, + uint32_t *size, uint8_t *pBuf) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT#GETLOG"); + AtCmdTxSendLn(env); + + *size = 0; + *wasreboot = 0; + *state = 0; + *pwramp = 0; + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "#LOG: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#LOG:")]; + *size = atoi(pSize); + AtCmdRxClear(env); + + if ((*size < 0) || (*size > 1024)) { + return AT_ERROR; + } + + + AtCmdRxReadRAW(env, pBuf, *size, env->stdRxTimeout); +// *size = env->rxBuffer.len - sizeof("#LOG:"); +// memcpy(pBuf, pSize, *size); +// AtCmdRxClear(env); + continue; + } else if (AtCmdRxBeginWithStatic(env, "#RSSI: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#RSSI:")]; + *rssi = atoi(pSize); + AtCmdRxClear(env); + + } else if (AtCmdRxBeginWithStatic(env, "#TEMP: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#TEMP:")]; + *temp = atoi(pSize); + AtCmdRxClear(env); + } else if (AtCmdRxBeginWithStatic(env, "#PWRAMP: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#PWRAMP:")]; + *pwramp = atoi(pSize); + AtCmdRxClear(env); + } else if (AtCmdRxBeginWithStatic(env, "#STATE: ")) { + char *pSize = &env->rxBuffer.data[sizeof("#STATE:")]; + *state = atoi(pSize); + AtCmdRxClear(env); + } else if (AtCmdRxBeginWithStatic(env, "#WASREBOOT")) { + *wasreboot = 1; + AtCmdRxClear(env); + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + } else if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + return AT_OK; + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return + AT_ERROR; +} + +AtCommandResult +AtModem_Get_Version(tAtCmd *env, char *versionModem, uint8_t *sizeModem, char *versionCrypto, uint8_t *sizeCrypto) { + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT+VERSION"); + AtCmdTxSendLn(env); + + *sizeModem = 0; + *sizeCrypto = 0; + + uint32_t timeout = env->stdRxTimeout; + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs = timeout; + + while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) { + leftMs = endMs - SystemGetMs(); + + if (AtCmdRxBeginWithStatic(env, "OK")) { + AtCmdRxClear(env); + + return AT_OK; + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + AtCmdRxClear(env); + return AT_ERROR; + + } else if (AtCmdRxBeginWithStatic(env, "#VERSION: MODEM_")) { + + char *start = env->rxBuffer.data + sizeof("#VERSION:"); + *sizeModem = env->rxBuffer.len - sizeof("#VERSION: "); + memcpy(versionModem, start, *sizeModem); + + AtCmdRxClear(env); + + } else if (AtCmdRxBeginWithStatic(env, "#VERSION: AUTH_")) { + + char *start = env->rxBuffer.data + sizeof("#VERSION:"); + *sizeCrypto = env->rxBuffer.len - sizeof("#VERSION: "); + memcpy(versionCrypto, start, *sizeCrypto); + + AtCmdRxClear(env); + + } else { + AtCmdProcessUnresolvedLine(env); + AtCmdRxClear(env); + continue; + } + } + + return AT_ERROR; +} diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..7886926 --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC", + "repo": "AsciiStringAssemblingUtils" + }, + { + "type": "git", + "provider": "GONEC", + "repo": "AtGsmCommon" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file