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