From 07c1d35d7cd44d73bfdf4e9b3383ce6bc06cd577 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 2 Jun 2025 14:32:56 +0300 Subject: [PATCH] Init --- GetGsmFirmware.c | 639 +++++++++++++++++++++++++++++++++++++++++++++++ GetGsmFirmware.h | 87 +++++++ Gsm_HttpGet.c | 70 ++++++ Gsm_HttpGet.h | 12 + modular.json | 10 + 5 files changed, 818 insertions(+) create mode 100755 GetGsmFirmware.c create mode 100755 GetGsmFirmware.h create mode 100755 Gsm_HttpGet.c create mode 100644 Gsm_HttpGet.h create mode 100755 modular.json diff --git a/GetGsmFirmware.c b/GetGsmFirmware.c new file mode 100755 index 0000000..98961fb --- /dev/null +++ b/GetGsmFirmware.c @@ -0,0 +1,639 @@ +// +// Created by cfif on 22.08.23. +// + +#include "GetGsmFirmware.h" +#include "string.h" +#include "stdlib.h" +#include "FirmwareLoader.h" +#include "ld_adr.h" +#include "InternalFlashPage.h" +#include "AtGsm_NetworkRegistrationStatus.h" +#include "AtGsmOperatorSelection.h" +#include "SystemDelayInterface.h" +#include "AtGsmSimComA7600_DefinePdpContext.h" + +#define LOG_SIGN "UPDATE" +#define LOGGER &env->log->logger + +#define FIRMWARE_MAIN_ADDR (0x08000000 + BOOT_AREA_LENGTH) +#define FIRMWARE_MAIN_RECOVERY_ADDR (FIRMWARE_MAIN_ADDR + FIRMWARE_MAIN_AREA_LENGTH) + +#define FIRMWARE_TELE_MAIN_ADDR (FIRMWARE_MAIN_RECOVERY_ADDR + FIRMWARE_MAIN_UPDATE_AREA_LENGTH) +#define FIRMWARE_TELE_RECOVERY_ADDR (FIRMWARE_MAIN_ADDR + FIRMWARE_MAIN_AREA_LENGTH) + +tFirmwareLoader FIRMWARE_UVEOS_LOADER; + +static uint32_t GetGsmFirmwareCrc32(const uint8_t *buf, size_t size) { + uint32_t crc = 0; + + for (size_t i = 0; i < size; ++i) { + crc += buf[i]; + } + + return crc; +} + +static bool WaitNetworkRegistration(tGsmFirmware *env, tAtCmd *gsmAt, uint16_t timeReg) { + + uint32_t timeEnd = SystemGetMs() + timeReg; + + tAtGsm_NetworkRegistrationReportMode mode; + tAtGsm_NetworkRegistrationState state; + + while (timeEnd > SystemGetMs()) { + if (AtGsm_NetworkRegistrationStatus(gsmAt, &mode, &state)) { + if (state == AT_NETWORK_REGISTRATION_STATE_REGISTERED_HOME || + state == AT_NETWORK_REGISTRATION_STATE_REGISTERED_ROAMING) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена регистрация") + return true; + } + } + SystemDelayMs(60); + } + + return false; +} + +static bool NetworkRequire(tGsmFirmware *env, tAtCmd *gsmAt) { + bool result = false; + + if (osMutexAcquire(gsmAt->access, 2000) == osOK) { + + if (!WaitNetworkRegistration(env, gsmAt, 2000)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Включение регистрации в сети"); + for (uint8_t i = 0; i < 5; ++i) { + AtGsm_OperatorSelectionAutomatic(gsmAt); + SystemDelayMs(150); + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ждем сеть..."); + if (WaitNetworkRegistration(env, gsmAt, 2000)) { + result = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети получена"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети не получена"); + } + + } else { + result = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Регистрация в сети присутствует"); + } + + osMutexRelease(gsmAt->access); + } + + return result; +} + +static int getFileSizeFirmware(tGsmFirmware *env, tAtCmd *gsmAt, char *firmware_php_path_req, uint8_t *firmware_buf) { + + char url[128]; + url[0] = '\0'; + strcat(url, firmware_php_path_req); + strcat(url, "?file="); + + if (env->firmwareType == FIRMWARE_UVEOS) { + strcat(url, firmware_php_uveos_req); + } + + if (env->firmwareType == FIRMWARE_TELE) { + strcat(url, firmware_php_tele_req); + } + + strcat(url, "&return_size=1"); + + int FileSizeCurrent = 0; + int connection_step = 0; + + while (connection_step < connect_http_retry) { + Gsm_HttpGet_Close(gsmAt); + size_t fileSize = Gsm_HttpGet_Open(gsmAt, url, strlen(url)); + + if (fileSize > 0) { + + size_t read = Gsm_HttpGet_Read(gsmAt, firmware_buf, 2048); + if (read > 0) { + + FileSizeCurrent = atoi((char *) firmware_buf); + break; + } else { + ++connection_step; + } + + } else { + ++connection_step; + } + } + + return FileSizeCurrent; +} + + +static int getMetadataFirmware(tGsmFirmware *env, tAtCmd *gsmAt, char *firmware_php_path_req, int sizeFileFirmware, + uint8_t *firmware_buf) { + char buf[12]; + + char url[128]; + url[0] = '\0'; + strcat(url, firmware_php_path_req); + strcat(url, "?offset="); + int offsetMeta = sizeFileFirmware - FIRMWARE_META_LENGTH; + utoa(offsetMeta, buf, 10); + strcat(url, buf); + strcat(url, "&limit="); + utoa(FIRMWARE_META_LENGTH, buf, 10); + strcat(url, buf); + strcat(url, "&file="); + if (env->firmwareType == FIRMWARE_UVEOS) { + strcat(url, firmware_php_uveos_req); + } + + if (env->firmwareType == FIRMWARE_TELE) { + strcat(url, firmware_php_tele_req); + } + + int connection_step = 0; + + size_t fileSizeMeta = 0; + + while (connection_step < connect_http_retry) { + + if (env->startUpdateFirmware == false) + return 0; + + Gsm_HttpGet_Close(gsmAt); + fileSizeMeta = Gsm_HttpGet_Open(gsmAt, url, strlen(url)); + + if (fileSizeMeta > 0) { + + size_t read = Gsm_HttpGet_Read(gsmAt, firmware_buf, 2048); + if (read > 0) { + break; + } else { + ++connection_step; + } + + } else { + ++connection_step; + } + } + + return (int) fileSizeMeta; +} + + +static bool +getFileBodyFirmware(tGsmFirmware *env, bool isDoGsmFirmware) { + + + if (env->Server.length < 1) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка. Не введен адреса сервера обновления"); + return false; + } + + if (NetworkRequire(env, env->gsmAt)) { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Начало обновления прошивки"); + } else { + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Ошибка. Нет регистрации в сети"); + return false; + } + + memset(env->firmwareStats, 0, sizeof(tFirmwareStats)); + + AtCommandResult res = AtGsmSimComA7600_PdpActivate(env->gsmAt, 2); + + res = AtGsmSimComA7600_DefinePdpContext(env->gsmAt, 2, AtGsmSimComA7600_PdpType_IP, + env->Apn.data, + env->Apn.length); + + res = AtGsmSimComA7600_PdpActivate(env->gsmAt, 2); + + uint32_t connection_step = 0; + size_t FileSizeCurrent = 0; + + while ((FileSizeCurrent == 0) && (connection_step < connect_http_retry)) { + + if (env->startUpdateFirmware == false) + return false; + + FileSizeCurrent = getFileSizeFirmware(env, env->gsmAt, env->Server.data, env->firmware_buf); + + if (FileSizeCurrent == 0) { + ++env->firmwareStats->stat_err_open; + ++connection_step; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Получение размера прошивки. Ошибка соединения с сервером. Попытка: %d из %d", + connection_step, connect_http_retry); + SystemDelayMs(3000); + } + + } + + if (FileSizeCurrent == 0) { + return false; + } + + + connection_step = 0; + size_t FileSizeMeta = 0; + + while ((FileSizeMeta == 0) && (connection_step < connect_http_retry)) { + + if (env->startUpdateFirmware == false) + return false; + + FileSizeMeta = getMetadataFirmware(env, env->gsmAt, env->Server.data, (int) FileSizeCurrent, env->firmware_buf); + + if (FileSizeMeta == 0) { + ++env->firmwareStats->stat_err_open; + ++connection_step; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Получение метаданных прошивки. Ошибка соединения с сервером. Попытка: %d из %d", + connection_step, connect_http_retry); + SystemDelayMs(3000); + } + + } + + if (FileSizeMeta == 0) { + return false; + } + + // Проверка нужно ли обновляться + if (env->isExaminationFirmware) { + + tFirmwareLoader FIRMWARE_HTTP; + FirmwareLoader_Init(&FIRMWARE_HTTP, FIRMWARE_META_LENGTH, 0, (uint32_t) &env->firmware_buf[0]); + FirmwareLoader_LoadMetadata(&FIRMWARE_HTTP, &FIRMWARE_HTTP.update); + + uint32_t httpCrc32 = *FIRMWARE_HTTP.update.metadata.crc; + uint32_t uveosCrc32 = *FIRMWARE_UVEOS_LOADER.main.metadata.crc; + + bool sameNames = + (*FIRMWARE_UVEOS_LOADER.main.metadata.nameLength == *FIRMWARE_HTTP.update.metadata.nameLength) && + memcmp( + FIRMWARE_UVEOS_LOADER.main.metadata.name, + FIRMWARE_HTTP.update.metadata.name, + *FIRMWARE_HTTP.update.metadata.nameLength) == 0; + + if ((uveosCrc32 == httpCrc32) && sameNames) { + env->isAbortOld = true; + LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Прошивка в обновлении не нуждается"); + return true; + } + } + + if (!isDoGsmFirmware) { + if (osMutexAcquire(env->access, 5000) == osOK) { + + if (FirmwareLoader_ClearUpdateFlash(&FIRMWARE_UVEOS_LOADER)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "ПЗУ очищено"); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка очистки ПЗУ"); + ++env->firmwareStats->stat_err_write; + osMutexRelease(env->access); + return false; + } + + osMutexRelease(env->access); + } + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Очистка ПЗУ не требуется"); + } + + + char url[128]; + char buf[12]; + + uint32_t portion_full = FileSizeCurrent / portion_size; + uint32_t portion_size_tail = FileSizeCurrent % portion_size; + + if (portion_size_tail > 0) + ++portion_full; + + uint32_t limit = portion_size; + connection_step = 0; + + if (!isDoGsmFirmware) { + env->offset = 0; + env->portion_step = 0; + } + + env->firmwareStats->stat_err_open = 0; + env->firmwareStats->stat_err_read = 0; + env->firmwareStats->stat_err_crc = 0; + env->firmwareStats->stat_err_write = 0; + + // Цикл по всем порциям + while ((env->portion_step < portion_full) && (connection_step < connect_http_retry)) { + + if (env->startUpdateFirmware == false) + return false; + + Gsm_HttpGet_Close(env->gsmAt); + + url[0] = '\0'; + strcat(url, env->Server.data); + strcat(url, "?offset="); + utoa(env->offset, buf, 10); + strcat(url, buf); + strcat(url, "&limit="); + utoa(limit, buf, 10); + strcat(url, buf); + strcat(url, "&file="); + if (env->firmwareType == FIRMWARE_UVEOS) { + strcat(url, firmware_php_uveos_req); + } + + if (env->firmwareType == FIRMWARE_TELE) { + strcat(url, firmware_php_tele_req); + } + + size_t fileSize = Gsm_HttpGet_Open(env->gsmAt, url, strlen(url)); + + if (fileSize == limit + 4) { + + size_t read = Gsm_HttpGet_Read(env->gsmAt, env->firmware_buf, fileSize); + + if (read == fileSize) { + + uint32_t crc_recv = ((uint32_t *) &env->firmware_buf[limit])[0]; + uint32_t crc_calc = GetGsmFirmwareCrc32(env->firmware_buf, limit); + + if (crc_recv != crc_calc) { + ++env->firmwareStats->stat_err_crc; + ++connection_step; + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Ошибка контрольной суммы данных от сервера. Попытка: %d из %d", + connection_step, connect_http_retry); + + continue; + } + + connection_step = 0; + ++env->portion_step; + + if (osMutexAcquire(env->access, 5000) == osOK) { + + if (sInternalFlashPage_Write(FIRMWARE_UVEOS_LOADER.update.address, env->offset, env->firmware_buf, + limit) == limit) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Загружено: %d из %d", env->portion_step, portion_full); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка записи в ПЗУ"); + ++env->firmwareStats->stat_err_write; + osMutexRelease(env->access); + return false; + } + + osMutexRelease(env->access); + } + + if ((portion_size_tail > 0) && (env->portion_step == portion_full - 1)) { + env->offset += portion_size; + limit = portion_size_tail; + } else { + env->offset += portion_size; + } + + } else { + ++env->firmwareStats->stat_err_read; + ++connection_step; + + LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Ошибка получения данных от сервера. Попытка: %d из %d", + connection_step, connect_http_retry); + + SystemDelayMs(500); + } + + } else { + ++env->firmwareStats->stat_err_open; + ++connection_step; + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Получение данных прошивки. Ошибка соединения с сервером. Попытка: %d из %d", + connection_step, connect_http_retry); + SystemDelayMs(3000); + } + + } + + if ((connection_step == connect_http_retry) || (env->firmwareStats->stat_err_write != 0)) { + return false; + } + + return true; +} + +bool GetDoGsmFirmware(tGsmFirmware *env) { + bool isLoadFirmware = getFileBodyFirmware(env, true); + + return isLoadFirmware; +} + +bool GetGsmFirmware(tGsmFirmware *env) { + + bool isLoadFirmware = getFileBodyFirmware(env, false); + + return isLoadFirmware; +} + +void StartUpdateFirmware(tGsmFirmware *env) { + env->doUpdateFirmware = false; + env->startUpdateFirmware = true; + env->isAbortOld = false; +} + +void _Noreturn FirmwareProcessingTask(tGsmFirmware *env) { +// uint32_t attempts; + + for (;;) { + + if (env->startUpdateFirmware) { + + if (env->doUpdateFirmware) { + bool result = GetDoGsmFirmware(env); + + if (env->startUpdateFirmware == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход из режима обновления УВЭОС"); + continue; + } + + if (result) { + env->startUpdateFirmware = false; + env->doUpdateFirmware = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Успех. Обновление завершено без ошибок"); + env->eventUpdateFunc(env->envUpdateFunc, true, env->isAbortOld); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка. Обновление не завершено"); + --env->attempts; + + env->eventUpdateFunc(env->envUpdateFunc, false, env->isAbortOld); + + + if (env->attempts > 0) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Обновление будет завершено позже, через %d сек. Осталось попыток %d из %d", + env->attempts_period, + env->attempts, + env->attemptsAll); + + for (uint32_t i = 0; i < env->attempts_period; ++i) { + + if (env->startUpdateFirmware == false) { + break; + } + SystemDelayMs(1000); + } + + if (env->startUpdateFirmware == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход из режима обновления УВЭОС"); + continue; + } + + + } else { + env->startUpdateFirmware = false; + env->doUpdateFirmware = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Попытки исчерпаны. Обновление будет завершено после получения команды на обновление"); + } + } + + } else { + bool result = GetGsmFirmware(env); + + if (env->startUpdateFirmware == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход из режима обновления УВЭОС"); + continue; + } + + if (result) { + env->startUpdateFirmware = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Успех. Обновление завершено без ошибок"); + env->eventUpdateFunc(env->envUpdateFunc, true, env->isAbortOld); + } else { +// attempts = env->attempts; + env->doUpdateFirmware = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка. Обновление не завершено"); + env->eventUpdateFunc(env->envUpdateFunc, false, env->isAbortOld); + + if (env->attempts > 0) { + LoggerStrFormatInfo(LOGGER, LOG_SIGN, + "Обновление будет завершено позже, через %d сек. Осталось попыток %d из %d", + env->attempts_period, + env->attempts, + env->attemptsAll); + + for (uint32_t i = 0; i < env->attempts_period; ++i) { + + if (env->startUpdateFirmware == false) { + break; + } + SystemDelayMs(1000); + } + + if (env->startUpdateFirmware == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход из режима обновления УВЭОС"); + continue; + } + + + } else { +/* + LoggerInfoStatic(LOGGER, LOG_SIGN, "Дополнительные 100 попыток"); + env->attempts = 100; +*/ + for (uint32_t i = 0; i < env->attempts_period; ++i) { + + if (env->startUpdateFirmware == false) { + break; + } + SystemDelayMs(1000); + } + + if (env->startUpdateFirmware == false) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход из режима обновления УВЭОС"); + continue; + } + + env->startUpdateFirmware = false; + env->doUpdateFirmware = false; + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Попытки исчерпаны. Обновление будет завершено после получения команды на обновление"); + } + + + } + } + + } + + SystemDelayMs(1000); + } +} + +void InitGsmFirmware(tGsmFirmware *env, + tAtCmd *gsmAt, + eFirmwareType firmwareType, + uint8_t *firmware_buf, + tFirmwareStats *firmwareStats, + tString64 *Apn, + tString64 *Server, + uint32_t attempts, + uint32_t attempts_period, + osMutexId_t access, + bool isExaminationFirmware, + EventUpdateFunc *eventUpdateFunc, + void *envUpdateFunc, + tLoggerToSerialPort *log) { + + + if (firmwareType == FIRMWARE_UVEOS) { + FirmwareLoader_Init(&FIRMWARE_UVEOS_LOADER, FIRMWARE_MAIN_AREA_LENGTH, FIRMWARE_MAIN_ADDR, + FIRMWARE_MAIN_RECOVERY_ADDR); + } + + if (firmwareType == FIRMWARE_TELE) { + FirmwareLoader_Init(&FIRMWARE_UVEOS_LOADER, FIRMWARE_TELE_AREA_LENGTH, FIRMWARE_TELE_MAIN_ADDR, + FIRMWARE_MAIN_RECOVERY_ADDR); + } + + bool mainFwOk = FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.main); + + env->isExaminationFirmware = isExaminationFirmware; + + env->access = access; + + env->firmwareType = firmwareType; + + env->doUpdateFirmware = false; + env->startUpdateFirmware = false; + + env->eventUpdateFunc = eventUpdateFunc; + env->envUpdateFunc = envUpdateFunc; + + env->attemptsAll = attempts; + env->attempts = attempts; + env->attempts_period = attempts_period; + + env->gsmAt = gsmAt; + env->firmware_buf = firmware_buf; + env->firmwareStats = firmwareStats; + + memset(env->Apn.data, 0, sizeof(env->Apn.data)); + env->Apn.length = Apn->length; + memcpy(&env->Apn.data, Apn->data, Apn->length); + + memset(env->Server.data, 0, sizeof(env->Server.data)); + env->Server.length = Server->length; + memcpy(&env->Server.data, Server->data, Server->length); + + env->log = log; + + InitThreadBlock(env->T_processing_Firmware, "Firmware", osPriorityNormal); +} + +void GsmFirmware_Start(tGsmFirmware *env) { + ThreadBlock_Start(env->T_processing_Firmware, env, FirmwareProcessingTask); +} + diff --git a/GetGsmFirmware.h b/GetGsmFirmware.h new file mode 100755 index 0000000..495367e --- /dev/null +++ b/GetGsmFirmware.h @@ -0,0 +1,87 @@ +// +// Created by cfif on 22.08.23. +// + +#ifndef GETGSMFIRMWARE_H +#define GETGSMFIRMWARE_H + +#include "AtCmdBase.h" +#include "Gsm_HttpGet.h" +#include "FirmwareLoader.h" +#include "LoggerToSerialPort.h" +#include "CmsisRtosThreadUtils.h" + +// Количество повторений до прерывания процедуры получения файла +#define connect_http_retry 5 +// Размер порции для приема +//#define portion_size (1024 - 4) +#define portion_size (1024 - 4) + +#define firmware_php_uveos_req "uveos.xfsb" +#define firmware_php_tele_req "tele.xfsb" + +typedef enum { + FIRMWARE_UVEOS = 0, + FIRMWARE_TELE = 1 +} eFirmwareType; + +typedef struct { + int stat_err_open; + int stat_err_read; + int stat_err_crc; + int stat_err_write; + int stat_err_file_crc; +} tFirmwareStats; + +typedef void (EventUpdateFunc)(void *env, bool result, bool isAbortOld); + +typedef struct { + tAtCmd *gsmAt; + uint8_t *firmware_buf; + tFirmwareStats *firmwareStats; + tString64 Apn; + tString64 Server; + tLoggerToSerialPort *log; + uint32_t portion_step; + uint32_t offset; + uint32_t attemptsAll; + uint32_t attempts; + uint32_t attempts_period; + volatile bool startUpdateFirmware; + volatile bool doUpdateFirmware; + + osMutexId_t access; + + bool isExaminationFirmware; + + EventUpdateFunc *eventUpdateFunc; + void *envUpdateFunc; + + // Старая прошивка + bool isAbortOld; + + eFirmwareType firmwareType; + + tStaticThreadBlock(1024) T_processing_Firmware; + +} tGsmFirmware; + +void InitGsmFirmware(tGsmFirmware *env, + tAtCmd *gsmAt, + eFirmwareType firmwareType, + uint8_t *firmware_buf, + tFirmwareStats *firmwareStats, + tString64 *Apn, + tString64 *Server, + uint32_t attempts, + uint32_t attempts_period, + osMutexId_t access, + bool isExaminationFirmware, + EventUpdateFunc *eventUpdateFunc, + void *envUpdateFunc, + tLoggerToSerialPort *log); + +void GsmFirmware_Start(tGsmFirmware *env); +void StartUpdateFirmware(tGsmFirmware *env); + +#endif //GETGSMFIRMWARE_H diff --git a/Gsm_HttpGet.c b/Gsm_HttpGet.c new file mode 100755 index 0000000..e890a73 --- /dev/null +++ b/Gsm_HttpGet.c @@ -0,0 +1,70 @@ +// +// Created by xemon on 10.07.23. +// + +#include +#include "Gsm_HttpGet.h" + + +static size_t Gsm_HttpGet_Open_Dir(tAtCmd *env, char *url, size_t urlSize) { + AtCommandResult res; + + res = AtGsmSimComA7600_HttpInit(env); + if (res != AT_OK) { + return 0; + } + + res = AtGsmSimComA7600_HttpSetUrl(env, url, urlSize); + if (res != AT_OK) { + return 0; + } + + uint16_t responseCode; + size_t len; + + res = AtGsmSimComA7600_HttpMethodAction(env, eAtGsmSimComA7600_HttpMethod_GET, &responseCode, &len, 10000); + + if (res != AT_OK) { + return 0; + } + if (responseCode != 200) { + return 0; + } + + return len; +} + +static size_t Gsm_HttpGet_Read_Dir(tAtCmd *env, uint8_t *data, size_t dataLimit) { + size_t read; + AtCommandResult res = AtGsmSimComA7600_HttpRead(env, data, 0, dataLimit, &read); + if (res != AT_OK) { return 0; } + return read; +} + + +size_t Gsm_HttpGet_Open(tAtCmd *env, char *url, size_t urlSize) { + size_t res = 0; + if (osMutexAcquire(env->access, 2000) == osOK) { + res = Gsm_HttpGet_Open_Dir(env, url, urlSize); + osMutexRelease(env->access); + } + return res; +} + +size_t Gsm_HttpGet_Read(tAtCmd *env, uint8_t *data, size_t dataLimit) { + size_t res = 0; + if (osMutexAcquire(env->access, 2000) == osOK) { + res = Gsm_HttpGet_Read_Dir(env, data, dataLimit); + osMutexRelease(env->access); + } + return res; +} + +bool Gsm_HttpGet_Close(tAtCmd *env) { + bool res = false; + if (osMutexAcquire(env->access, 2000) == osOK) { + res = AtGsmSimComA7600_HttpTerminate(env) == AT_OK; + osMutexRelease(env->access); + } + return res; +} \ No newline at end of file diff --git a/Gsm_HttpGet.h b/Gsm_HttpGet.h new file mode 100644 index 0000000..702b64b --- /dev/null +++ b/Gsm_HttpGet.h @@ -0,0 +1,12 @@ +// +// Created by cfif on 03.07.2024. +// + +#ifndef SMART_COMPONENTS_UPDATE_GSM_HTTPGET_H +#define SMART_COMPONENTS_UPDATE_GSM_HTTPGET_H + +size_t Gsm_HttpGet_Open(tAtCmd *env, char *url, size_t urlSize); +size_t Gsm_HttpGet_Read(tAtCmd *env, uint8_t *data, size_t dataLimit); +bool Gsm_HttpGet_Close(tAtCmd *env); + +#endif //SMART_COMPONENTS_UPDATE_GSM_HTTPGET_H diff --git a/modular.json b/modular.json new file mode 100755 index 0000000..0dd1901 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file