Beispiel #1
0
/******************************************************************************
 * 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
}
Beispiel #3
0
// 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);
        }
    }
}
Beispiel #5
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();
}
Beispiel #7
0
// 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;
}
Beispiel #8
0
/******************************************************************************
 * 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);
}
Beispiel #9
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;
}
Beispiel #10
0
//连接服务器超时回调
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;
}
Beispiel #11
0
// 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);
	}

}
Beispiel #12
0
/******************************************************************************
 * 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);
}
Beispiel #13
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);
}
Beispiel #14
0
/******************************************************************************
 * 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);
}
Beispiel #15
0
/******************************************************************************
 * 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);
}
Beispiel #16
0
// 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;
}
Beispiel #17
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], 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);
    }
}