mirror of
https://github.com/openshwprojects/OpenBK7231T_App.git
synced 2026-02-04 15:45:40 +00:00
ota cosmetic (#1762)
* step 1 * Update obk_main.mk * Update OpenBeken.mk * Update obk_main.cmake * Update hal_ota_bk7231.c * Update hal_ota_bk7231.c * m * split * guards * Update hal_ota_bl602.c * Update hal_ota_bl602.c * bk * better * header * w * TMP * tttttttt * Update rest_interface.c * hal_ota is xradio header.... * undoi * header * move * xradio * read * fx * t * makefile * move out xradi o read * fx * move out esp * move out bl602 * move out beken, ln * move out w8 * ecr tr * realtek * Update rest_interface.c * win * forgot * tr6260 split * Update hal_ota_tr6260.c * rename ota_progress * use OTA_GetProgress on all paltforms * fx * not needed header * call OTA_IncrementProgress on OTA so we at laest know that something is happening
This commit is contained in:
@ -360,6 +360,7 @@
|
||||
<ClCompile Include="src\hal\win32\hal_flashVars_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_generic_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_main_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_ota_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_pins_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_wifi_win32.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_uart_win32.c" />
|
||||
@ -1300,4 +1301,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@ -402,6 +402,11 @@
|
||||
<ClCompile Include="src\berry\modules\be_i2c.c" />
|
||||
<ClCompile Include="src\driver\drv_gosundSW2.c" />
|
||||
<ClCompile Include="src\driver\drv_pinMutex.c" />
|
||||
<ClCompile Include="src\driver\drv_ds1820_full.c" />
|
||||
<ClCompile Include="src\driver\drv_ds1820_common.c" />
|
||||
<ClCompile Include="src\driver\drv_soft_spi.c" />
|
||||
<ClCompile Include="src\driver\drv_spi_flash.c" />
|
||||
<ClCompile Include="src\hal\win32\hal_ota_win32.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\base64\base64.h" />
|
||||
@ -610,6 +615,7 @@
|
||||
<ClInclude Include="libraries\berry\generate\be_fixed_sys.h" />
|
||||
<ClInclude Include="libraries\berry\generate\be_fixed_time.h" />
|
||||
<ClInclude Include="libraries\berry\generate\be_fixed_undefined.h" />
|
||||
<ClInclude Include="src\driver\drv_soft_spi.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\platforms\bk7231t\bk7231t_os\beken378\func\include\net_param_pub.h" />
|
||||
|
||||
@ -34,6 +34,7 @@ APP_C += $(OBK_DIR)/hal/bk7231/hal_main_bk7231.c
|
||||
APP_C += $(OBK_DIR)/hal/bk7231/hal_pins_bk7231.c
|
||||
APP_C += $(OBK_DIR)/hal/bk7231/hal_wifi_bk7231.c
|
||||
APP_C += $(OBK_DIR)/hal/bk7231/hal_uart_bk7231.c
|
||||
APP_C += $(OBK_DIR)/hal/bk7231/hal_ota_bk7231.c
|
||||
|
||||
OBK_SRCS = $(OBK_DIR)/
|
||||
include $(OBK_DIR)/../platforms/obk_main.mk
|
||||
|
||||
@ -15,6 +15,7 @@ CSRCS += hal/ecr6600/hal_main_ecr6600.c
|
||||
CSRCS += hal/ecr6600/hal_pins_ecr6600.c
|
||||
CSRCS += hal/ecr6600/hal_wifi_ecr6600.c
|
||||
CSRCS += hal/ecr6600/hal_uart_ecr6600.c
|
||||
CSRCS += hal/ecr6600/hal_ota_ecr6600.c
|
||||
|
||||
OBK_SRCS =
|
||||
include $(TOPDIR)/../../platforms/obk_main.mk
|
||||
|
||||
@ -14,6 +14,7 @@ set(PROJ_ALL_SRC
|
||||
${OBK_SRCS}hal/espidf/hal_pins_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_wifi_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_uart_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_ota_espidf.c
|
||||
${OBKM_SRC}
|
||||
${BERRY_SRC_C}
|
||||
../../../libraries/mqtt_patched.c
|
||||
|
||||
@ -13,6 +13,7 @@ set(PROJ_ALL_SRC
|
||||
${OBK_SRCS}hal/espidf/hal_pins_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_wifi_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_uart_espidf.c
|
||||
${OBK_SRCS}hal/espidf/hal_ota_espidf.c
|
||||
${OBKM_SRC}
|
||||
${BERRY_SRC_C}
|
||||
../../../libraries/mqtt_patched.c
|
||||
|
||||
@ -23,6 +23,7 @@ set(PROJ_ALL_SRC
|
||||
${OBK_SRCS}hal/ln882h/hal_main_ln882h.c
|
||||
${OBK_SRCS}hal/ln882h/hal_pins_ln882h.c
|
||||
${OBK_SRCS}hal/ln882h/hal_wifi_ln882h.c
|
||||
${OBK_SRCS}hal/ln882h/hal_ota_ln882h.c
|
||||
main.c
|
||||
usr_app.c
|
||||
bsp/serial_hw.c
|
||||
|
||||
@ -16,6 +16,7 @@ SRC_C += $(OBK_DIR)/src/hal/realtek/hal_flashVars_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_generic_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_pins_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_wifi_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_ota_realtek.c
|
||||
|
||||
OBK_SRCS = $(OBK_DIR)/src/
|
||||
include $(OBK_DIR)/platforms/obk_main.mk
|
||||
|
||||
@ -20,6 +20,7 @@ SRC_C += $(OBK_DIR)/src/hal/realtek/hal_flashVars_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_generic_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_pins_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_wifi_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_ota_realtek.c
|
||||
|
||||
OBK_SRCS = $(OBK_DIR)/src/
|
||||
include $(OBK_DIR)/platforms/obk_main.mk
|
||||
|
||||
@ -13,6 +13,7 @@ CSRC += hal/realtek/hal_flashVars_realtek.c
|
||||
CSRC += hal/realtek/hal_generic_realtek.c
|
||||
CSRC += hal/realtek/hal_pins_realtek.c
|
||||
CSRC += hal/realtek/hal_wifi_realtek.c
|
||||
CSRC += hal/realtek/hal_ota_realtek.c
|
||||
|
||||
OBK_SRCS =
|
||||
include $(EFDIR)/../platforms/obk_main.mk
|
||||
|
||||
@ -51,6 +51,7 @@ target_sources(
|
||||
${OBK_SRCS}hal/realtek/hal_flashVars_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_generic_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_pins_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_ota_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_wifi_realtek_new.c
|
||||
${OBK_SRCS}hal/realtek/rtl8721da/hal_main_rtl8721da.c
|
||||
${OBK_SRCS}hal/realtek/rtl8720e/hal_pins_rtl8720e.c
|
||||
|
||||
@ -51,6 +51,7 @@ target_sources(
|
||||
${OBK_SRCS}hal/realtek/hal_flashVars_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_generic_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_pins_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_ota_realtek.c
|
||||
${OBK_SRCS}hal/realtek/hal_wifi_realtek_new.c
|
||||
${OBK_SRCS}hal/realtek/rtl8721da/hal_main_rtl8721da.c
|
||||
${OBK_SRCS}hal/realtek/rtl8721da/hal_pins_rtl8721da.c
|
||||
|
||||
@ -15,6 +15,7 @@ SRC_C += $(OBK_DIR)/src/hal/realtek/hal_flashVars_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_generic_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_pins_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_wifi_realtek.c
|
||||
SRC_C += $(OBK_DIR)/src/hal/realtek/hal_ota_realtek.c
|
||||
|
||||
OBK_SRCS = $(OBK_DIR)/src/
|
||||
include $(OBK_DIR)/platforms/obk_main.mk
|
||||
|
||||
@ -11,6 +11,7 @@ CSRCS += hal/tr6260/hal_generic_tr6260.c
|
||||
CSRCS += hal/tr6260/hal_main_tr6260.c
|
||||
CSRCS += hal/tr6260/hal_pins_tr6260.c
|
||||
CSRCS += hal/tr6260/hal_wifi_tr6260.c
|
||||
CSRCS += hal/tr6260/hal_ota_tr6260.c
|
||||
|
||||
OBK_SRCS =
|
||||
include $(OBK_PATH)/../platforms/obk_main.mk
|
||||
|
||||
@ -28,6 +28,7 @@ CSRCS += $(_SHARED_APP)/hal/w800/hal_generic_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_main_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_pins_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_wifi_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_ota_w800.c
|
||||
CSRCS += main.c
|
||||
|
||||
OBK_SRCS = $(_SHARED_APP)/
|
||||
|
||||
@ -22,6 +22,7 @@ CSRCS += $(_SHARED_APP)/hal/w800/hal_main_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_pins_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_wifi_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_uart_w800.c
|
||||
CSRCS += $(_SHARED_APP)/hal/w800/hal_ota_w800.c
|
||||
|
||||
OBK_SRCS = $(_SHARED_APP)/
|
||||
include $(_SHARED_APP)/../platforms/obk_main.mk
|
||||
|
||||
@ -9,6 +9,7 @@ SRCS += $(OBK_SRCS)hal/xradio/hal_pins_xradio
|
||||
SRCS += $(OBK_SRCS)hal/xradio/hal_flashConfig_xradio
|
||||
SRCS += $(OBK_SRCS)hal/xradio/hal_flashVars_xradio
|
||||
SRCS += $(OBK_SRCS)hal/xradio/hal_uart_xradio
|
||||
SRCS += $(OBK_SRCS)hal/xradio/hal_ota_xradio
|
||||
SRCS += $(OBK_SRCS)hal/xradio/xr809/hal_pins_xr809
|
||||
SRCS += $(OBK_SRCS)hal/xradio/xr806/hal_pins_xr806
|
||||
SRCS += $(OBK_SRCS)hal/xradio/xr872/hal_pins_xr872
|
||||
|
||||
@ -52,7 +52,6 @@ set(OBKM_SRC
|
||||
${OBK_SRCS}httpclient/utils_net.c
|
||||
${OBK_SRCS}httpclient/utils_timer.c
|
||||
${OBK_SRCS}littlefs/our_lfs.c
|
||||
${OBK_SRCS}ota/ota.c
|
||||
|
||||
${OBK_SRCS}driver/drv_main.c
|
||||
|
||||
|
||||
@ -69,7 +69,6 @@ OBKM_SRC += $(OBK_SRCS)httpclient/utils_timer.c
|
||||
OBKM_SRC += $(OBK_SRCS)littlefs/lfs_util.c
|
||||
OBKM_SRC += $(OBK_SRCS)littlefs/lfs.c
|
||||
OBKM_SRC += $(OBK_SRCS)littlefs/our_lfs.c
|
||||
OBKM_SRC += $(OBK_SRCS)ota/ota.c
|
||||
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_main.c
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include "../hal/hal_flashVars.h"
|
||||
#include "../logging/logging.h"
|
||||
#include "../mqtt/new_mqtt.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
#include "drv_local.h"
|
||||
#include "drv_ntp.h"
|
||||
#include "drv_public.h"
|
||||
@ -330,9 +330,7 @@ commandResult_t BL09XX_ResetEnergyCounterEx(int asensdatasetix, float* pvalue)
|
||||
energyCounterStamp[asensdatasetix] = xTaskGetTickCount();
|
||||
}
|
||||
ConsumptionResetTime = (time_t)NTP_GetCurrentTime();
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress()==-1)
|
||||
#endif
|
||||
if (OTA_GetProgress()==-1)
|
||||
{
|
||||
BL09XX_SaveEmeteringStatistics();
|
||||
lastConsumptionSaveStamp = xTaskGetTickCount();
|
||||
@ -721,9 +719,7 @@ void BL_ProcessUpdate(float voltage, float current, float power,
|
||||
//MQTT_PublishMain_StringFloat(sensdataset->sensors[OBK_CONSUMPTION_YESTERDAY].names.name_mqtt, BL_ChangeEnergyUnitIfNeeded(sensors[OBK_CONSUMPTION_YESTERDAY].lastReading ),
|
||||
// sensdataset->sensors[OBK_CONSUMPTION_YESTERDAY].rounding_decimals, 0);
|
||||
//stat_updatesSent++;
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress()==-1)
|
||||
#endif
|
||||
if (OTA_GetProgress()==-1)
|
||||
{
|
||||
BL09XX_SaveEmeteringStatistics();
|
||||
lastConsumptionSaveStamp = xTaskGetTickCount();
|
||||
@ -917,9 +913,7 @@ void BL_ProcessUpdate(float voltage, float current, float power,
|
||||
if (((sensdataset->sensors[OBK_CONSUMPTION_TOTAL].lastReading - lastSavedEnergyCounterValue[asensdatasetix]) >= changeSavedThresholdEnergy) ||
|
||||
((xTaskGetTickCount() - lastConsumptionSaveStamp) >= (6 * 3600 * 1000 / portTICK_PERIOD_MS)))
|
||||
{
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() == -1)
|
||||
#endif
|
||||
if (OTA_GetProgress() == -1)
|
||||
{
|
||||
lastSavedEnergyCounterValue[asensdatasetix] = (float)sensdataset->sensors[OBK_CONSUMPTION_TOTAL].lastReading;
|
||||
BL09XX_SaveEmeteringStatistics();
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#include "../httpserver/new_http.h"
|
||||
#include "../hal/hal_pins.h"
|
||||
#include "../hal/hal_adc.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
|
||||
static int g_noChangeTimePassed = 0; // time without change. Every event in any of the doorsensor channels resets it.
|
||||
static int g_emergencyTimeWithNoConnection = 0; // time without connection to MQTT. Extends the interval till Deep Sleep until connection is established or EMERGENCY_TIME_TO_SLEEP_WITHOUT_MQTT
|
||||
@ -110,11 +110,7 @@ void DoorDeepSleep_QueueNewEvents() {
|
||||
|
||||
void DoorDeepSleep_OnEverySecond() {
|
||||
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() >= 0) {
|
||||
#else
|
||||
if (false) {
|
||||
#endif
|
||||
if (OTA_GetProgress() >= 0) {
|
||||
// update active
|
||||
g_noChangeTimePassed = 0;
|
||||
g_emergencyTimeWithNoConnection = 0;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include "../cmnds/cmd_public.h"
|
||||
#include "../httpserver/new_http.h"
|
||||
#include "../logging/logging.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
|
||||
#include "drv_ntp.h"
|
||||
|
||||
@ -718,15 +718,11 @@ void NTP_OnEverySecond()
|
||||
if (b_ntp_simulatedTime) {
|
||||
return;
|
||||
}
|
||||
#elif PLATFORM_BL602
|
||||
#elif PLATFORM_W600 || PLATFORM_W800
|
||||
#elif PLATFORM_XR809
|
||||
#elif PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() != -1)
|
||||
#endif
|
||||
if (OTA_GetProgress() != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(g_ntp_socket == 0) {
|
||||
// if no socket, this is a reconnect delay
|
||||
if(g_ntp_delay > 0) {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#include "../cmnds/cmd_public.h"
|
||||
#include "../httpserver/new_http.h"
|
||||
#include "../logging/logging.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
|
||||
#include "drv_ntp.h"
|
||||
|
||||
|
||||
@ -1,20 +1,15 @@
|
||||
#include "ota.h"
|
||||
#include "../hal_ota.h"
|
||||
|
||||
#if defined(PLATFORM_W600)
|
||||
|
||||
//W600 uses OTA functions from its SDK.
|
||||
|
||||
#elif PLATFORM_BEKEN
|
||||
|
||||
#include "../new_common.h"
|
||||
#include "../new_cfg.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "typedef.h"
|
||||
#include "flash_pub.h"
|
||||
//#include "flash.h"
|
||||
#include "../logging/logging.h"
|
||||
#include "../httpclient/http_client.h"
|
||||
#include "../driver/drv_public.h"
|
||||
#include "../driver/drv_bl_shared.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "../../httpclient/http_client.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../../driver/drv_public.h"
|
||||
#include "../../driver/drv_bl_shared.h"
|
||||
|
||||
static unsigned char *sector = (void *)0;
|
||||
int sectorlen = 0;
|
||||
@ -31,6 +26,11 @@ extern UINT32 flash_read(char *user_buf, UINT32 count, UINT32 address);
|
||||
extern UINT32 flash_write(char *user_buf, UINT32 count, UINT32 address);
|
||||
extern UINT32 flash_ctrl(UINT32 cmd, void *parm);
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = flash_read((char*)buffer, readlen, startaddr);
|
||||
return res;
|
||||
}
|
||||
|
||||
int init_ota(unsigned int startaddr){
|
||||
flash_init();
|
||||
@ -112,7 +112,6 @@ static void store_sector(unsigned int addr, unsigned char *data){
|
||||
OTA_IncrementProgress(SECTOR_SIZE);
|
||||
}
|
||||
|
||||
#if ENABLE_SEND_POSTANDGET
|
||||
|
||||
httprequest_t httprequest;
|
||||
|
||||
@ -221,42 +220,53 @@ void otarequest(const char *urlin){
|
||||
OTA_ResetProgress();
|
||||
OTA_IncrementProgress(1);
|
||||
}
|
||||
#else
|
||||
|
||||
void otarequest(const char *urlin) {
|
||||
addLogAdv(LOG_INFO, LOG_FEATURE_OTA, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***** SDK independent code from this point. ******/
|
||||
int ota_status = -1;
|
||||
int total_bytes = 0;
|
||||
|
||||
int ota_progress()
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
return ota_status;
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
init_ota(startaddr);
|
||||
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
if (writelen < 0 || (startaddr + writelen > maxaddr))
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen);
|
||||
return http_rest_error(request, -20, "writelen < 0 or end > 0x200000");
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
//ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen);
|
||||
add_otadata((unsigned char*)writebuf, writelen);
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
close_ota();
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void OTA_ResetProgress()
|
||||
{
|
||||
ota_status = -1;
|
||||
}
|
||||
|
||||
extern void OTA_IncrementProgress(int value)
|
||||
{
|
||||
ota_status += value;
|
||||
}
|
||||
|
||||
int OTA_GetTotalBytes()
|
||||
{
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
extern void OTA_SetTotalBytes(int value)
|
||||
{
|
||||
total_bytes = value;
|
||||
}
|
||||
|
||||
318
src/hal/bl602/hal_ota_bl602.c
Normal file
318
src/hal/bl602/hal_ota_bl602.c
Normal file
@ -0,0 +1,318 @@
|
||||
#ifdef PLATFORM_BL602
|
||||
|
||||
#include <hal_boot2.h>
|
||||
#include <utils_sha256.h>
|
||||
#include <bl_mtd.h>
|
||||
#include <bl_flash.h>
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
|
||||
typedef struct ota_header {
|
||||
union {
|
||||
struct {
|
||||
uint8_t header[16];
|
||||
|
||||
uint8_t type[4];//RAW XZ
|
||||
uint32_t len;//body len
|
||||
uint8_t pad0[8];
|
||||
|
||||
uint8_t ver_hardware[16];
|
||||
uint8_t ver_software[16];
|
||||
|
||||
uint8_t sha256[32];
|
||||
uint32_t unpacked_len;//full len
|
||||
} s;
|
||||
uint8_t _pad[512];
|
||||
} u;
|
||||
} ota_header_t;
|
||||
#define OTA_HEADER_SIZE (sizeof(ota_header_t))
|
||||
|
||||
static int _check_ota_header(ota_header_t *ota_header, uint32_t *ota_len, int *use_xz)
|
||||
{
|
||||
char str[33];//assume max segment size
|
||||
int i;
|
||||
|
||||
memcpy(str, ota_header->u.s.header, sizeof(ota_header->u.s.header));
|
||||
str[sizeof(ota_header->u.s.header)] = '\0';
|
||||
puts("[OTA] [HEADER] ota header is ");
|
||||
puts(str);
|
||||
puts("\r\n");
|
||||
|
||||
memcpy(str, ota_header->u.s.type, sizeof(ota_header->u.s.type));
|
||||
str[sizeof(ota_header->u.s.type)] = '\0';
|
||||
puts("[OTA] [HEADER] file type is ");
|
||||
puts(str);
|
||||
puts("\r\n");
|
||||
if (strstr(str, "XZ")) {
|
||||
*use_xz = 1;
|
||||
}
|
||||
else {
|
||||
*use_xz = 0;
|
||||
}
|
||||
|
||||
memcpy(ota_len, &(ota_header->u.s.len), 4);
|
||||
printf("[OTA] [HEADER] file length (exclude ota header) is %lu\r\n", *ota_len);
|
||||
|
||||
memcpy(str, ota_header->u.s.ver_hardware, sizeof(ota_header->u.s.ver_hardware));
|
||||
str[sizeof(ota_header->u.s.ver_hardware)] = '\0';
|
||||
puts("[OTA] [HEADER] ver_hardware is ");
|
||||
puts(str);
|
||||
puts("\r\n");
|
||||
|
||||
memcpy(str, ota_header->u.s.ver_software, sizeof(ota_header->u.s.ver_software));
|
||||
str[sizeof(ota_header->u.s.ver_software)] = '\0';
|
||||
puts("[OTA] [HEADER] ver_software is ");
|
||||
puts(str);
|
||||
puts("\r\n");
|
||||
|
||||
memcpy(str, ota_header->u.s.sha256, sizeof(ota_header->u.s.sha256));
|
||||
str[sizeof(ota_header->u.s.sha256)] = '\0';
|
||||
puts("[OTA] [HEADER] sha256 is ");
|
||||
for (i = 0; i < sizeof(ota_header->u.s.sha256); i++) {
|
||||
printf("%02X", str[i]);
|
||||
}
|
||||
puts("\r\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
int sockfd, i;
|
||||
int ret;
|
||||
struct hostent* hostinfo;
|
||||
uint8_t* recv_buffer;
|
||||
struct sockaddr_in dest;
|
||||
iot_sha256_context ctx;
|
||||
uint8_t sha256_result[32];
|
||||
uint8_t sha256_img[32];
|
||||
bl_mtd_handle_t handle;
|
||||
//init_ota(startaddr);
|
||||
|
||||
|
||||
#define OTA_PROGRAM_SIZE (512)
|
||||
int ota_header_found, use_xz;
|
||||
ota_header_t* ota_header = 0;
|
||||
|
||||
ret = bl_mtd_open(BL_MTD_PARTITION_NAME_FW_DEFAULT, &handle, BL_MTD_OPEN_FLAG_BACKUP);
|
||||
if (ret)
|
||||
{
|
||||
return http_rest_error(request, -20, "Open Default FW partition failed");
|
||||
}
|
||||
|
||||
recv_buffer = pvPortMalloc(OTA_PROGRAM_SIZE);
|
||||
|
||||
unsigned int buffer_offset, flash_offset, ota_addr;
|
||||
uint32_t bin_size, part_size, running_size;
|
||||
uint8_t activeID;
|
||||
HALPartition_Entry_Config ptEntry;
|
||||
|
||||
activeID = hal_boot2_get_active_partition();
|
||||
|
||||
printf("Starting OTA test. OTA bin addr is %p, incoming len %i\r\n", recv_buffer, writelen);
|
||||
|
||||
printf("[OTA] [TEST] activeID is %u\r\n", activeID);
|
||||
|
||||
if (hal_boot2_get_active_entries(BOOT2_PARTITION_TYPE_FW, &ptEntry))
|
||||
{
|
||||
printf("PtTable_Get_Active_Entries fail\r\n");
|
||||
vPortFree(recv_buffer);
|
||||
bl_mtd_close(handle);
|
||||
return http_rest_error(request, -20, "PtTable_Get_Active_Entries fail");
|
||||
}
|
||||
ota_addr = ptEntry.Address[!ptEntry.activeIndex];
|
||||
bin_size = ptEntry.maxLen[!ptEntry.activeIndex];
|
||||
part_size = ptEntry.maxLen[!ptEntry.activeIndex];
|
||||
running_size = ptEntry.maxLen[ptEntry.activeIndex];
|
||||
(void)part_size;
|
||||
/*XXX if you use bin_size is product env, you may want to set bin_size to the actual
|
||||
* OTA BIN size, and also you need to splilt XIP_SFlash_Erase_With_Lock into
|
||||
* serveral pieces. Partition size vs bin_size check is also needed
|
||||
*/
|
||||
printf("Starting OTA test. OTA size is %lu\r\n", bin_size);
|
||||
|
||||
printf("[OTA] [TEST] activeIndex is %u, use OTA address=%08x\r\n", ptEntry.activeIndex, (unsigned int)ota_addr);
|
||||
|
||||
printf("[OTA] [TEST] Erase flash with size %lu...", bin_size);
|
||||
hal_update_mfg_ptable();
|
||||
|
||||
//Erase in chunks, because erasing everything at once is slow and causes issues with http connection
|
||||
uint32_t erase_offset = 0;
|
||||
uint32_t erase_len = 0;
|
||||
while (erase_offset < bin_size)
|
||||
{
|
||||
erase_len = bin_size - erase_offset;
|
||||
if (erase_len > 0x10000)
|
||||
{
|
||||
erase_len = 0x10000; //Erase in 64kb chunks
|
||||
}
|
||||
bl_mtd_erase(handle, erase_offset, erase_len);
|
||||
printf("[OTA] Erased: %lu / %lu \r\n", erase_offset, erase_len);
|
||||
erase_offset += erase_len;
|
||||
rtos_delay_milliseconds(100);
|
||||
}
|
||||
printf("[OTA] Done\r\n");
|
||||
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
// get header
|
||||
// recv_buffer
|
||||
//buffer_offset = 0;
|
||||
//do {
|
||||
// int take_len;
|
||||
|
||||
// take_len = OTA_PROGRAM_SIZE - buffer_offset;
|
||||
|
||||
// memcpy(recv_buffer + buffer_offset, writebuf, writelen);
|
||||
// buffer_offset += writelen;
|
||||
|
||||
|
||||
// if (towrite > 0) {
|
||||
// writebuf = request->received;
|
||||
// writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
// if (writelen < 0) {
|
||||
// ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
// }
|
||||
// }
|
||||
//} while(true)
|
||||
|
||||
buffer_offset = 0;
|
||||
flash_offset = 0;
|
||||
ota_header = 0;
|
||||
use_xz = 0;
|
||||
|
||||
utils_sha256_init(&ctx);
|
||||
utils_sha256_starts(&ctx);
|
||||
memset(sha256_result, 0, sizeof(sha256_result));
|
||||
do
|
||||
{
|
||||
char* useBuf = writebuf;
|
||||
int useLen = writelen;
|
||||
|
||||
if (ota_header == 0)
|
||||
{
|
||||
int take_len;
|
||||
|
||||
// how much left for header?
|
||||
take_len = OTA_PROGRAM_SIZE - buffer_offset;
|
||||
// clamp to available len
|
||||
if (take_len > useLen)
|
||||
take_len = useLen;
|
||||
printf("Header takes %i. ", take_len);
|
||||
memcpy(recv_buffer + buffer_offset, writebuf, take_len);
|
||||
buffer_offset += take_len;
|
||||
useBuf = writebuf + take_len;
|
||||
useLen = writelen - take_len;
|
||||
|
||||
if (buffer_offset >= OTA_PROGRAM_SIZE)
|
||||
{
|
||||
ota_header = (ota_header_t*)recv_buffer;
|
||||
if (strncmp((const char*)ota_header, "BL60X_OTA", 9))
|
||||
{
|
||||
return http_rest_error(request, -20, "Invalid header ident");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ota_header && useLen)
|
||||
{
|
||||
|
||||
|
||||
if (flash_offset + useLen >= part_size)
|
||||
{
|
||||
return http_rest_error(request, -20, "Too large bin");
|
||||
}
|
||||
if (ota_header->u.s.unpacked_len != 0xFFFFFFFF && running_size < ota_header->u.s.unpacked_len)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "Unpacked OTA image size (%u) is bigger than running partition size (%u)", ota_header->u.s.unpacked_len, running_size);
|
||||
return http_rest_error(request, -20, "");
|
||||
}
|
||||
//ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen);
|
||||
//add_otadata((unsigned char*)writebuf, writelen);
|
||||
|
||||
printf("Flash takes %i. ", useLen);
|
||||
utils_sha256_update(&ctx, (byte*)useBuf, useLen);
|
||||
bl_mtd_write(handle, flash_offset, useLen, (byte*)useBuf);
|
||||
flash_offset += useLen;
|
||||
}
|
||||
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
|
||||
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
|
||||
if (ota_header == 0)
|
||||
{
|
||||
return http_rest_error(request, -20, "No header found");
|
||||
}
|
||||
utils_sha256_finish(&ctx, sha256_result);
|
||||
puts("\r\nCalculated SHA256 Checksum:");
|
||||
for (i = 0; i < sizeof(sha256_result); i++)
|
||||
{
|
||||
printf("%02X", sha256_result[i]);
|
||||
}
|
||||
puts("\r\nHeader SHA256 Checksum:");
|
||||
for (i = 0; i < sizeof(sha256_result); i++)
|
||||
{
|
||||
printf("%02X", ota_header->u.s.sha256[i]);
|
||||
}
|
||||
if (memcmp(ota_header->u.s.sha256, sha256_result, sizeof(sha256_img)))
|
||||
{
|
||||
/*Error found*/
|
||||
return http_rest_error(request, -20, "SHA256 NOT Correct");
|
||||
}
|
||||
printf("[OTA] [TCP] prepare OTA partition info\r\n");
|
||||
ptEntry.len = total;
|
||||
printf("[OTA] [TCP] Update PARTITION, partition len is %lu\r\n", ptEntry.len);
|
||||
hal_boot2_update_ptable(&ptEntry);
|
||||
printf("[OTA] [TCP] Rebooting\r\n");
|
||||
//close_ota();
|
||||
vPortFree(recv_buffer);
|
||||
utils_sha256_free(&ctx);
|
||||
bl_mtd_close(handle);
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = bl_flash_read(startaddr, (uint8_t *)buffer, readlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif // PLATFORM_BL602
|
||||
|
||||
|
||||
97
src/hal/ecr6600/hal_ota_ecr6600.c
Normal file
97
src/hal/ecr6600/hal_ota_ecr6600.c
Normal file
@ -0,0 +1,97 @@
|
||||
#if PLATFORM_ECR6600
|
||||
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../hal_ota.h"
|
||||
|
||||
#include "flash.h"
|
||||
|
||||
extern int ota_init(void);
|
||||
extern int ota_write(unsigned char* data, unsigned int len);
|
||||
extern int ota_done(bool reset);
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = drv_spiflash_read(startaddr, (uint8_t*)buffer, readlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (request->contentLength > 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "Content-length is 0");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
if (ota_init() != 0)
|
||||
{
|
||||
ret = -1;
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (ota_write((unsigned char*)writebuf, writelen) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
goto update_ota_exit;
|
||||
}
|
||||
delay_ms(10);
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", writelen, total);
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
|
||||
update_ota_exit:
|
||||
if (ret != -1)
|
||||
{
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "OTA is successful");
|
||||
ota_done(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "OTA failed. Reboot to retry");
|
||||
return http_rest_error(request, ret, "error");
|
||||
}
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
146
src/hal/espidf/hal_ota_espidf.c
Normal file
146
src/hal/espidf/hal_ota_espidf.c
Normal file
@ -0,0 +1,146 @@
|
||||
#if PLATFORM_ESPIDF || PLATFORM_ESP8266
|
||||
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../../logging/logging.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_app_format.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_partition.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_wifi.h"
|
||||
#if PLATFORM_ESPIDF
|
||||
#include "esp_flash.h"
|
||||
#include "esp_pm.h"
|
||||
#else
|
||||
#include "esp_image_format.h"
|
||||
#include "spi_flash.h"
|
||||
#define esp_flash_read(a,b,c,d) spi_flash_read(c,b,d)
|
||||
#define OTA_WITH_SEQUENTIAL_WRITES OTA_SIZE_UNKNOWN
|
||||
#define esp_ota_abort esp_ota_end
|
||||
#endif
|
||||
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start!\r\n");
|
||||
esp_err_t err;
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
const esp_partition_t* update_partition = NULL;
|
||||
const esp_partition_t* running = esp_ota_get_running_partition();
|
||||
update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
esp_wifi_set_ps(WIFI_PS_NONE);
|
||||
bool image_header_was_checked = false;
|
||||
do
|
||||
{
|
||||
if (image_header_was_checked == false)
|
||||
{
|
||||
esp_app_desc_t new_app_info;
|
||||
if (towrite > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t))
|
||||
{
|
||||
memcpy(&new_app_info, &writebuf[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "New firmware version: %s", new_app_info.version);
|
||||
|
||||
esp_app_desc_t running_app_info;
|
||||
if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Running firmware version: %s", running_app_info.version);
|
||||
}
|
||||
|
||||
image_header_was_checked = true;
|
||||
|
||||
err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_begin failed (%s)", esp_err_to_name(err));
|
||||
esp_ota_abort(update_handle);
|
||||
return -1;
|
||||
}
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "esp_ota_begin succeeded");
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "received package is not fit len");
|
||||
esp_ota_abort(update_handle);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
err = esp_ota_write(update_handle, (const void*)writebuf, writelen);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
esp_ota_abort(update_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", writelen, total);
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "OTA in progress: 100%%, total Write binary data length: %d", total);
|
||||
|
||||
err = esp_ota_end(update_handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
if (err == ESP_ERR_OTA_VALIDATE_FAILED)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "Image validation failed, image is corrupted");
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_end failed (%s)!", esp_err_to_name(err));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
err = esp_ota_set_boot_partition(update_partition);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = esp_flash_read(NULL, (void*)buffer, startaddr, readlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,19 +13,6 @@
|
||||
#define START_ADR_OF_BK_PARTITION_OTA 0x132000
|
||||
#endif
|
||||
|
||||
/// @brief Initialise OTA flash starting at startaddr. Only used for Beken SDK.
|
||||
/// @param startaddr
|
||||
/// @return
|
||||
int init_ota(unsigned int startaddr);
|
||||
|
||||
/// @brief Add any length of data to OTA. Only used for Beken SDK.
|
||||
/// @param data
|
||||
/// @param len
|
||||
void add_otadata(unsigned char *data, int len);
|
||||
|
||||
/// @brief Finalise OTA flash (write last sector if incomplete). Only used for Beken SDK.
|
||||
void close_ota();
|
||||
|
||||
/// @brief Handle OTA request. Only used for Beken SDK.
|
||||
/// @param urlin
|
||||
void otarequest(const char *urlin);
|
||||
@ -35,7 +22,7 @@ void otarequest(const char *urlin);
|
||||
|
||||
/// @brief Indicates current OTA progress status. A non -ve value indicates active OTA.
|
||||
/// @return
|
||||
int ota_progress();
|
||||
int OTA_GetProgress();
|
||||
|
||||
/// @brief Reset OTA progress status to -1. This can be called from other SDKs.
|
||||
/// @param value
|
||||
@ -53,5 +40,7 @@ int OTA_GetTotalBytes();
|
||||
/// @param value
|
||||
void OTA_SetTotalBytes(int value);
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr);
|
||||
|
||||
#endif /* __OTA_H__ */
|
||||
|
||||
315
src/hal/ln882h/hal_ota_ln882h.c
Normal file
315
src/hal/ln882h/hal_ota_ln882h.c
Normal file
@ -0,0 +1,315 @@
|
||||
#ifdef PLATFORM_LN882H
|
||||
|
||||
#include "hal/hal_flash.h"
|
||||
#include "flash_partition_table.h"
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../hal_ota.h"
|
||||
|
||||
#include "ota_port.h"
|
||||
#include "ota_image.h"
|
||||
#include "ota_types.h"
|
||||
#include "hal/hal_flash.h"
|
||||
#include "netif/ethernetif.h"
|
||||
#include "flash_partition_table.h"
|
||||
|
||||
|
||||
#define KV_OTA_UPG_STATE ("kv_ota_upg_state")
|
||||
#define HTTP_OTA_DEMO_STACK_SIZE (1024 * 16)
|
||||
|
||||
#define SECTOR_SIZE_4KB (1024 * 4)
|
||||
|
||||
static char g_http_uri_buff[512] = "http://192.168.122.48:9090/ota-images/otaimage-v1.3.bin";
|
||||
|
||||
// a block to save http data.
|
||||
static char *temp4K_buf = NULL;
|
||||
static int temp4k_offset = 0;
|
||||
|
||||
// where to save OTA data in flash.
|
||||
static int32_t flash_ota_start_addr = OTA_SPACE_OFFSET;
|
||||
static int32_t flash_ota_offset = 0;
|
||||
static uint8_t is_persistent_started = LN_FALSE;
|
||||
static uint8_t is_ready_to_verify = LN_FALSE;
|
||||
static uint8_t is_precheck_ok = LN_FALSE;
|
||||
static uint8_t httpc_ota_started = 0;
|
||||
|
||||
/**
|
||||
* @brief Pre-check the image file to be downloaded.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] app_offset The offset of the APP partition in Flash.
|
||||
* @param[in] ota_hdr pointer to ota partition info struct.
|
||||
*
|
||||
* @return whether the check is successful.
|
||||
* @retval #LN_TRUE successful.
|
||||
* @retval #LN_FALSE failed.
|
||||
*/
|
||||
static int ota_download_precheck(uint32_t app_offset, image_hdr_t * ota_hdr)
|
||||
{
|
||||
|
||||
image_hdr_t *app_hdr = NULL;
|
||||
if (NULL == (app_hdr = OS_Malloc(sizeof(image_hdr_t)))) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "[%s:%d] malloc failed.\r\n", __func__, __LINE__);
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
if (OTA_ERR_NONE != image_header_fast_read(app_offset, app_hdr)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "failed to read app header.\r\n");
|
||||
goto ret_err;
|
||||
}
|
||||
|
||||
if ((ota_hdr->image_type == IMAGE_TYPE_ORIGINAL) || \
|
||||
(ota_hdr->image_type == IMAGE_TYPE_ORIGINAL_XZ))
|
||||
{
|
||||
// check version
|
||||
if (((ota_hdr->ver.ver_major << 8) + ota_hdr->ver.ver_minor) == \
|
||||
((app_hdr->ver.ver_major << 8) + app_hdr->ver.ver_minor)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "[%s:%d] same version, do not upgrade!\r\n",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
|
||||
// check file size
|
||||
if (((ota_hdr->img_size_orig + sizeof(image_hdr_t)) > APP_SPACE_SIZE) || \
|
||||
((ota_hdr->img_size_orig_xz + sizeof(image_hdr_t)) > OTA_SPACE_SIZE)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "[%s:%d] size check failed.\r\n", __func__, __LINE__);
|
||||
goto ret_err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//image type not support!
|
||||
goto ret_err;
|
||||
}
|
||||
|
||||
OS_Free(app_hdr);
|
||||
return LN_TRUE;
|
||||
|
||||
ret_err:
|
||||
OS_Free(app_hdr);
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
static int ota_persistent_start(void)
|
||||
{
|
||||
if (NULL == temp4K_buf) {
|
||||
temp4K_buf = OS_Malloc(SECTOR_SIZE_4KB);
|
||||
if (NULL == temp4K_buf) {
|
||||
LOG(LOG_LVL_INFO, "failed to alloc 4KB!!!\r\n");
|
||||
return LN_FALSE;
|
||||
}
|
||||
memset(temp4K_buf, 0, SECTOR_SIZE_4KB);
|
||||
}
|
||||
|
||||
temp4k_offset = 0;
|
||||
flash_ota_start_addr = OTA_SPACE_OFFSET;
|
||||
flash_ota_offset = 0;
|
||||
is_persistent_started = LN_TRUE;
|
||||
return LN_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save block to flash.
|
||||
*
|
||||
* @param buf
|
||||
* @param buf_len
|
||||
* @return return LN_TRUE on success, LN_FALSE on failure.
|
||||
*/
|
||||
static int ota_persistent_write(const char *buf, const int32_t buf_len)
|
||||
{
|
||||
int part_len = SECTOR_SIZE_4KB; // we might have a buffer so large, that we need to write multiple 4K segments ...
|
||||
int buf_offset = 0; // ... and we need to keep track, what is already written
|
||||
|
||||
if (!is_persistent_started) {
|
||||
return LN_TRUE;
|
||||
}
|
||||
|
||||
if (temp4k_offset + buf_len < SECTOR_SIZE_4KB) {
|
||||
// just copy all buf data to temp4K_buf
|
||||
memcpy(temp4K_buf + temp4k_offset, buf, buf_len);
|
||||
temp4k_offset += buf_len;
|
||||
part_len = 0;
|
||||
}
|
||||
while (part_len >= SECTOR_SIZE_4KB) { // so we didn't copy all data to buffer (part_len would be 0 then)
|
||||
// just copy part of buf to temp4K_buf
|
||||
part_len = temp4k_offset + buf_len - buf_offset - SECTOR_SIZE_4KB; // beware, this can be > SECTOR_SIZE_4KB !!!
|
||||
memcpy(temp4K_buf + temp4k_offset, buf + buf_offset, buf_len - buf_offset - part_len);
|
||||
temp4k_offset += buf_len - buf_offset - part_len;
|
||||
buf_offset = buf_len - part_len;
|
||||
|
||||
if (temp4k_offset >= SECTOR_SIZE_4KB) {
|
||||
// write to flash
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "write at flash: 0x%08x (temp4k_offset=%i)\r\n", flash_ota_start_addr + flash_ota_offset, temp4k_offset);
|
||||
|
||||
if (flash_ota_offset == 0) {
|
||||
if (LN_TRUE != ota_download_precheck(APP_SPACE_OFFSET, (image_hdr_t *)temp4K_buf))
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "ota download precheck failed!\r\n");
|
||||
is_precheck_ok = LN_FALSE;
|
||||
return LN_FALSE;
|
||||
}
|
||||
is_precheck_ok = LN_TRUE;
|
||||
}
|
||||
|
||||
hal_flash_erase(flash_ota_start_addr + flash_ota_offset, SECTOR_SIZE_4KB);
|
||||
hal_flash_program(flash_ota_start_addr + flash_ota_offset, SECTOR_SIZE_4KB, (uint8_t *)temp4K_buf);
|
||||
|
||||
flash_ota_offset += SECTOR_SIZE_4KB;
|
||||
memset(temp4K_buf, 0, SECTOR_SIZE_4KB);
|
||||
temp4k_offset = 0;
|
||||
}
|
||||
}
|
||||
if (part_len > 0) {
|
||||
memcpy(temp4K_buf + temp4k_offset, buf + (buf_len - part_len), part_len);
|
||||
temp4k_offset += part_len;
|
||||
}
|
||||
|
||||
return LN_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief save last block and clear flags.
|
||||
* @return return LN_TRUE on success, LN_FALSE on failure.
|
||||
*/
|
||||
static int ota_persistent_finish(void)
|
||||
{
|
||||
if (!is_persistent_started) {
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
// write to flash
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "write at flash: 0x%08x\r\n", flash_ota_start_addr + flash_ota_offset);
|
||||
hal_flash_erase(flash_ota_start_addr + flash_ota_offset, SECTOR_SIZE_4KB);
|
||||
hal_flash_program(flash_ota_start_addr + flash_ota_offset, SECTOR_SIZE_4KB, (uint8_t *)temp4K_buf);
|
||||
|
||||
OS_Free(temp4K_buf);
|
||||
temp4K_buf = NULL;
|
||||
temp4k_offset = 0;
|
||||
|
||||
flash_ota_offset = 0;
|
||||
is_persistent_started = LN_FALSE;
|
||||
return LN_TRUE;
|
||||
}
|
||||
|
||||
static int update_ota_state(void)
|
||||
{
|
||||
upg_state_t state = UPG_STATE_DOWNLOAD_OK;
|
||||
ln_nvds_set_ota_upg_state(state);
|
||||
return LN_TRUE;
|
||||
}
|
||||
/**
|
||||
* @brief check ota image header, body.
|
||||
* @return return LN_TRUE on success, LN_FALSE on failure.
|
||||
*/
|
||||
static int ota_verify_download(void)
|
||||
{
|
||||
image_hdr_t ota_header;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Succeed to verify OTA image content.\r\n");
|
||||
if (OTA_ERR_NONE != image_header_fast_read(OTA_SPACE_OFFSET, &ota_header)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "failed to read ota header.\r\n");
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
if (OTA_ERR_NONE != image_header_verify(&ota_header)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "failed to verify ota header.\r\n");
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
if (OTA_ERR_NONE != image_body_verify(OTA_SPACE_OFFSET, &ota_header)) {
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "failed to verify ota body.\r\n");
|
||||
return LN_FALSE;
|
||||
}
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Succeed to verify OTA image content.\r\n");
|
||||
return LN_TRUE;
|
||||
}
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start!\r\n");
|
||||
if (LN_TRUE != ota_persistent_start())
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start error, exit...\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
//ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen);
|
||||
|
||||
if (LN_TRUE != ota_persistent_write(writebuf, writelen))
|
||||
{
|
||||
// ADDLOG_DEBUG(LOG_FEATURE_OTA, "ota write err.\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtos_delay_milliseconds(10);
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", writelen, total);
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
|
||||
ota_persistent_finish();
|
||||
is_ready_to_verify = LN_TRUE;
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "cb info: recv %d finished, no more data to deal with.\r\n", towrite);
|
||||
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "http client job done, exit...\r\n");
|
||||
if (LN_TRUE == is_precheck_ok)
|
||||
{
|
||||
if ((LN_TRUE == is_ready_to_verify) && (LN_TRUE == ota_verify_download()))
|
||||
{
|
||||
update_ota_state();
|
||||
//ln_chip_reboot();
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Veri bad\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Precheck bad\r\n");
|
||||
}
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = hal_flash_read(startaddr, readlen, (uint8_t *)buffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif // PLATFORM_LN882H
|
||||
|
||||
1048
src/hal/realtek/hal_ota_realtek.c
Normal file
1048
src/hal/realtek/hal_ota_realtek.c
Normal file
File diff suppressed because it is too large
Load Diff
94
src/hal/tr6260/hal_ota_tr6260.c
Normal file
94
src/hal/tr6260/hal_ota_tr6260.c
Normal file
@ -0,0 +1,94 @@
|
||||
#if PLATFORM_TR6260
|
||||
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../hal_ota.h"
|
||||
|
||||
#include "otaHal.h"
|
||||
#include "drv_spiflash.h"
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = hal_spiflash_read(startaddr, (uint8_t*)buffer, readlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (request->contentLength > 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "Content-length is 0");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
if (otaHal_init() != 0)
|
||||
{
|
||||
ret = -1;
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (otaHal_write((unsigned char*)writebuf, writelen) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
goto update_ota_exit;
|
||||
}
|
||||
delay_ms(10);
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", writelen, total);
|
||||
total += writelen;
|
||||
startaddr += writelen;
|
||||
towrite -= writelen;
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
} while ((towrite > 0) && (writelen >= 0));
|
||||
|
||||
update_ota_exit:
|
||||
if (ret != -1)
|
||||
{
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "OTA is successful");
|
||||
otaHal_done();
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "OTA failed. Reboot to retry");
|
||||
return http_rest_error(request, ret, "error");
|
||||
}
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
302
src/hal/w800/hal_ota_w800.c
Normal file
302
src/hal/w800/hal_ota_w800.c
Normal file
@ -0,0 +1,302 @@
|
||||
#if defined(PLATFORM_W800) || defined(PLATFORM_W600)
|
||||
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../logging/logging.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../hal_ota.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "wm_internal_flash.h"
|
||||
#include "wm_socket_fwup.h"
|
||||
#include "wm_fwup.h"
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
#ifdef PLATFORM_W600
|
||||
int nRetCode = 0;
|
||||
char error_message[256];
|
||||
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen);
|
||||
return http_rest_error(request, -20, "writelen < 0");
|
||||
}
|
||||
|
||||
struct pbuf* p;
|
||||
|
||||
//Data is uploaded in 1024 sized chunks, creating a bigger buffer just in case this assumption changes.
|
||||
//The code below is based on sdk\OpenW600\src\app\ota\wm_http_fwup.c
|
||||
char* Buffer = (char*)os_malloc(2048 + 3);
|
||||
memset(Buffer, 0, 2048 + 3);
|
||||
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
int recvLen = 0;
|
||||
int totalLen = 0;
|
||||
//printf("\ntowrite %d writelen=%d\n", towrite, writelen);
|
||||
|
||||
do
|
||||
{
|
||||
if (writelen > 0)
|
||||
{
|
||||
//bk_printf("Copying %d from writebuf to Buffer towrite=%d\n", writelen, towrite);
|
||||
memcpy(Buffer + 3, writebuf, writelen);
|
||||
|
||||
if (recvLen == 0)
|
||||
{
|
||||
T_BOOTER* booter = (T_BOOTER*)(Buffer + 3);
|
||||
bk_printf("magic_no=%u, img_type=%u, zip_type=%u\n", booter->magic_no, booter->img_type, booter->zip_type);
|
||||
|
||||
if (TRUE == tls_fwup_img_header_check(booter))
|
||||
{
|
||||
totalLen = booter->upd_img_len + sizeof(T_BOOTER);
|
||||
OTA_ResetProgress();
|
||||
OTA_SetTotalBytes(totalLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(error_message, "Image header check failed");
|
||||
nRetCode = -19;
|
||||
break;
|
||||
}
|
||||
|
||||
nRetCode = socket_fwup_accept(0, ERR_OK);
|
||||
if (nRetCode != ERR_OK)
|
||||
{
|
||||
sprintf(error_message, "Firmware update startup failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, writelen + 3, PBUF_REF);
|
||||
if (!p)
|
||||
{
|
||||
sprintf(error_message, "Unable to allocate memory for buffer");
|
||||
nRetCode = -18;
|
||||
break;
|
||||
}
|
||||
|
||||
if (recvLen == 0)
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_START;
|
||||
}
|
||||
else if (recvLen == (totalLen - writelen))
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_DATA;
|
||||
}
|
||||
|
||||
*(Buffer + 1) = (writelen >> 8) & 0xFF;
|
||||
*(Buffer + 2) = writelen & 0xFF;
|
||||
p->payload = Buffer;
|
||||
p->len = p->tot_len = writelen + 3;
|
||||
|
||||
nRetCode = socket_fwup_recv(0, p, ERR_OK);
|
||||
if (nRetCode != ERR_OK)
|
||||
{
|
||||
sprintf(error_message, "Firmware data processing failed");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
OTA_IncrementProgress(writelen);
|
||||
recvLen += writelen;
|
||||
printf("Downloaded %d / %d\n", recvLen, totalLen);
|
||||
}
|
||||
|
||||
towrite -= writelen;
|
||||
}
|
||||
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
sprintf(error_message, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
nRetCode = -17;
|
||||
}
|
||||
}
|
||||
} while ((nRetCode == 0) && (towrite > 0) && (writelen >= 0));
|
||||
|
||||
tls_mem_free(Buffer);
|
||||
|
||||
if (nRetCode != 0)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, error_message);
|
||||
socket_fwup_err(0, nRetCode);
|
||||
return http_rest_error(request, nRetCode, error_message);
|
||||
}
|
||||
|
||||
|
||||
#elif PLATFORM_W800
|
||||
int nRetCode = 0;
|
||||
char error_message[256];
|
||||
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen);
|
||||
return http_rest_error(request, -20, "writelen < 0");
|
||||
}
|
||||
|
||||
struct pbuf* p;
|
||||
|
||||
//The code below is based on W600 code and adopted to the differences in sdk\OpenW800\src\app\ota\wm_http_fwup.c
|
||||
// fiexd crashing caused by not checking "writelen" before doing memcpy
|
||||
// e.g. if more than 2 packets arrived before next loop, writelen could be > 2048 !!
|
||||
#define FWUP_MSG_SIZE 3
|
||||
#define MAX_BUFF_SIZE 2048
|
||||
char* Buffer = (char*)os_malloc(MAX_BUFF_SIZE + FWUP_MSG_SIZE);
|
||||
|
||||
if (!Buffer)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "ABORTED: failed to allocate buffer");
|
||||
return http_rest_error(request, -20, "");
|
||||
}
|
||||
|
||||
if (request->contentLength >= 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
|
||||
int recvLen = 0;
|
||||
int totalLen = 0;
|
||||
printf("\ntowrite %d writelen=%d\n", towrite, writelen);
|
||||
|
||||
do
|
||||
{
|
||||
while (writelen > 0)
|
||||
{
|
||||
int actwrite = writelen < MAX_BUFF_SIZE ? writelen : MAX_BUFF_SIZE; // mustn't write more than Buffers size! Will crash else!
|
||||
//bk_printf("Copying %d from writebuf to Buffer (writelen=%d) towrite=%d -- free_heap:%d\n", actwrite, writelen, towrite, xPortGetFreeHeapSize());
|
||||
memset(Buffer, 0, MAX_BUFF_SIZE + FWUP_MSG_SIZE);
|
||||
memcpy(Buffer + FWUP_MSG_SIZE, writebuf, actwrite);
|
||||
if (recvLen == 0)
|
||||
{
|
||||
IMAGE_HEADER_PARAM_ST *booter = (IMAGE_HEADER_PARAM_ST*)(Buffer + FWUP_MSG_SIZE);
|
||||
bk_printf("magic_no=%u, img_type=%u, zip_type=%u, signature=%u\n",
|
||||
booter->magic_no, booter->img_attr.b.img_type, booter->img_attr.b.zip_type, booter->img_attr.b.signature);
|
||||
|
||||
if (TRUE == tls_fwup_img_header_check(booter))
|
||||
{
|
||||
totalLen = booter->img_len + sizeof(IMAGE_HEADER_PARAM_ST);
|
||||
if (booter->img_attr.b.signature)
|
||||
{
|
||||
totalLen += 128;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(error_message, "Image header check failed");
|
||||
nRetCode = -19;
|
||||
break;
|
||||
}
|
||||
|
||||
nRetCode = socket_fwup_accept(0, ERR_OK);
|
||||
if (nRetCode != ERR_OK)
|
||||
{
|
||||
sprintf(error_message, "Firmware update startup failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, actwrite + FWUP_MSG_SIZE, PBUF_REF);
|
||||
if (!p)
|
||||
{
|
||||
sprintf(error_message, "Unable to allocate memory for buffer");
|
||||
nRetCode = -18;
|
||||
break;
|
||||
}
|
||||
|
||||
if (recvLen == 0)
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_START;
|
||||
}
|
||||
else if (recvLen == (totalLen - actwrite))
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Buffer = SOCKET_FWUP_DATA;
|
||||
}
|
||||
|
||||
*(Buffer + 1) = (actwrite >> 8) & 0xFF;
|
||||
*(Buffer + 2) = actwrite & 0xFF;
|
||||
p->payload = Buffer;
|
||||
p->len = p->tot_len = actwrite + FWUP_MSG_SIZE;
|
||||
|
||||
nRetCode = socket_fwup_recv(0, p, ERR_OK);
|
||||
if (nRetCode != ERR_OK)
|
||||
{
|
||||
sprintf(error_message, "Firmware data processing failed");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
recvLen += actwrite;
|
||||
}
|
||||
|
||||
towrite -= actwrite;
|
||||
writelen -= actwrite; // calculate, how much is left to write
|
||||
writebuf += actwrite; // in case, we only wrote part of buffer, advance in buffer
|
||||
}
|
||||
|
||||
if (towrite > 0)
|
||||
{
|
||||
writebuf = request->received;
|
||||
writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
if (writelen < 0)
|
||||
{
|
||||
sprintf(error_message, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
nRetCode = -17;
|
||||
}
|
||||
}
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Downloaded %d / %d", recvLen, totalLen);
|
||||
rtos_delay_milliseconds(10); // give some time for flashing - will else increase used memory fast
|
||||
} while ((nRetCode == 0) && (towrite > 0) && (writelen >= 0));
|
||||
bk_printf("Download completed (%d / %d)\n", recvLen, totalLen);
|
||||
if (Buffer) os_free(Buffer);
|
||||
if (p) pbuf_free(p);
|
||||
|
||||
|
||||
if (nRetCode != 0)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, error_message);
|
||||
socket_fwup_err(0, nRetCode);
|
||||
return http_rest_error(request, nRetCode, error_message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = tls_fls_read(startaddr, (uint8_t*)buffer, readlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
22
src/hal/win32/hal_ota_win32.c
Normal file
22
src/hal/win32/hal_ota_win32.c
Normal file
@ -0,0 +1,22 @@
|
||||
#ifdef WINDOWS
|
||||
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../../logging/logging.h"
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
res = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
146
src/hal/xradio/hal_ota_xradio.c
Normal file
146
src/hal/xradio/hal_ota_xradio.c
Normal file
@ -0,0 +1,146 @@
|
||||
#if PLATFORM_XRADIO
|
||||
|
||||
#include <image/flash.h>
|
||||
#include <ota/ota.h>
|
||||
#include "../../obk_config.h"
|
||||
#include "../../new_common.h"
|
||||
#include "../../new_cfg.h"
|
||||
#include "../../httpserver/new_http.h"
|
||||
#include "../../logging/logging.h"
|
||||
|
||||
uint32_t flash_read(uint32_t flash, uint32_t addr, void* buf, uint32_t size);
|
||||
#define FLASH_INDEX_XR809 0
|
||||
|
||||
int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr)
|
||||
{
|
||||
int total = 0;
|
||||
int towrite = request->bodylen;
|
||||
char* writebuf = request->bodystart;
|
||||
int writelen = request->bodylen;
|
||||
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength);
|
||||
|
||||
bool recvfp = true;
|
||||
|
||||
ota_status_t ota_update_rest_init(void* url)
|
||||
{
|
||||
return OTA_STATUS_OK;
|
||||
}
|
||||
ota_status_t ota_update_rest_get(uint8_t* buf, uint32_t buf_size, uint32_t* recv_size, uint8_t* eof_flag)
|
||||
{
|
||||
if (recvfp)
|
||||
{
|
||||
//free(buf);
|
||||
//recvfp = false;
|
||||
//buf = writebuf;
|
||||
//*recv_size = writelen;
|
||||
//return OTA_STATUS_OK;
|
||||
int bsize = (writelen > buf_size ? buf_size : writelen);
|
||||
memcpy(buf, writebuf + startaddr, bsize);
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", bsize, startaddr);
|
||||
startaddr += bsize;
|
||||
*recv_size = bsize;
|
||||
*eof_flag = 0;
|
||||
total += bsize;
|
||||
towrite -= bsize;
|
||||
writelen -= bsize;
|
||||
recvfp = writelen > 0;
|
||||
return OTA_STATUS_OK;
|
||||
}
|
||||
if (towrite > 0)
|
||||
{
|
||||
*recv_size = writelen = recv(request->fd, buf, (request->receivedLenmax > buf_size ? buf_size : request->receivedLenmax), 0);
|
||||
//*recv_size = writelen = recv(request->fd, writebuf, request->receivedLenmax, 0);
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "Writelen %i at %i", writelen, total);
|
||||
if (writelen < 0)
|
||||
{
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite);
|
||||
*eof_flag = 1;
|
||||
*recv_size = 0;
|
||||
return OTA_STATUS_OK;
|
||||
//return OTA_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
total += writelen;
|
||||
towrite -= writelen;
|
||||
|
||||
if ((towrite > 0) && (writelen >= 0))
|
||||
{
|
||||
*eof_flag = 0;
|
||||
rtos_delay_milliseconds(10);
|
||||
return OTA_STATUS_OK;
|
||||
}
|
||||
*eof_flag = 1;
|
||||
return OTA_STATUS_OK;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
uint32_t* verify_value;
|
||||
ota_verify_t verify_type;
|
||||
ota_verify_data_t verify_data;
|
||||
|
||||
if (request->contentLength > 0)
|
||||
{
|
||||
towrite = request->contentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "Content-length is 0");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
ota_init();
|
||||
|
||||
if (ota_update_image(NULL, ota_update_rest_init, ota_update_rest_get) != OTA_STATUS_OK)
|
||||
{
|
||||
ret = -1;
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "ota_update_image failed");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
if (ota_get_verify_data(&verify_data) != OTA_STATUS_OK)
|
||||
{
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "ota_get_verify_data not ok, OTA_VERIFY_NONE");
|
||||
verify_type = OTA_VERIFY_NONE;
|
||||
verify_value = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
verify_type = verify_data.ov_type;
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "ota_get_verify_data ok");
|
||||
verify_value = (uint32_t*)(verify_data.ov_data);
|
||||
}
|
||||
|
||||
if (ota_verify_image(verify_type, verify_value) != OTA_STATUS_OK)
|
||||
{
|
||||
ret = -1;
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "OTA verify image failed");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
update_ota_exit:
|
||||
if (ret != -1)
|
||||
{
|
||||
ADDLOG_INFO(LOG_FEATURE_OTA, "OTA is successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_OTA, "OTA failed.");
|
||||
return http_rest_error(request, ret, "error");
|
||||
}
|
||||
ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total);
|
||||
http_setup(request, httpMimeTypeJson);
|
||||
hprintf255(request, "{\"size\":%d}", total);
|
||||
poststr(request, NULL);
|
||||
CFG_IncrementOTACount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HAL_FlashRead(char*buffer, int readlen, int startaddr) {
|
||||
int res;
|
||||
//uint32_t flash_read(uint32_t flash, uint32_t addr,void *buf, uint32_t size)
|
||||
res = flash_read(0, startaddr, buffer, readlen);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@ -2,7 +2,7 @@
|
||||
#include "http_fns.h"
|
||||
#include "../new_pins.h"
|
||||
#include "../new_cfg.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
// Commands register, execution API and cmd tokenizer
|
||||
#include "../cmnds/cmd_public.h"
|
||||
#include "../driver/drv_tuyaMCU.h"
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#elif PLATFORM_XRADIO
|
||||
#include <image/flash.h>
|
||||
#include "ota/ota.h"
|
||||
#include <ota/ota.h>
|
||||
#elif defined(PLATFORM_BK7231N)
|
||||
// tuya-iotos-embeded-sdk-wifi-ble-bk7231n/sdk/include/tuya_hal_storage.h
|
||||
#include "tuya_hal_storage.h"
|
||||
@ -1045,12 +1045,10 @@ typedef enum {
|
||||
|
||||
#endif
|
||||
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() >= 0)
|
||||
if (OTA_GetProgress() >= 0)
|
||||
{
|
||||
hprintf255(request, "<h5>OTA In Progress. Downloaded: %i B Flashed: %06lXh</h5>", OTA_GetTotalBytes(), ota_progress());
|
||||
hprintf255(request, "<h5>OTA In Progress. Downloaded: %i B Flashed: %06lXh</h5>", OTA_GetTotalBytes(), OTA_GetProgress());
|
||||
}
|
||||
#endif
|
||||
if (bSafeMode) {
|
||||
hprintf255(request, "<h5 class='safe'>You are in safe mode (AP mode) because full reboot failed %i times. ",
|
||||
g_bootFailures);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include "http_fns.h"
|
||||
#include "../new_pins.h"
|
||||
#include "../new_cfg.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
// Commands register, execution API and cmd tokenizer
|
||||
#include "../cmnds/cmd_public.h"
|
||||
#include "../driver/drv_tuyaMCU.h"
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#include "http_fns.h"
|
||||
#include "../new_pins.h"
|
||||
#include "../new_cfg.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
#include "../hal/hal_wifi.h"
|
||||
#include "../base64/base64.h"
|
||||
#include "http_basic_auth.h"
|
||||
|
||||
@ -97,5 +97,7 @@ int HTTP_RegisterCallback(const char* url, int method, http_callback_fn callback
|
||||
|
||||
int my_strnicmp(const char* a, const char* b, int len);
|
||||
|
||||
int http_rest_error(http_request_t* request, int code, char* msg);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
#include "../driver/drv_public.h"
|
||||
#include "../driver/drv_ntp.h"
|
||||
#include "../driver/drv_tuyaMCU.h"
|
||||
#include "../ota/ota.h"
|
||||
#include "../hal/hal_ota.h"
|
||||
#ifndef WINDOWS
|
||||
#include <lwip/dns.h>
|
||||
#endif
|
||||
@ -2183,9 +2183,7 @@ int MQTT_RunEverySecondUpdate()
|
||||
if (mqtt_client == 0 || res == 0)
|
||||
{
|
||||
//addLogAdv(LOG_INFO,LOG_FEATURE_MAIN, "Timer discovers disconnected mqtt %i\n",mqtt_loopsWithDisconnected);
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() == -1)
|
||||
#endif
|
||||
if (OTA_GetProgress() == -1)
|
||||
{
|
||||
mqtt_loopsWithDisconnected++;
|
||||
if (mqtt_loopsWithDisconnected > LOOPS_WITH_DISCONNECTED)
|
||||
@ -2241,8 +2239,7 @@ int MQTT_RunEverySecondUpdate()
|
||||
g_wantTasmotaTeleSend = 0;
|
||||
}
|
||||
g_timeSinceLastMQTTPublish++;
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() != -1)
|
||||
if (OTA_GetProgress() != -1)
|
||||
{
|
||||
addLogAdv(LOG_INFO, LOG_FEATURE_MQTT, "OTA started MQTT will be closed\n");
|
||||
LOCK_TCPIP_CORE();
|
||||
@ -2250,7 +2247,6 @@ int MQTT_RunEverySecondUpdate()
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CFG_HasFlag(OBK_FLAG_DO_TASMOTA_TELE_PUBLISHES)) {
|
||||
static int g_mqtt_tasmotaTeleCounter_sensor = 0;
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#include "httpserver/http_tcp_server.h"
|
||||
#include "httpserver/rest_interface.h"
|
||||
#include "mqtt/new_mqtt.h"
|
||||
#include "ota/ota.h"
|
||||
#include "hal/hal_ota.h"
|
||||
|
||||
#if ENABLE_LITTLEFS
|
||||
#include "littlefs/our_lfs.h"
|
||||
@ -105,6 +105,40 @@ int DRV_SSDP_Active = 0;
|
||||
|
||||
void Main_ForceUnsafeInit();
|
||||
|
||||
|
||||
|
||||
// TEMPORARY
|
||||
int ota_status = -1;
|
||||
int total_bytes = 0;
|
||||
|
||||
int OTA_GetProgress()
|
||||
{
|
||||
return ota_status;
|
||||
}
|
||||
|
||||
void OTA_ResetProgress()
|
||||
{
|
||||
ota_status = -1;
|
||||
}
|
||||
|
||||
void OTA_IncrementProgress(int value)
|
||||
{
|
||||
ota_status += value;
|
||||
}
|
||||
|
||||
int OTA_GetTotalBytes()
|
||||
{
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
void OTA_SetTotalBytes(int value)
|
||||
{
|
||||
total_bytes = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if PLATFORM_XR806 || PLATFORM_XR872
|
||||
size_t xPortGetFreeHeapSize()
|
||||
{
|
||||
@ -625,9 +659,7 @@ void Main_OnEverySecond()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PLATFORM_BK7231N || PLATFORM_BK7231T
|
||||
if (ota_progress() == -1)
|
||||
#endif
|
||||
if (OTA_GetProgress() == -1)
|
||||
{
|
||||
CFG_Save_IfThereArePendingChanges();
|
||||
}
|
||||
|
||||
@ -610,12 +610,6 @@ void otarequest(const char *urlin) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ota_progress() {
|
||||
return 0;
|
||||
}
|
||||
int ota_total_bytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user