/****************************************************************************** * FunctionName : upgrade_check * Description : check the upgrade process, if not finished in 300S,exit * Parameters : pvParameters--save the server address\port\request frame for * Returns : none *******************************************************************************/ LOCAL void upgrade_check(struct upgrade_server_info *server) { /*network not stable, upgrade data lost, this may be called*/ // vTaskDelete(pxCreatedTask); giveup = true; os_timer_disarm(&upgrade_timer); if(NULL != precv_buf) { free(precv_buf); } totallength = 0; sumlength = 0; flash_erased=FALSE; /*take too long to finish,fail*/ server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); upgrade_deinit(); os_printf("\n upgrade fail,exit.\n"); // if (server->check_cb != NULL) { // server->check_cb(server); // } }
/****************************************************************************** * FunctionName : user_upgrade_check * Description : Processing the received data from the server * Parameters : arg -- Additional argument to pass to the callback function * pusrdata -- The received data (or NULL when the connection has been closed!) * length -- The length of received data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_check(struct upgrade_server_info *server) { UPGRADE_DBG("upgrade_check\n"); if (system_upgrade_flag_check() != UPGRADE_FLAG_FINISH) { totallength = 0; sumlength = 0; os_timer_disarm(&upgrade_timer); system_upgrade_flag_set(UPGRADE_FLAG_IDLE); upgrade_deinit(); server->upgrade_flag = false; if (server->check_cb != NULL) { server->check_cb(server); } } else { os_timer_disarm(&upgrade_timer); upgrade_deinit(); server->upgrade_flag = true; if (server->check_cb != NULL) { server->check_cb(server); } } #ifdef UPGRADE_SSL_ENABLE espconn_secure_disconnect(upgrade_conn); #else espconn_disconnect(upgrade_conn); #endif }
// called when connection receives data (hopefully the rom) static void ICACHE_FLASH_ATTR upgrade_recvcb(void *arg, char *pusrdata, unsigned short length) { char *ptrData, *ptrLen, *ptr; // disarm the timer os_timer_disarm(&ota_timer); // first reply? if (upgrade->content_len == 0) { // valid http response? if ((ptrLen = (char*)os_strstr(pusrdata, "Content-Length: ")) && (ptrData = (char*)os_strstr(ptrLen, "\r\n\r\n")) && (os_strncmp(pusrdata + 9, "200", 3) == 0)) { // end of header/start of data ptrData += 4; // length of data after header in this chunk length -= (ptrData - pusrdata); // running total of download length upgrade->total_len += length; // process current chunk if (!rboot_write_flash(&upgrade->write_status, (uint8*)ptrData, length)) { // write error rboot_ota_deinit(); return; } // work out total download size ptrLen += 16; ptr = (char *)os_strstr(ptrLen, "\r\n"); *ptr = '\0'; // destructive upgrade->content_len = atoi(ptrLen); } else { // fail, not a valid http header/non-200 response/etc. rboot_ota_deinit(); return; } } else { // not the first chunk, process it upgrade->total_len += length; if (!rboot_write_flash(&upgrade->write_status, (uint8*)pusrdata, length)) { // write error rboot_ota_deinit(); return; } } // check if we are finished if (upgrade->total_len == upgrade->content_len) { system_upgrade_flag_set(UPGRADE_FLAG_FINISH); // clean up and call user callback rboot_ota_deinit(); } else if (upgrade->conn->state != ESPCONN_READ) { // fail, but how do we get here? premature end of stream? rboot_ota_deinit(); } else { // timer for next recv os_timer_setfn(&ota_timer, (os_timer_func_t *)rboot_ota_deinit, 0); os_timer_arm(&ota_timer, OTA_NETWORK_TIMEOUT, 0); } }
/****************************************************************************** * FunctionName : upgrade_download * Description : Processing the upgrade data from the host * Parameters : bin -- server number * pusrdata -- The upgrade data (or NULL when the connection has been closed!) * length -- The length of upgrade data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_download(void *arg, char *pusrdata, unsigned short length) { char *ptr = NULL; char *ptmp2 = NULL; char lengthbuffer[32]; if (totallength == 0 && (ptr = (char *)os_strstr(pusrdata, "\r\n\r\n")) != NULL && (ptr = (char *)os_strstr(pusrdata, "Content-Length")) != NULL) { ptr = (char *)os_strstr(pusrdata, "\r\n\r\n"); length -= ptr - pusrdata; length -= 4; totallength += length; UPGRADE_DBG("upgrade file download start.\n"); system_upgrade(ptr + 4, length); ptr = (char *)os_strstr(pusrdata, "Content-Length: "); if (ptr != NULL) { ptr += 16; ptmp2 = (char *)os_strstr(ptr, "\r\n"); if (ptmp2 != NULL) { os_memset(lengthbuffer, 0, sizeof(lengthbuffer)); os_memcpy(lengthbuffer, ptr, ptmp2 - ptr); sumlength = atoi(lengthbuffer); } else { UPGRADE_DBG("sumlength failed\n"); } } else { UPGRADE_DBG("Content-Length: failed\n"); } } else { totallength += length; os_printf("totallen = %d\n",totallength); system_upgrade(pusrdata, length); } if (totallength == sumlength) { UPGRADE_DBG("upgrade file download finished.\n"); system_upgrade_flag_set(UPGRADE_FLAG_FINISH); totallength = 0; sumlength = 0; upgrade_check(upgrade_conn->reverse); os_timer_disarm(&upgrade_10s); os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_deinit, NULL); os_timer_arm(&upgrade_10s, 10, 0); } else { if (upgrade_conn->state != ESPCONN_READ) { totallength = 0; sumlength = 0; os_timer_disarm(&upgrade_10s); os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_check, upgrade_conn->reverse); os_timer_arm(&upgrade_10s, 10, 0); } } }
int ICACHE_FLASH_ATTR cgiUpgradeRaw(HttpdConnData *connData) { int ret = cgiUploadRaw(connData); if (ret == HTTPD_CGI_DONE){ system_upgrade_flag_set(UPGRADE_FLAG_FINISH); // Schedule a reboot os_timer_disarm(&flash_reboot_timer); os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL); os_timer_arm(&flash_reboot_timer, 2000, 1); } return ret; }
//OTA reboot function void ICACHE_FLASH_ATTR debug_OtaReboot() { #if ESP_MESH_SUPPORT ESP_DBG("deinit for OTA\r\n"); espconn_mesh_disable(NULL); wifi_station_disconnect(); wifi_set_opmode(NULL_MODE); #endif user_esp_clr_upgrade_finish_flag();//clear flag and reboot system_upgrade_flag_set(UPGRADE_FLAG_FINISH); ESP_DBG("call system upgrade reboot...\r\n"); system_upgrade_reboot(); }
// Handle request to reboot into the new firmware int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) { if (connData->conn==NULL) { //Connection aborted. Clean up. return HTTPD_CGI_DONE; } // TODO: sanity-check that the 'next' partition actually contains something that looks like // valid firmware // This should probably be forked into a separate task that waits a second to let the // current HTTP request finish... system_upgrade_flag_set(UPGRADE_FLAG_FINISH); system_upgrade_reboot(); httpdStartResponse(connData, 200); httpdEndHeaders(connData); return HTTPD_CGI_DONE; }
/****************************************************************************** * FunctionName : upgrade_connection * Description : connect with a server * Parameters : bin -- server number * url -- the url whitch upgrade files saved * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_connect(struct upgrade_server_info *server){ UPGRADE_DBG("upgrade_connect\n"); pbuf = server->url; espconn_regist_connectcb(upgrade_conn, upgrade_connect_cb); espconn_regist_recvcb(upgrade_conn, upgrade_download); system_upgrade_init(); system_upgrade_flag_set(UPGRADE_FLAG_START); espconn_connect(upgrade_conn); os_timer_disarm(&upgrade_connect_timer); os_timer_setfn(&upgrade_connect_timer, (os_timer_func_t *)upgrade_connect_timeout_cb, upgrade_conn); os_timer_arm(&upgrade_connect_timer, 5000, 0); }
/* cgiUpgradeRaw */ int ICACHE_FLASH_ATTR cgiUpgradeRaw(HttpdConnection * ptConnection) { /* initialization */ int iRet = 0; iRet = cgiUploadRaw(ptConnection); if (HTTPD_CGI_DONE == iRet) { /* once completed flashing */ system_upgrade_flag_set(UPGRADE_FLAG_FINISH); /* schedule reboot */ os_timer_disarm(&flash_reboot_timer); os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL); os_timer_arm(&flash_reboot_timer, 2000, 1); } return iRet; }
//连接服务器超时回调 LOCAL void ICACHE_FLASH_ATTR upgrade_connect_timeout_cb(struct espconn *pespconn){ struct upgrade_server_info *server; if (pespconn == NULL) { return; } server = pespconn->reverse; os_timer_disarm(&upgrade_timer); system_upgrade_flag_set(UPGRADE_FLAG_IDLE); server->upgrade_flag = false; if (server->check_cb != NULL) { server->check_cb(server); } system_upgrade_deinit(); os_free(pespconn->proto.tcp); pespconn->proto.tcp = NULL; os_free(pespconn); pespconn = NULL; upgrade_conn = NULL; }
// clean up at the end of the update // will call the user call back to indicate completion void ICACHE_FLASH_ATTR rboot_ota_deinit() { bool result; uint8 rom_slot; ota_callback callback; struct espconn *conn; os_timer_disarm(&ota_timer); // save only remaining bits of interest from upgrade struct // then we can clean it up early, so disconnect callback // can distinguish between us calling it after update finished // or being called earlier in the update process conn = upgrade->conn; rom_slot = upgrade->rom_slot; callback = upgrade->callback; // clean up os_free(upgrade); upgrade = 0; // if connected, disconnect and clean up connection if (conn) espconn_disconnect(conn); // check for completion if (system_upgrade_flag_check() == UPGRADE_FLAG_FINISH) { result = true; } else { system_upgrade_flag_set(UPGRADE_FLAG_IDLE); result = false; } // call user call back if (callback) { callback(result, rom_slot); } }
/****************************************************************************** * FunctionName : upgrade_connection * Description : connect with a server * Parameters : bin -- server number * url -- the url whitch upgrade files saved * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_connect(struct upgrade_server_info *server) { UPGRADE_DBG("upgrade_connect\n"); pbuf = server->url; espconn_regist_connectcb(upgrade_conn, upgrade_connect_cb); espconn_regist_recvcb(upgrade_conn, upgrade_download); system_upgrade_init(); system_upgrade_flag_set(UPGRADE_FLAG_START); #ifdef UPGRADE_SSL_ENABLE espconn_secure_connect(upgrade_conn); #else espconn_connect(upgrade_conn); #endif os_timer_disarm(&upgrade_10s); os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_10s_cb, upgrade_conn); os_timer_arm(&upgrade_10s, 10000, 0); }
//下载结果检查 LOCAL void ICACHE_FLASH_ATTR upgrade_check(struct upgrade_server_info *server){ UPGRADE_DBG("upgrade_check\n"); if (server == NULL) { return; } os_timer_disarm(&upgrade_timer); if (system_upgrade_flag_check() != UPGRADE_FLAG_FINISH) { totallength = 0; sumlength = 0; server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); } else { server->upgrade_flag = true; os_timer_disarm(&upgrade_timer); } upgrade_deinit(); if (server->check_cb != NULL) { server->check_cb(server); } espconn_disconnect(upgrade_conn); }
/****************************************************************************** * FunctionName : upgrade_task * Description : task to connect with target server and get firmware data * Parameters : pvParameters--save the server address\port\request frame for * : the upgrade server\call back functions to tell the userapp * : the result of this upgrade task * Returns : none *******************************************************************************/ void upgrade_task(void *pvParameters) { int recbytes; int sta_socket; int retry_count = 0; struct ip_info ipconfig; struct upgrade_server_info *server = pvParameters; flash_erased=FALSE; precv_buf = (char*)malloc(UPGRADE_DATA_SEG_LEN); if(NULL == precv_buf){ os_printf("upgrade_task,memory exhausted, check it\n"); } while (retry_count++ < UPGRADE_RETRY_TIMES) { if (giveup) {os_printf("giveup !\r\n");break;} wifi_get_ip_info(STATION_IF, &ipconfig); /* check the ip address or net connection state*/ while (ipconfig.ip.addr == 0) { vTaskDelay(1000 / portTICK_RATE_MS); wifi_get_ip_info(STATION_IF, &ipconfig); } sta_socket = socket(PF_INET,SOCK_STREAM,0); if (-1 == sta_socket) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("socket fail !\r\n"); continue; } /*for upgrade connection debug*/ //server->sockaddrin.sin_addr.s_addr= inet_addr("192.168.1.170"); if(0 != connect(sta_socket,(struct sockaddr *)(&server->sockaddrin),sizeof(struct sockaddr))) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("connect fail!\r\n"); continue; } os_printf("Connect ok!\n"); system_upgrade_init(); system_upgrade_flag_set(UPGRADE_FLAG_START); if(write(sta_socket,server->url,strlen(server->url)) < 0) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("send fail\n"); continue; } os_printf("Request send success\n"); while((recbytes = read(sta_socket, precv_buf, UPGRADE_DATA_SEG_LEN)) > 0) { if(FALSE==flash_erased){ close(sta_socket); os_printf("pre erase flash!\n"); if(false == upgrade_data_load(precv_buf,recbytes)){ os_printf("upgrade data error!\n"); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); // break; } // upgrade_data_load(precv_buf,recbytes); break; } if(false == upgrade_data_load(precv_buf,recbytes)) { os_printf("upgrade data error!\n"); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); break; } /*this two length data should be equal, if totallength is bigger, *maybe data wrong or server send extra info, drop it anyway*/ if(totallength >= sumlength) { os_printf("upgrade data load finish.\n"); close(sta_socket); goto finish; } // os_printf("upgrade_task %d word left\n",uxTaskGetStackHighWaterMark(NULL)); } if(recbytes <= 0) { close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); os_printf("ERROR:read data fail!\r\n"); } totallength =0; sumlength = 0; } finish: os_timer_disarm(&upgrade_timer); if(upgrade_crc_check(system_get_fw_start_sec(),sumlength) != 0) { printf("upgrade crc check failed !\n"); server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); } if(NULL != precv_buf) { free(precv_buf); } totallength = 0; sumlength = 0; flash_erased=FALSE; if(retry_count == UPGRADE_RETRY_TIMES){ /*retry too many times, fail*/ server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); }else{ if (server->upgrade_flag == true) system_upgrade_flag_set(UPGRADE_FLAG_FINISH); } upgrade_deinit(); os_printf("\n Exit upgrade task.\n"); if (server->check_cb != NULL) { server->check_cb(server); } vTaskDelay(100 / portTICK_RATE_MS); vTaskDelete(NULL); }
/****************************************************************************** * FunctionName : upgrade_task * Description : task to connect with target server and get firmware data * Parameters : pvParameters--save the server address\port\request frame for * : the upgrade server\call back functions to tell the userapp * : the result of this upgrade task * Returns : none *******************************************************************************/ void upgrade_ssl_task(void *pvParameters) { int recbytes; int sta_socket; int retry_count = 0; struct ip_info ipconfig; struct upgrade_server_info *server = pvParameters; flash_erased=FALSE; precv_buf = (char*)malloc(UPGRADE_DATA_SEG_LEN);//the max data length while (retry_count++ < UPGRADE_RETRY_TIMES) { if (giveup) break; wifi_get_ip_info(STATION_IF, &ipconfig); /* check the ip address or net connection state*/ while (ipconfig.ip.addr == 0) { vTaskDelay(1000 / portTICK_RATE_MS); wifi_get_ip_info(STATION_IF, &ipconfig); } sta_socket = socket(PF_INET,SOCK_STREAM,0); if (-1 == sta_socket) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("socket fail !\r\n"); continue; } /*for upgrade connection debug*/ //server->sockaddrin.sin_addr.s_addr= inet_addr("192.168.1.170"); if(0 != connect(sta_socket,(struct sockaddr *)(&server->sockaddrin),sizeof(struct sockaddr))) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("connect fail!\r\n"); continue; } uint32_t options = SSL_DISPLAY_CERTS | SSL_NO_DEFAULT_KEY; int i=0; int quiet = 0; int cert_index = 0, ca_cert_index = 0; int cert_size, ca_cert_size; char **ca_cert, **cert; SSL *ssl; SSL_CTX *ssl_ctx; uint8_t *read_buf = NULL; cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size); cert = (char **)calloc(1, sizeof(char *)*cert_size); if ((ssl_ctx= ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) { printf("Error: Client context is invalid\n"); close(sta_socket); continue; } ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CACERT, default_certificate, default_certificate_len, NULL); for (i = 0; i < cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)){ printf("Certificate '%s' is undefined.\n", cert[i]); } } for (i = 0; i < ca_cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)){ printf("Certificate '%s' is undefined.\n", ca_cert[i]); } } free(cert); free(ca_cert); ssl= ssl_client_new(ssl_ctx, sta_socket, NULL, 0); if (ssl == NULL){ ssl_ctx_free(ssl_ctx); close(sta_socket); continue; } if(ssl_handshake_status(ssl) != SSL_OK){ printf("client handshake fail.\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); continue; } //handshake sucesses,show cert and free x509_ctx here if (!quiet) { const char *common_name = ssl_get_cert_dn(ssl,SSL_X509_CERT_COMMON_NAME); if (common_name) { printf("Common Name:\t\t\t%s\n", common_name); } display_session_id(ssl); display_cipher(ssl); quiet = true; x509_free(ssl->x509_ctx); ssl->x509_ctx=NULL; } system_upgrade_init(); system_upgrade_flag_set(UPGRADE_FLAG_START); if(ssl_write(ssl, server->url, strlen(server->url)+1) < 0) { ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("send fail\n"); continue; } os_printf("Request send success\n"); while((recbytes = ssl_read(ssl, &read_buf)) >= 0) { if(recbytes == 0){ vTaskDelay(500 / portTICK_RATE_MS); continue; } if(recbytes > UPGRADE_DATA_SEG_LEN) { ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); vTaskDelay(2000 / portTICK_RATE_MS); printf("bigger than UPGRADE_DATA_SEG_LEN\n"); } if((recbytes)<=1460) memcpy(precv_buf,read_buf,recbytes); else os_printf("ERR2:arr_overflow,%u,%d\n",__LINE__,recbytes); if(FALSE==flash_erased){ ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); os_printf("pre erase flash!\n"); upgrade_data_load(precv_buf,recbytes); break; } if(false == upgrade_data_load(read_buf,recbytes)) { os_printf("upgrade data error!\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); break; } /*this two length data should be equal, if totallength is bigger, *maybe data wrong or server send extra info, drop it anyway*/ if(totallength >= sumlength) { os_printf("upgrade data load finish.\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); goto finish; } os_printf("upgrade_task %d word left\n",uxTaskGetStackHighWaterMark(NULL)); } if(recbytes < 0) { os_printf("ERROR:read data fail! recbytes %d\r\n",recbytes); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); } os_printf("upgrade_task %d word left\n",uxTaskGetStackHighWaterMark(NULL)); totallength =0; sumlength = 0; } finish: if(upgrade_crc_check(system_get_fw_start_sec(),sumlength) != 0) { printf("upgrade crc check failed !\n"); server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); } os_timer_disarm(&upgrade_timer); totallength = 0; sumlength = 0; flash_erased=FALSE; free(precv_buf); if(retry_count == UPGRADE_RETRY_TIMES){ /*retry too many times, fail*/ server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); }else{ if (server->upgrade_flag == true) system_upgrade_flag_set(UPGRADE_FLAG_FINISH); } upgrade_deinit(); os_printf("\n Exit upgrade task.\n"); if (server->check_cb != NULL) { server->check_cb(server); } vTaskDelay(100 / portTICK_RATE_MS); vTaskDelete(NULL); }
// start the ota process, with user supplied options bool ICACHE_FLASH_ATTR rboot_ota_start(ota_callback callback) { uint8 slot; rboot_config bootconf; err_t result; // check not already updating if (system_upgrade_flag_check() == UPGRADE_FLAG_START) { return false; } // create upgrade status structure upgrade = (upgrade_status*)os_zalloc(sizeof(upgrade_status)); if (!upgrade) { CHATFABRIC_DEBUG(_GLOBAL_DEBUG, "No ram!\r\n"); return false; } // store the callback upgrade->callback = callback; // get details of rom slot to update bootconf = rboot_get_config(); slot = bootconf.current_rom; if (slot == 0) slot = 1; else slot = 0; upgrade->rom_slot = slot; // flash to rom slot upgrade->write_status = rboot_write_init(bootconf.roms[upgrade->rom_slot]); // to flash a file (e.g. containing a filesystem) to an arbitrary location // (e.g. 0x40000 bytes after the start of the rom) use code this like instead: // Note: address must be start of a sector (multiple of 4k)! //upgrade->write_status = rboot_write_init(bootconf.roms[upgrade->rom_slot] + 0x40000); //upgrade->rom_slot = FLASH_BY_ADDR; // create connection upgrade->conn = (struct espconn *)os_zalloc(sizeof(struct espconn)); if (!upgrade->conn) { CHATFABRIC_DEBUG(_GLOBAL_DEBUG, "No ram!\r\n"); os_free(upgrade); return false; } upgrade->conn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); if (!upgrade->conn->proto.tcp) { CHATFABRIC_DEBUG(_GLOBAL_DEBUG, "No ram!\r\n"); os_free(upgrade->conn); os_free(upgrade); return false; } // set update flag system_upgrade_flag_set(UPGRADE_FLAG_START); // dns lookup result = espconn_gethostbyname(upgrade->conn, OTA_HOST, &upgrade->ip, upgrade_resolved); if (result == ESPCONN_OK) { // hostname is already cached or is actually a dotted decimal ip address upgrade_resolved(0, &upgrade->ip, upgrade->conn); } else if (result == ESPCONN_INPROGRESS) { // lookup taking place, will call upgrade_resolved on completion } else { CHATFABRIC_DEBUG(_GLOBAL_DEBUG, "DNS error!\r\n"); os_free(upgrade->conn->proto.tcp); os_free(upgrade->conn); os_free(upgrade); return false; } return true; }
/****************************************************************************** * FunctionName : upgrade_download * Description : Processing the upgrade data from the host * Parameters : bin -- server number * pusrdata -- The upgrade data (or NULL when the connection has been closed!) * length -- The length of upgrade data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_download(void *arg, char *pusrdata, unsigned short length){ char *ptr = NULL; char *ptmp2 = NULL; char lengthbuffer[32], returncode[4]; uint8_t md5_calc[16],i = 0,progress = 0; char output[64] = {0}; struct upgrade_server_info *server = (struct upgrade_server_info *)upgrade_conn->reverse; uint32_t count; //检查返回码 if (totallength == 0){ ptr = (char *)os_strstr(pusrdata, "HTTP/1.1 "); os_memset(returncode, 0, sizeof(returncode)); os_memcpy(returncode, ptr+9, 3); if(os_strcmp(returncode ,"200")){ //下载失败 UPGRADE_DBG("http download return code error\n"); upgrade_check(server); return; } } if (totallength == 0 && (ptr = (char *)os_strstr(pusrdata, "\r\n\r\n")) != NULL && (ptr = (char *)os_strstr(pusrdata, "Content-Length")) != NULL) { ptr = (char *)os_strstr(pusrdata, "\r\n\r\n"); length -= ptr - pusrdata; length -= 4; totallength += length; UPGRADE_DBG("upgrade file download start.\n"); file_info_clear(); MD5Init(&_ctx); MD5Update(&_ctx, ptr + 4, length); system_upgrade(ptr + 4, length); ptr = (char *)os_strstr(pusrdata, "Content-Length: "); if (ptr != NULL) { ptr += 16; ptmp2 = (char *)os_strstr(ptr, "\r\n"); if (ptmp2 != NULL) { os_memset(lengthbuffer, 0, sizeof(lengthbuffer)); os_memcpy(lengthbuffer, ptr, ptmp2 - ptr); sumlength = atoi(lengthbuffer); } else { UPGRADE_DBG("sumlength failed\n"); upgrade_check(server); return; } } else { upgrade_check(server); UPGRADE_DBG("Content-Length: failed\n"); return; } } else { if(totallength + length > sumlength) {length = sumlength - totallength;} totallength += length; os_printf("totallen = %d\n",totallength); MD5Update(&_ctx, pusrdata, length); system_upgrade(pusrdata, length); } progress = totallength*100/sumlength; os_memset(output, 0, sizeof(output)); os_sprintf(output,"%s:2,%d\r\n", CMD_DOWN_FILE, progress); at_port_print(output); //正在下载 显示下载进度 //at_response_ok(); if ((totallength == sumlength)) { UPGRADE_DBG("upgrade file download finished.\n"); MD5Final(md5_calc, &_ctx); os_memset(output, 0, sizeof(output)); for(i = 0; i < 16; i++) { os_sprintf(output + (i * 2), "%02x", md5_calc[i]); } os_printf("md5 = %s\n",output); if(!os_strcmp(server->md5,output)){ UPGRADE_DBG("md5 check ok.\n"); system_upgrade_flag_set(UPGRADE_FLAG_FINISH); //保存文件 file_info->file_size = sumlength; file_info->file_start_sec = UPDATE_CACHE_WIFIAPP_SEC_START; file_info_write(file_info); totallength = 0; sumlength = 0; upgrade_check(server); return; } UPGRADE_DBG("md5 check error.\n"); upgrade_check(server); return; } if (upgrade_conn->state != ESPCONN_READ) { totallength = 0; sumlength = 0; os_timer_disarm(&upgrade_rev_timer); os_timer_setfn(&upgrade_rev_timer, (os_timer_func_t *)upgrade_check, server); os_timer_arm(&upgrade_rev_timer, 10, 0); } }