nongye/STM32F103_App1/HardWare/NETWORK/net_wifi_ota.c

270 lines
10 KiB
C
Raw Normal View History

/* net_wifi_ota.c - WiFi ͨ<><CDA8> OTA <20>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD>
*
* ESP-01S <EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>CIPMUX=0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OTA <EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MQTT <EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
* <EFBFBD><EFBFBD>͸<EFBFBD><EFBFBD>("+++") <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> ͸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> HTTP GET <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>չ̼<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> ÿ 3072B д W25Q64 <EFBFBD><EFBFBD> B + <EFBFBD>ض<EFBFBD>У<EFBFBD><EFBFBD> + <EFBFBD>ۼ<EFBFBD> CRC16
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> CRC + <EFBFBD>̼<EFBFBD>ͷУ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> MQTT <EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> д OTA <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD> BL
*
* <EFBFBD>ο<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̡<EFBFBD>4·<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD>WIFI<EFBFBD><EFBFBD>4G V3.4 WIFI<EFBFBD>޻ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˼·<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> W25Q64 ˫<EFBFBD><EFBFBD> + CRC + <EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD> + BootLoader <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD>Ȳο<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* д<EFBFBD>ڲ<EFBFBD> Flash APP2 <EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD> TCP <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>MCU <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
* <EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD>٣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڡ<EFBFBD>
*/
#include "net_wifi_ota.h"
#include "net_wifi.h"
#include "esp8266.h"
#include "network.h"
#include "air780e.h" /* bg_delay / U2_CopyBuff / Verify_Firmware_External / crc16_modbus_update */
#include "ota_app.h" /* Application_Size */
#include "uart.h"
#include "led.h"
#include "log.h"
#include "../W25Q64/w25q64.h"
#include "stdio.h"
#include "string.h"
#include <stdlib.h>
#define WIFI_OTA_CHUNK 3072u /* <20><> 4G OTA <20><>ͬ<EFBFBD>ķֿ<C4B7><D6BF><EFBFBD><EFBFBD><EFBFBD> */
#define WIFI_OTA_HDR_TIMEOUT 15000u /* <20><> HTTP <20><>Ӧͷ<D3A6><CDB7>ʱ */
#define WIFI_OTA_IDLE_TIMEOUT 20000u /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ʱ<EFBFBD><CAB1>TCP <20><><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>٣<EFBFBD> */
static uint8_t s_blk[WIFI_OTA_CHUNK]; /* <20>ֿ<EFBFBD><D6BF>ݴ棺дflash/У<><D0A3>/CRC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9B4A6> */
/* <20><><EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD>ȫ<EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD> */
static uint8_t *ota_memfind(uint8_t *hay, uint16_t hay_len, const char *needle)
{
uint16_t nlen = strlen(needle);
if (hay_len < nlen) return NULL;
for (uint16_t i = 0; i <= hay_len - nlen; i++) {
if (memcmp(hay + i, needle, nlen) == 0) return hay + i;
}
return NULL;
}
/* <20><>Сд<D0A1><D0B4><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2>ң<EFBFBD>Content-Length ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сд<D0A1><D0B4>һ<EFBFBD><D2BB> */
static uint8_t *ota_memfind_i(uint8_t *hay, uint16_t hay_len, const char *needle)
{
uint16_t nlen = strlen(needle);
if (hay_len < nlen) return NULL;
for (uint16_t i = 0; i <= hay_len - nlen; i++) {
uint16_t j;
for (j = 0; j < nlen; j++) {
char a = hay[i + j], b = needle[j];
if (a >= 'A' && a <= 'Z') a += 32;
if (b >= 'A' && b <= 'Z') b += 32;
if (a != b) break;
}
if (j == nlen) return hay + i;
}
return NULL;
}
/* <20><><EFBFBD>ѽ<EFBFBD><D1BD>ջ<EFBFBD><D5BB><EFBFBD>ǰ n <20>ֽ<EFBFBD> */
static void ota_consume(uint16_t n)
{
if (n >= U2_CopyIndex) {
U2_CopyIndex = 0;
} else {
memmove(U2_CopyBuff, U2_CopyBuff + n, U2_CopyIndex - n);
U2_CopyIndex -= n;
}
U2_CopyBuff[U2_CopyIndex] = '\0';
}
/*==== HTTP Range <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD>ع̼<D8B9><CCBC><EFBFBD> W25Q64 <20><> B<><42><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD> 0 <20><> *out_size=<3D>̼<EFBFBD><CCBC><EFBFBD>С ====
* ÿ<EFBFBD><EFBFBD> 3072B һ<EFBFBD><EFBFBD> GET<EFBFBD><EFBFBD>Range: bytes=off-end<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MCU <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 6 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 57KB<EFBFBD><EFBFBD>MCU д flash <EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڣ<EFBFBD><EFBFBD><EFBFBD> */
static int wifi_ota_download(const char *host, int port, const char *path,
uint16_t crc16, uint32_t *out_size)
{
char req[224];
uint32_t offset = 0, total_size = 0;
uint16_t crc_acc = 0xFFFF;
int last_pct = -1;
/* <20><><EFBFBD><EFBFBD> MQTT <20><><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬΪ͸<CEAA><CDB8>ģʽ<C4A3><CABD> */
esp_exit_transparent();
if (esp_enter_transparent(host, (uint16_t)port) != 0) {
log_warn("> WiFi OTA: <20><><EFBFBD>ӹ̼<D3B9><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>");
return -1;
}
while (1) {
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ܴ<EFBFBD>С<EFBFBD>ضϣ<D8B6>total_size <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> */
uint32_t want_end = offset + WIFI_OTA_CHUNK - 1;
if (total_size > 0 && want_end >= total_size) want_end = total_size - 1;
/* HTTP/1.1 Ĭ<><C4AC> keep-alive<76><65>ͬһ TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>򷢶<EFBFBD><F2B7A2B6><EFBFBD> Range <20><><EFBFBD><EFBFBD> */
snprintf(req, sizeof(req),
"GET %s HTTP/1.1\r\nHost: %s:%d\r\nUser-Agent: esp8266-ota\r\nAccept: */*\r\nRange: bytes=%u-%u\r\n\r\n",
path, host, port, (unsigned)offset, (unsigned)want_end);
esp_rx_clear();
esp_send((uint8_t *)req, strlen(req));
/* <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n\r\n <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
uint32_t hdr_end = 0;
uint32_t tick = HAL_GetTick();
while (HAL_GetTick() - tick < WIFI_OTA_HDR_TIMEOUT) {
bg_delay(50);
uint8_t *p = ota_memfind(U2_CopyBuff, U2_CopyIndex, "\r\n\r\n");
if (p) { hdr_end = (uint32_t)(p - U2_CopyBuff) + 4; break; }
if (ota_memfind(U2_CopyBuff, U2_CopyIndex, "CLOSED")) {
log_warn("> WiFi OTA: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD> @%u", (unsigned)offset);
return -1;
}
}
if (hdr_end == 0) {
log_warn("> WiFi OTA: <20><>Ӧͷ<D3A6><CDB7>ʱ @%u", (unsigned)offset);
return -1;
}
/* <20><><EFBFBD><EFBFBD> 206<30><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> Range<67><65>200 ˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Range<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (strncmp((char *)U2_CopyBuff, "HTTP/", 5) != 0) {
log_warn("> WiFi OTA: <20><>Ӧ<EFBFBD>쳣 @%u", (unsigned)offset);
return -1;
}
if (!ota_memfind(U2_CopyBuff, 16, " 206")) {
U2_CopyBuff[hdr_end < 120 ? hdr_end : 120] = '\0';
log_warn("> WiFi OTA: <20><> 206 <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> Range?<3F><>: %.60s", U2_CopyBuff);
return -1;
}
/* <20><>һ<EFBFBD><EFBFBD><E9A3BA> Content-Range: bytes 0-x/TOTAL <20><><EFBFBD>ܴ<EFBFBD>С<EFBFBD><D0A1>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> B */
if (total_size == 0) {
uint8_t *cr = ota_memfind_i(U2_CopyBuff, hdr_end, "content-range:");
uint8_t *slash = cr ? (uint8_t *)strchr((char *)cr, '/') : NULL;
if (slash) total_size = (uint32_t)atoi((char *)slash + 1);
if (total_size == 0 || total_size > Application_Size) {
log_warn("> WiFi OTA: <20>̼<EFBFBD><CCBC>ܴ<EFBFBD>С<EFBFBD>쳣 %u", (unsigned)total_size);
return -1;
}
log_info("**************************************");
log_info("* WiFi OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ *");
log_info("* <20>̼<EFBFBD><CCBC><EFBFBD>С: %u <20>ֽ<EFBFBD> *", (unsigned)total_size);
log_info("**************************************");
log_info("> <20><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD> W25Q64 <20>²<EFBFBD>λ...");
W25Q64_EraseRegion(W25Q64_SLOT_NEW_ADDR, W25Q64_SLOT_SIZE);
log_info("> W25Q64 <20>²<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
/* <20><><EFBFBD><EFBFBD><E9B3A4> = Content-Length<74><68><EFBFBD><EFBFBD>3072<37><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD>С<EFBFBD><D0A1> */
uint32_t clen = 0;
{
uint8_t *cl = ota_memfind_i(U2_CopyBuff, hdr_end, "content-length:");
if (cl) clen = (uint32_t)atoi((char *)cl + 15);
}
if (clen == 0 || clen > WIFI_OTA_CHUNK) {
log_warn("> WiFi OTA: <20><EFBFBD><E9B3A4><EFBFBD>쳣 %u @%u", (unsigned)clen, (unsigned)offset);
return -1;
}
ota_consume((uint16_t)hdr_end);
/* <20><>ȷ<EFBFBD><C8B7> clen <20>ֽڹ̼<DAB9><CCBC><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD> */
uint16_t got = 0;
tick = HAL_GetTick();
while (got < clen) {
if (U2_CopyIndex > 0) {
tick = HAL_GetTick();
uint16_t n = U2_CopyIndex;
if (n > (uint16_t)(clen - got)) n = (uint16_t)(clen - got);
memcpy(s_blk + got, U2_CopyBuff, n);
got += n;
ota_consume(n);
} else {
if (HAL_GetTick() - tick > WIFI_OTA_IDLE_TIMEOUT) {
log_warn("> WiFi OTA: <20><><EFBFBD>ݽ<EFBFBD><DDBD>ճ<EFBFBD>ʱ @%u <20><><EFBFBD><EFBFBD> %u/%u",
(unsigned)offset, got, (unsigned)clen);
log_warn("> OTA <20><><EFBFBD><EFBFBD>: CNDTR=%u RxState=%u rxcplt=%u ore=%u pending=%u",
(unsigned)huart4.hdmarx->Instance->CNDTR,
(unsigned)huart4.RxState,
(unsigned)g_uart4_rxcplt_cnt,
(unsigned)g_uart4_ore_cnt,
(unsigned)U2_CopyIndex);
return -1;
}
bg_delay(20);
}
}
/* д W25Q64 <20><> B + <20>ض<EFBFBD>У<EFBFBD><D0A3> + <20>ۼ<EFBFBD> CRC */
W25Q64_WriteBuffer(W25Q64_SLOT_NEW_ADDR + offset, s_blk, clen);
if (!W25Q64_Verify(W25Q64_SLOT_NEW_ADDR + offset, s_blk, clen)) {
log_error("> WiFi OTA: W25Q64 <20>ض<EFBFBD>У<EFBFBD><D0A3>ʧ<EFBFBD><CAA7> offset=%u", (unsigned)offset);
return -1;
}
for (uint16_t i = 0; i < clen; i++) {
crc_acc = crc16_modbus_update(crc_acc, s_blk[i]);
}
offset += clen;
int pct = (int)(offset * 100 / total_size);
if (pct > 100) pct = 100;
if (pct / 10 > last_pct / 10) {
last_pct = pct;
log_info("> [%3d%%] %u/%uB", pct, (unsigned)offset, (unsigned)total_size);
LED2_TOGGLE;
}
if (offset >= total_size) break;
}
/* <20><><EFBFBD><EFBFBD> CRC16 У<><D0A3> */
log_info("> W25Q64 CRC16=0x%04X (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>=0x%04X)", crc_acc, crc16);
if (crc16 != 0 && crc_acc != crc16) {
log_error("> WiFi OTA: CRC16 У<>鲻ƥ<E9B2BB><EFBFBD><E4A3A1>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>");
return -1;
}
/* <20>̼<EFBFBD>ͷ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>У<EFBFBD>飨ջ<E9A3A8><D5BB>/<2F><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (!Verify_Firmware_External(W25Q64_SLOT_NEW_ADDR, total_size)) {
log_error("> WiFi OTA: <20>̼<EFBFBD>ͷУ<CDB7><D0A3><EFBFBD><EFBFBD>Ч");
return -1;
}
*out_size = total_size;
log_info("> WiFi OTA: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>%uB У<><D0A3>ͨ<EFBFBD><CDA8>", (unsigned)total_size);
return 0;
}
/*==== WiFi OTA <20><><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD> air780e_trigger_ota <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ====
* <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> result=1 <EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>ֱ<EFBFBD>Ӹ<EFBFBD>λ<EFBFBD><EFBFBD> BootLoader<EFBFBD><EFBFBD>
* ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD>ϱ<EFBFBD> result=0<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD> MQTT <EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD> */
void net_wifi_ota(const char *host, int port, const char *path,
const char *ota_id, uint16_t new_ver, uint16_t crc16)
{
uint32_t file_size = 0;
log_info("> WiFi OTA: <20><>ʼ");
/* MQTT <20><><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD>ʼ<EFBFBD><CABC>progress 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>񷢲<EFBFBD> */
NET_mqtt_report("iot.ota.progress.post", ota_id, 0);
bg_delay(500);
g_net_tx_busy = 1;
g_wifi_mqtt_ready = 0; /* MQTT <20><>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTA <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD> */
int ret = wifi_ota_download(host, port, path, crc16, &file_size);
/* <20><><EFBFBD><EFBFBD> MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WiFi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λģ<CEBB><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AP<41><50>͸<EFBFBD><CDB8><EFBFBD><EFBFBD>CONNECT/SUB<55><42><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD> */
if (net_wifi_init() == 0) {
g_net_tx_busy = 0;
NET_mqtt_report("iot.ota.result.post", ota_id, ret == 0 ? 1 : 0);
bg_delay(2000); /* <20>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD> */
} else {
g_net_tx_busy = 0;
log_warn("> WiFi OTA: MQTT <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD>ʧ");
}
if (ret == 0) {
log_info("**************************************");
log_info("* WiFi OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD> *");
log_info("* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BootLoader... *");
log_info("**************************************");
/* ֻ<>ѹ̼<D1B9><CCBC><EFBFBD>Ϣд<CFA2><D0B4> W25Q64<36><34><EFBFBD><EFBFBD><E6B1BE><EFBFBD><EFBFBD> APP ȷ<>ϳɹ<CFB3><C9B9><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4> EEPROM */
W25Q64_OTA_SetNewInfo(new_ver, file_size, crc16);
bg_delay(100);
NVIC_SystemReset();
}
log_warn("> WiFi OTA: <20><><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}