/* * ESPRESSIF MIT License * * Copyright (c) 2015 * * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, * it is free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished * to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ /***************************************************** ** Name : fota_crc32.c ** Author : tianzx ** Version : 1.0 ** Date : 2016-9 ** Description : CRC32 Checking ******************************************************/ #include "esp_common.h" #include "lwip/err.h" #include "lwip/ip_addr.h" #include "lwip/mem.h" #include #define BUFSIZE 512 #define CRC_BLOCK_SIZE 512 uint16 start_sec; static unsigned int *crc_table; #ifdef MEMLEAK_DEBUG static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif static int init_crc_table(void); static unsigned int crc32(unsigned int crc, unsigned char *buffer, unsigned int size); static int ICACHE_FLASH_ATTR init_crc_table(void) { unsigned int c; unsigned int i, j; crc_table = (unsigned int *)zalloc(256 * 4); if (crc_table == NULL) { return -1; } for (i = 0; i < 256; i++) { c = (unsigned int)i; for (j = 0; j < 8; j++) { if (c & 1) { c = 0xedb88320L ^ (c >> 1); } else { c = c >> 1; } } crc_table[i] = c; } return 0; } static unsigned int ICACHE_FLASH_ATTR crc32(unsigned int crc, unsigned char *buffer, unsigned int size) { unsigned int i; for (i = 0; i < size; i++) { crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); } return crc ; } static int ICACHE_FLASH_ATTR calc_img_crc(unsigned int sumlength, unsigned int *img_crc) { int fd; int ret; int i = 0; uint8 error = 0; unsigned char *buf = (char *)zalloc(BUFSIZE); if (buf == NULL) { free(crc_table); return -1; } unsigned int crc = 0xffffffff; uint16 sec_block = sumlength / CRC_BLOCK_SIZE ; uint32 sec_last = sumlength % CRC_BLOCK_SIZE; for (i = 0; i < sec_block; i++) { if (0 != (error = spi_flash_read(start_sec * SPI_FLASH_SEC_SIZE + i * CRC_BLOCK_SIZE , (uint32 *)buf, BUFSIZE))) { free(crc_table); free(buf); printf("spi_flash_read error %d\n", error); return -1; } crc = crc32(crc, buf, BUFSIZE); } if (sec_last > 0) { if (0 != (error = spi_flash_read(start_sec * SPI_FLASH_SEC_SIZE + i * CRC_BLOCK_SIZE, (uint32 *)buf, sec_last))) { free(crc_table); free(buf); printf("spi_flash_read error %d\n", error); return -1; } crc = crc32(crc, buf, sec_last); } *img_crc = crc; free(crc_table); free(buf); return 0; } bool ICACHE_FLASH_ATTR upgrade_crc_check(uint16 fw_bin_sec , unsigned int sumlength) { int ret; unsigned int img_crc; unsigned int flash_crc = 0xFF; start_sec = fw_bin_sec; if (0 != init_crc_table()) { return false; } ret = calc_img_crc(sumlength - 4, &img_crc); if (ret < 0) { return false; } img_crc = abs(img_crc); printf("img_crc = %u\n", img_crc); spi_flash_read(start_sec * SPI_FLASH_SEC_SIZE + sumlength - 4, &flash_crc, 4); printf("flash_crc = %u\n", flash_crc); if (img_crc == flash_crc) { return true; } else { return false; } }