mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-15 14:38:13 +08:00
214 lines
6.3 KiB
C
214 lines
6.3 KiB
C
/**
|
|
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
|
* Copyright (c) 2016 MXCHIP Inc.
|
|
*
|
|
* The contents of this file may not be disclosed to third parties, copied or
|
|
* duplicated in any form, in whole or in part, without the prior written
|
|
* permission of MXCHIP Corporation.
|
|
*
|
|
*/
|
|
|
|
#include "mico.h"
|
|
#include "tftp.h"
|
|
#include "CheckSumUtils.h"
|
|
#include "mico_system.h"
|
|
|
|
|
|
#define DEFAULT_OTA_AP "MICO_OTA_AP"
|
|
#define DEFAULT_OTA_NETMASK "255.0.0.0"
|
|
#define DEFAULT_OTA_SERVER "10.0.0.2"
|
|
#define UDP_PORT 20000
|
|
#define TCP_PORT 30000
|
|
|
|
#define fota_log(M, ...) custom_log("Force OTA", M, ##__VA_ARGS__)
|
|
#define fota_log_trace() custom_log_trace("Force OTA")
|
|
|
|
static int wifi_up = 0;
|
|
extern void mico_write_ota_tbl(int len, uint16_t crc);
|
|
|
|
|
|
void wlan_get_mac_address( uint8_t *mac );
|
|
|
|
enum {
|
|
OTA_SUCCESS = 0,
|
|
OTA_NO_AP = -1,
|
|
OTA_NO_FILE = -2,
|
|
OTA_MD5_FAIL = -3,
|
|
OTA_NO_MEM = -4,
|
|
};
|
|
/* Call back for OTA finished */
|
|
WEAK void mico_ota_finished(int result, uint8_t *reserved)
|
|
{
|
|
switch(result) {
|
|
case OTA_SUCCESS:
|
|
printf("OTA SUCCESS. Rebooting...\r\n");
|
|
MicoSystemReboot();
|
|
break;
|
|
case OTA_NO_AP:
|
|
printf("OTA FAIL. Can't find the OTA AP\r\n");
|
|
break;
|
|
case OTA_NO_FILE:
|
|
printf("OTA FAIL. Can't find the OTA image\r\n");
|
|
break;
|
|
case OTA_MD5_FAIL:
|
|
printf("OTA FAIL. MD5 check failed\r\n");
|
|
break;
|
|
case OTA_NO_MEM:
|
|
printf("OTA FAIL. Don't have enough memory\r\n");
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void FOTA_WifiStatusHandler(WiFiEvent event, void * arg)
|
|
{
|
|
UNUSED_PARAMETER(arg);
|
|
switch (event) {
|
|
case NOTIFY_STATION_UP:
|
|
wifi_up = 1;
|
|
break;
|
|
case NOTIFY_STATION_DOWN:
|
|
wifi_up = 0;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/* connect to AP: ssid="mico_ota_ap", security=OPEN.
|
|
* Broadcast to find OTA server
|
|
* Connect to OTA server, request to OTA.
|
|
*/
|
|
void tftp_ota(void)
|
|
{
|
|
network_InitTypeDef_st conf;
|
|
tftp_file_info_t fileinfo;
|
|
uint32_t ipaddr = inet_addr(DEFAULT_OTA_SERVER), flashaddr;
|
|
int filelen, maxretry = 5, len, left, i = 0;
|
|
uint8_t md5_recv[16];
|
|
uint8_t md5_calc[16];
|
|
uint8_t *tmpbuf;
|
|
md5_context ctx;
|
|
uint8_t mac[6], sta_ip_addr[16];
|
|
mico_logic_partition_t* ota_partition = MicoFlashGetInfo( MICO_PARTITION_OTA_TEMP );
|
|
uint16_t crc = 0;
|
|
CRC16_Context contex;
|
|
|
|
#define TMP_BUF_LEN 1024
|
|
|
|
fota_log("Start OTA");
|
|
mico_system_notify_remove_all(mico_notify_WIFI_STATUS_CHANGED);
|
|
mico_system_notify_remove_all(mico_notify_WiFI_PARA_CHANGED);
|
|
mico_system_notify_remove_all(mico_notify_DHCP_COMPLETED);
|
|
mico_system_notify_remove_all(mico_notify_WIFI_CONNECT_FAILED);
|
|
mico_system_notify_remove_all(mico_notify_EASYLINK_WPS_COMPLETED);
|
|
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *)FOTA_WifiStatusHandler, NULL );
|
|
micoWlanStopEasyLink();
|
|
micoWlanStopEasyLinkPlus();
|
|
micoWlanStopAirkiss();
|
|
mico_rtos_thread_msleep(10);
|
|
|
|
tmpbuf = (uint8_t*)malloc(TMP_BUF_LEN);
|
|
if (tmpbuf == NULL) {
|
|
fota_log("ERROR!! Can't get enough memory");
|
|
mico_ota_finished(OTA_NO_MEM, NULL);
|
|
return;
|
|
}
|
|
|
|
wlan_get_mac_address(mac);
|
|
|
|
sprintf((char *)sta_ip_addr, "10.%d.%d.%d",
|
|
mac[3], mac[4], mac[5]);
|
|
|
|
fota_log("Staic IP = %s", sta_ip_addr);
|
|
|
|
memset(&conf, 0, sizeof(network_InitTypeDef_st));
|
|
|
|
conf.wifi_mode = Station;
|
|
strcpy(conf.wifi_ssid, DEFAULT_OTA_AP);
|
|
|
|
conf.dhcpMode = DHCP_Disable;
|
|
strcpy(conf.net_mask, DEFAULT_OTA_NETMASK);
|
|
strcpy(conf.local_ip_addr, (char *)sta_ip_addr);
|
|
|
|
wifi_up = 0;
|
|
fota_log("Connect to AP %s...", DEFAULT_OTA_AP);
|
|
micoWlanStart(&conf);
|
|
|
|
while(wifi_up == 0) {
|
|
mico_rtos_thread_msleep(100);
|
|
i++;
|
|
if (i > 100) {
|
|
fota_log("ERROR!! Can't find the OTA AP");
|
|
mico_ota_finished(OTA_NO_AP, NULL);
|
|
return;
|
|
}
|
|
}
|
|
fota_log("AP connected, tftp download image... to 0x%lx", ota_partition->partition_start_addr);
|
|
|
|
fileinfo.filelen = ota_partition->partition_length;
|
|
fileinfo.flashaddr = 0;
|
|
fileinfo.flashtype = MICO_PARTITION_OTA_TEMP;
|
|
strcpy(fileinfo.filename, "mico_ota.bin");
|
|
|
|
while((filelen = tget (&fileinfo, ipaddr)) < 0) {
|
|
fota_log("tget return filelen %d, maxretry %d", filelen, maxretry);
|
|
maxretry--;
|
|
if (maxretry < 0) {
|
|
fota_log("ERROR!! Can't get OTA image.");
|
|
free(tmpbuf);
|
|
mico_ota_finished(OTA_NO_FILE, NULL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
filelen -= 16; // remove md5.
|
|
fota_log("tftp download image finished, OTA bin len %d", filelen);
|
|
flashaddr = filelen;
|
|
MicoFlashRead(MICO_PARTITION_OTA_TEMP, &flashaddr, (uint8_t *)md5_recv, 16);
|
|
InitMd5( &ctx );
|
|
CRC16_Init( &contex );
|
|
flashaddr = 0;
|
|
left = filelen;
|
|
while(left > 0) {
|
|
if (left > TMP_BUF_LEN) {
|
|
len = TMP_BUF_LEN;
|
|
} else {
|
|
len = left;
|
|
}
|
|
left -= len;
|
|
MicoFlashRead(MICO_PARTITION_OTA_TEMP, &flashaddr, (uint8_t *)tmpbuf, len);
|
|
Md5Update( &ctx, (uint8_t *)tmpbuf, len);
|
|
CRC16_Update( &contex, tmpbuf, len );
|
|
}
|
|
Md5Final( &ctx, md5_calc );
|
|
CRC16_Final( &contex, &crc );
|
|
|
|
if(memcmp(md5_calc, md5_recv, 16) != 0) {
|
|
fota_log("ERROR!! MD5 Error.");
|
|
fota_log("RX: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
md5_recv[0],md5_recv[1],md5_recv[2],md5_recv[3],
|
|
md5_recv[4],md5_recv[5],md5_recv[6],md5_recv[7],
|
|
md5_recv[8],md5_recv[9],md5_recv[10],md5_recv[11],
|
|
md5_recv[12],md5_recv[13],md5_recv[14],md5_recv[15]);
|
|
fota_log("Need: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
md5_calc[0],md5_calc[1],md5_calc[2],md5_calc[3],
|
|
md5_calc[4],md5_calc[5],md5_calc[6],md5_calc[7],
|
|
md5_calc[8],md5_calc[9],md5_calc[10],md5_calc[11],
|
|
md5_calc[12],md5_calc[13],md5_calc[14],md5_calc[15]);
|
|
mico_ota_finished(OTA_MD5_FAIL, NULL);
|
|
return;
|
|
}
|
|
|
|
fota_log("OTA bin md5 check success, CRC %x. upgrading...", crc);
|
|
mico_ota_switch_to_new_fw( filelen, crc );
|
|
mico_ota_finished(OTA_SUCCESS, NULL);
|
|
while(1)
|
|
mico_rtos_thread_sleep(100);
|
|
}
|
|
|
|
|