diff --git a/board/STM8L052R8T6/IAR/shell/README.md b/board/STM8L052R8T6/IAR/shell/README.md index b96b840c..f87cb4ac 100644 --- a/board/STM8L052R8T6/IAR/shell/README.md +++ b/board/STM8L052R8T6/IAR/shell/README.md @@ -1,7 +1,3 @@ - set your uart's baudrate to 9600, too high may not work -- replace all the tos_mmheap_alloc in tos_shell.c with malloc - - replace all the tos_mmheap_free in tos_shell.c with free - - That means we would not use tos_mmheap in STM8 \ No newline at end of file +- disable TOS_CFG_MMHEAP_EN \ No newline at end of file diff --git a/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash.c b/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash.c index 2bb9f734..be6320f9 100644 --- a/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash.c +++ b/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash.c @@ -1,3 +1,4 @@ +#include "tos_k.h" #include "stm32l4xx.h" #define SECTOR_SIZE 2048 // sector size for stm32l431RCTX diff --git a/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash_ota.c b/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash_ota.c index 4d214fcc..61a1ef27 100644 --- a/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash_ota.c +++ b/board/TencentOS_tiny_EVB_MX_Plus/BSP/Hardware/ONCHIP_FLASH/onchip_flash_ota.c @@ -1,4 +1,4 @@ -#include "tos_ota_download.h" +#include "ota_flash.h" #include "onchip_flash.h" #define ONCHIP_FLASH_ADDR_START 0x08000000 // start address for onchip flash for stm32l431RCTX @@ -8,7 +8,7 @@ #define SECTOR_SIZE_LOG2 11 // 2 ^ 11 = 2048 #define FOR_OTA_FLASH_SIZE (2 * SECTOR_SIZE) // storage for OTA -#define FOR_OTA_FLASH_START 0x803d000 +#define FOR_OTA_FLASH_START 0x801e000 ota_flash_drv_t stm32l4_norflash_onchip_drv_ota = { .write = stm32l4_norflash_onchip_write, @@ -19,7 +19,5 @@ ota_flash_drv_t stm32l4_norflash_onchip_drv_ota = { ota_flash_prop_t stm32l4_norflash_onchip_prop_ota = { .sector_size_log2 = SECTOR_SIZE_LOG2, .pgm_type = OTA_FLASH_PROGRAM_TYPE_DOUBLEWORD, - .flash_start = FOR_OTA_FLASH_START, - .flash_size = FOR_OTA_FLASH_SIZE, }; diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvoptx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvoptx new file mode 100644 index 00000000..bdfb1782 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvoptx @@ -0,0 +1,1412 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + TencentOS_tiny + 0x4 + ARM-ADS + + 80000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\list\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U303030303030303030303031 -O10446 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM) + + + + + + 0 + 1 + buf + + + 1 + 1 + rc + + + + + 1 + 0 + 0x803d000 + 0 + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + startup_stm32l431xx.s + startup_stm32l431xx.s + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\gpio.c + gpio.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\main.c + main.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\mcu_init.c + mcu_init.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\stm32l4xx_hal_msp.c + stm32l4xx_hal_msp.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\stm32l4xx_it_module.c + stm32l4xx_it_module.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\usart.c + usart.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\adc.c + adc.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\dac.c + dac.c + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\i2c.c + i2c.c + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\spi.c + spi.c + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\tim.c + tim.c + 0 + 0 + + + + + examples + 0 + 0 + 0 + 0 + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\examples\ota_download_through_http\ota_download_through_http_sample.c + ota_download_through_http_sample.c + 0 + 0 + + + + + Drivers/STM32L4xx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + stm32l4xx_hal_tim.c + 0 + 0 + + + 4 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + stm32l4xx_hal_tim_ex.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + stm32l4xx_hal_uart.c + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + stm32l4xx_hal_uart_ex.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + stm32l4xx_hal.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + stm32l4xx_hal_i2c.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + stm32l4xx_hal_i2c_ex.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + stm32l4xx_hal_rcc.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + stm32l4xx_hal_rcc_ex.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + stm32l4xx_hal_flash.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + stm32l4xx_hal_flash_ex.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + stm32l4xx_hal_flash_ramfunc.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + stm32l4xx_hal_gpio.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + stm32l4xx_hal_dma.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + stm32l4xx_hal_dma_ex.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + stm32l4xx_hal_pwr.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + stm32l4xx_hal_pwr_ex.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + stm32l4xx_hal_cortex.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + stm32l4xx_hal_adc_ex.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + stm32l4xx_hal_adc.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + stm32l4xx_hal_dac.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + stm32l4xx_hal_dac_ex.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + stm32l4xx_hal_spi.c + 0 + 0 + + + 4 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + stm32l4xx_hal_spi_ex.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 5 + 38 + 1 + 0 + 0 + 0 + system_stm32l4xx.c + system_stm32l4xx.c + 0 + 0 + + + + + Hardware + 0 + 0 + 0 + 0 + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\DHT11\DHT11_BUS.c + DHT11_BUS.c + 0 + 0 + + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\OLED\oled.c + oled.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + onchip_flash.c + 0 + 0 + + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + onchip_flash_ota.c + 0 + 0 + + + + + kernel + 0 + 0 + 0 + 0 + + 7 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_binary_heap.c + tos_binary_heap.c + 0 + 0 + + + 7 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_char_fifo.c + tos_char_fifo.c + 0 + 0 + + + 7 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_completion.c + tos_completion.c + 0 + 0 + + + 7 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_countdownlatch.c + tos_countdownlatch.c + 0 + 0 + + + 7 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_event.c + tos_event.c + 0 + 0 + + + 7 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_global.c + tos_global.c + 0 + 0 + + + 7 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mail_queue.c + tos_mail_queue.c + 0 + 0 + + + 7 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_message_queue.c + tos_message_queue.c + 0 + 0 + + + 7 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mmblk.c + tos_mmblk.c + 0 + 0 + + + 7 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mmheap.c + tos_mmheap.c + 0 + 0 + + + 7 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mutex.c + tos_mutex.c + 0 + 0 + + + 7 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_pend.c + tos_pend.c + 0 + 0 + + + 7 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + tos_priority_mail_queue.c + 0 + 0 + + + 7 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_message_queue.c + tos_priority_message_queue.c + 0 + 0 + + + 7 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_queue.c + tos_priority_queue.c + 0 + 0 + + + 7 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_ring_queue.c + tos_ring_queue.c + 0 + 0 + + + 7 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_robin.c + tos_robin.c + 0 + 0 + + + 7 + 60 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sched.c + tos_sched.c + 0 + 0 + + + 7 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sem.c + tos_sem.c + 0 + 0 + + + 7 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sys.c + tos_sys.c + 0 + 0 + + + 7 + 63 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_task.c + tos_task.c + 0 + 0 + + + 7 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_tick.c + tos_tick.c + 0 + 0 + + + 7 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_time.c + tos_time.c + 0 + 0 + + + 7 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_timer.c + tos_timer.c + 0 + 0 + + + 7 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_barrier.c + tos_barrier.c + 0 + 0 + + + 7 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_bitmap.c + tos_bitmap.c + 0 + 0 + + + 7 + 69 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_rwlock.c + tos_rwlock.c + 0 + 0 + + + 7 + 70 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_stopwatch.c + tos_stopwatch.c + 0 + 0 + + + + + cpu + 0 + 0 + 0 + 0 + + 8 + 71 + 2 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + port_s.S + 0 + 0 + + + 8 + 72 + 1 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + tos_cpu.c + 0 + 0 + + + 8 + 73 + 1 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + port_c.c + 0 + 0 + + + + + cmsis + 0 + 0 + 0 + 0 + + 9 + 74 + 1 + 0 + 0 + 0 + ..\..\..\..\..\osal\cmsis_os\cmsis_os.c + cmsis_os.c + 0 + 0 + + + + + config + 0 + 0 + 0 + 0 + + 10 + 75 + 5 + 0 + 0 + 0 + ..\..\TOS-CONFIG\tos_config.h + tos_config.h + 0 + 0 + + + + + at + 0 + 0 + 0 + 0 + + 11 + 76 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\at\src\tos_at.c + tos_at.c + 0 + 0 + + + + + devices + 0 + 0 + 0 + 0 + + 12 + 77 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\esp8266\esp8266.c + esp8266.c + 0 + 0 + + + + + sal_module_wrapper + 0 + 0 + 0 + 0 + + 13 + 78 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\sal_module_wrapper\sal_module_wrapper.c + sal_module_wrapper.c + 0 + 0 + + + + + hal + 0 + 0 + 0 + 0 + + 14 + 79 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\hal\st\stm32l4xx\src\tos_hal_uart.c + tos_hal_uart.c + 0 + 0 + + + + + ota_download + 0 + 0 + 0 + 0 + + 15 + 80 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\download\protocol\http\ota_download_http.c + ota_download_http.c + 0 + 0 + + + 15 + 81 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\download\transport_layer\tcp\module\hal_tcp_module.c + hal_tcp_module.c + 0 + 0 + + + + + ota_common + 0 + 0 + 0 + 0 + + 16 + 82 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\flash\ota_flash.c + ota_flash.c + 0 + 0 + + + 16 + 83 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\crc\crc8.c + crc8.c + 0 + 0 + + + 16 + 84 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\image\ota_image.c + ota_image.c + 0 + 0 + + + 16 + 85 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\partition\ota_partition.c + ota_partition.c + 0 + 0 + + + 16 + 86 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\env\ota_env.c + ota_env.c + 0 + 0 + + + + + kv + 0 + 0 + 0 + 0 + + 17 + 87 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\fs\kv\tos_kv.c + tos_kv.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvprojx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvprojx new file mode 100644 index 00000000..294fdafd --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvprojx @@ -0,0 +1,922 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + TencentOS_tiny + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + STM32L431RCTx + STMicroelectronics + Keil.STM32L4xx_DFP.2.0.0 + http://www.keil.com/pack + IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4") + + + + + + + + + + + + + + + $$Device:STM32L431RCTx$CMSIS\SVD\STM32L4x1.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\obj\ + TencentOS_tiny + 1 + 0 + 1 + 1 + 0 + .\list\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output=@L.bin !L + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4107 + + 1 + STLink\ST-LINKIII-KEIL_SWO.dll + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8008000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32L431xx, + + ..\..\..\BSP\Inc;..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Inc;..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Legacy;..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Include;..\..\..\..\..\kernel\core\include;..\..\..\TOS-CONFIG;..\..\..\..\..\platform\arch\arm\cortex-m4\keil;..\..\..\..\..\kernel\pm\include;..\..\..\..\..\osal\cmsis_os;..\..\..\..\..\arch\arm\arm-v7m\common\include;..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc;..\..\..\BSP\Hardware\DHT11;..\..\..\BSP\Hardware\OLED;..\..\..\BSP\Hardware\BH1750;..\..\..\..\..\devices\esp8266;..\..\..\..\..\net\at\include;..\..\..\..\..\kernel\hal\include;..\..\..\..\..\net\sal_module_wrapper;..\..\..\..\..\components\ota\download\include;..\..\..\..\..\components\ota\common\crc;..\..\..\..\..\components\ota\common\image;..\..\..\..\..\components\ota\common\flash;..\..\..\..\..\components\ota\common\partition;..\..\..\..\..\components\ota\common\env;..\..\..\..\..\components\fs\kv\include;..\..\..\..\..\components\ota\common\info + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32l431xx.s + 2 + startup_stm32l431xx.s + + + + + Application/User + + + gpio.c + 1 + ..\..\..\BSP\Src\gpio.c + + + main.c + 1 + ..\..\..\BSP\Src\main.c + + + mcu_init.c + 1 + ..\..\..\BSP\Src\mcu_init.c + + + stm32l4xx_hal_msp.c + 1 + ..\..\..\BSP\Src\stm32l4xx_hal_msp.c + + + stm32l4xx_it_module.c + 1 + ..\..\..\BSP\Src\stm32l4xx_it_module.c + + + usart.c + 1 + ..\..\..\BSP\Src\usart.c + + + adc.c + 1 + ..\..\..\BSP\Src\adc.c + + + dac.c + 1 + ..\..\..\BSP\Src\dac.c + + + i2c.c + 1 + ..\..\..\BSP\Src\i2c.c + + + spi.c + 1 + ..\..\..\BSP\Src\spi.c + + + tim.c + 1 + ..\..\..\BSP\Src\tim.c + + + + + examples + + + ota_download_through_http_sample.c + 1 + ..\..\..\..\..\examples\ota_download_through_http\ota_download_through_http_sample.c + + + + + Drivers/STM32L4xx_HAL_Driver + + + stm32l4xx_hal_tim.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + + + stm32l4xx_hal_tim_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + + + stm32l4xx_hal_uart.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + + + stm32l4xx_hal_uart_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + + + stm32l4xx_hal.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + + + stm32l4xx_hal_i2c.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + + + stm32l4xx_hal_i2c_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + + + stm32l4xx_hal_rcc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + + + stm32l4xx_hal_rcc_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + + + stm32l4xx_hal_flash.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + + + stm32l4xx_hal_flash_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + + + stm32l4xx_hal_flash_ramfunc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + + + stm32l4xx_hal_gpio.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + + + stm32l4xx_hal_dma.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + + + stm32l4xx_hal_dma_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + + + stm32l4xx_hal_pwr.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + + + stm32l4xx_hal_pwr_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + + + stm32l4xx_hal_cortex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + + + stm32l4xx_hal_adc_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + + + stm32l4xx_hal_adc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + + + stm32l4xx_hal_dac.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + + + stm32l4xx_hal_dac_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + + + stm32l4xx_hal_spi.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + + + stm32l4xx_hal_spi_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + + + + + Drivers/CMSIS + + + system_stm32l4xx.c + 1 + system_stm32l4xx.c + + + + + Hardware + + + DHT11_BUS.c + 1 + ..\..\..\BSP\Hardware\DHT11\DHT11_BUS.c + + + oled.c + 1 + ..\..\..\BSP\Hardware\OLED\oled.c + + + onchip_flash.c + 1 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + + + onchip_flash_ota.c + 1 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + + + + + kernel + + + tos_binary_heap.c + 1 + ..\..\..\..\..\kernel\core\tos_binary_heap.c + + + tos_char_fifo.c + 1 + ..\..\..\..\..\kernel\core\tos_char_fifo.c + + + tos_completion.c + 1 + ..\..\..\..\..\kernel\core\tos_completion.c + + + tos_countdownlatch.c + 1 + ..\..\..\..\..\kernel\core\tos_countdownlatch.c + + + tos_event.c + 1 + ..\..\..\..\..\kernel\core\tos_event.c + + + tos_global.c + 1 + ..\..\..\..\..\kernel\core\tos_global.c + + + tos_mail_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_mail_queue.c + + + tos_message_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_message_queue.c + + + tos_mmblk.c + 1 + ..\..\..\..\..\kernel\core\tos_mmblk.c + + + tos_mmheap.c + 1 + ..\..\..\..\..\kernel\core\tos_mmheap.c + + + tos_mutex.c + 1 + ..\..\..\..\..\kernel\core\tos_mutex.c + + + tos_pend.c + 1 + ..\..\..\..\..\kernel\core\tos_pend.c + + + tos_priority_mail_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + + + tos_priority_message_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_message_queue.c + + + tos_priority_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_queue.c + + + tos_ring_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_ring_queue.c + + + tos_robin.c + 1 + ..\..\..\..\..\kernel\core\tos_robin.c + + + tos_sched.c + 1 + ..\..\..\..\..\kernel\core\tos_sched.c + + + tos_sem.c + 1 + ..\..\..\..\..\kernel\core\tos_sem.c + + + tos_sys.c + 1 + ..\..\..\..\..\kernel\core\tos_sys.c + + + tos_task.c + 1 + ..\..\..\..\..\kernel\core\tos_task.c + + + tos_tick.c + 1 + ..\..\..\..\..\kernel\core\tos_tick.c + + + tos_time.c + 1 + ..\..\..\..\..\kernel\core\tos_time.c + + + tos_timer.c + 1 + ..\..\..\..\..\kernel\core\tos_timer.c + + + tos_barrier.c + 1 + ..\..\..\..\..\kernel\core\tos_barrier.c + + + tos_bitmap.c + 1 + ..\..\..\..\..\kernel\core\tos_bitmap.c + + + tos_rwlock.c + 1 + ..\..\..\..\..\kernel\core\tos_rwlock.c + + + tos_stopwatch.c + 1 + ..\..\..\..\..\kernel\core\tos_stopwatch.c + + + + + cpu + + + port_s.S + 2 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + + + tos_cpu.c + 1 + ..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + + + port_c.c + 1 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + + + + + cmsis + + + cmsis_os.c + 1 + ..\..\..\..\..\osal\cmsis_os\cmsis_os.c + + + + + config + + + tos_config.h + 5 + ..\..\TOS-CONFIG\tos_config.h + + + + + at + + + tos_at.c + 1 + ..\..\..\..\..\net\at\src\tos_at.c + + + + + devices + + + esp8266.c + 1 + ..\..\..\..\..\devices\esp8266\esp8266.c + + + + + sal_module_wrapper + + + sal_module_wrapper.c + 1 + ..\..\..\..\..\net\sal_module_wrapper\sal_module_wrapper.c + + + + + hal + + + tos_hal_uart.c + 1 + ..\..\..\..\..\platform\hal\st\stm32l4xx\src\tos_hal_uart.c + + + + + ota_download + + + ota_download_http.c + 1 + ..\..\..\..\..\components\ota\download\protocol\http\ota_download_http.c + + + hal_tcp_module.c + 1 + ..\..\..\..\..\components\ota\download\transport_layer\tcp\module\hal_tcp_module.c + + + + + ota_common + + + ota_flash.c + 1 + ..\..\..\..\..\components\ota\common\flash\ota_flash.c + + + crc8.c + 1 + ..\..\..\..\..\components\ota\common\crc\crc8.c + + + ota_image.c + 1 + ..\..\..\..\..\components\ota\common\image\ota_image.c + + + ota_partition.c + 1 + ..\..\..\..\..\components\ota\common\partition\ota_partition.c + + + ota_env.c + 1 + ..\..\..\..\..\components\ota\common\env\ota_env.c + + + + + kv + + + tos_kv.c + 1 + ..\..\..\..\..\components\fs\kv\tos_kv.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/startup_stm32l431xx.s b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/startup_stm32l431xx.s new file mode 100644 index 00000000..6a5c15a5 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/startup_stm32l431xx.s @@ -0,0 +1,404 @@ +;********************** COPYRIGHT(c) 2017 STMicroelectronics ****************** +;* File Name : startup_stm32l431xx.s +;* Author : MCD Application Team +;* Description : STM32L431xx Ultra Low Power devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;* +;******************************************************************************* +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x100 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x100 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection + DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line + DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_IRQHandler ; ADC1 + DCD CAN1_TX_IRQHandler ; CAN1 TX + DCD CAN1_RX0_IRQHandler ; CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; CAN1 SCE + DCD EXTI9_5_IRQHandler ; External Line[9:5]s + DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15 + DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; External Line[15:10] + DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD 0 ; Reserved + DCD SPI3_IRQHandler ; SPI3 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD COMP_IRQHandler ; COMP Interrupt + DCD LPTIM1_IRQHandler ; LP TIM1 interrupt + DCD LPTIM2_IRQHandler ; LP TIM2 interrupt + DCD 0 ; Reserved + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 + DCD LPUART1_IRQHandler ; LP UART1 interrupt + DCD QUADSPI_IRQHandler ; Quad SPI global interrupt + DCD I2C3_EV_IRQHandler ; I2C3 event + DCD I2C3_ER_IRQHandler ; I2C3 error + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD 0 ; Reserved + DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt + DCD TSC_IRQHandler ; Touch Sense Controller global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD RNG_IRQHandler ; RNG global interrupt + DCD FPU_IRQHandler ; FPU + DCD CRS_IRQHandler ; CRS interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_PVM_IRQHandler [WEAK] + EXPORT TAMP_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK] + EXPORT TIM1_UP_TIM16_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT TIM6_DAC_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT DMA2_Channel6_IRQHandler [WEAK] + EXPORT DMA2_Channel7_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT QUADSPI_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SWPMI1_IRQHandler [WEAK] + EXPORT TSC_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_PVM_IRQHandler +TAMP_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_TIM15_IRQHandler +TIM1_UP_TIM16_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +SDMMC1_IRQHandler +SPI3_IRQHandler +TIM6_DAC_IRQHandler +TIM7_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +COMP_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +DMA2_Channel6_IRQHandler +DMA2_Channel7_IRQHandler +LPUART1_IRQHandler +QUADSPI_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SAI1_IRQHandler +SWPMI1_IRQHandler +TSC_IRQHandler +RNG_IRQHandler +FPU_IRQHandler +CRS_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/system_stm32l4xx.c b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/system_stm32l4xx.c new file mode 100644 index 00000000..70e973e9 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/system_stm32l4xx.c @@ -0,0 +1,337 @@ +/** + ****************************************************************************** + * @file system_stm32l4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the MSI (4 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | MSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 8 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * PLLSAI1_P | NA + *----------------------------------------------------------------------------- + * PLLSAI1_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI1_R | NA + *----------------------------------------------------------------------------- + * PLLSAI2_P | NA + *----------------------------------------------------------------------------- + * PLLSAI2_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI2_R | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l4xx_system + * @{ + */ + +/** @addtogroup STM32L4xx_System_Private_Includes + * @{ + */ + +#include "stm32l4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x8000 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 4000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint32_t MSIRangeTable[12] = {100000U, 200000U, 400000U, 800000U, 1000000U, 2000000U, \ + 4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U}; +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U; + + /* Get MSI Range frequency--------------------------------------------------*/ + if((RCC->CR & RCC_CR_MSIRGSEL) == RESET) + { /* MSISRANGE from RCC_CSR applies */ + msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U; + } + else + { /* MSIRANGE from RCC_CR applies */ + msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; + + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ; + + switch (pllsource) + { + case 0x02: /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm); + break; + + case 0x03: /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm); + break; + + default: /* MSI used as PLL clock source */ + pllvco = (msirange / pllm); + break; + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U; + SystemCoreClock = pllvco/pllr; + break; + + default: + SystemCoreClock = msirange; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvoptx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvoptx new file mode 100644 index 00000000..0a0ddeb6 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvoptx @@ -0,0 +1,3007 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + TencentOS_tiny + 0x4 + ARM-ADS + + 80000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\list\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U303030303030303030303031 -O10446 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM) + + + + + 0 + 0 + 46 + 1 +
134258674
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\examples\ota_download_through_qcloud_iot_explorer\entry.c + + \\TencentOS_tiny\../../../../../examples/ota_download_through_qcloud_iot_explorer/entry.c\46 +
+ + 1 + 0 + 28 + 1 +
134354734
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\components\ota\common\env\ota_env.c + + \\TencentOS_tiny\../../../../../components/ota/common/env/ota_env.c\28 +
+
+ + + 0 + 1 + k_curr_task + + + 1 + 1 + k_next_task + + + + + 0 + 2 + pProperty->key + + + 1 + 2 + sg_DataTemplate[i].data_property.key + + + 2 + 2 + sg_DataTemplate[i].data_property.type + + + 3 + 2 + brightness_str + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + +
+
+ + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + startup_stm32l431xx.s + startup_stm32l431xx.s + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\gpio.c + gpio.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\main.c + main.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\mcu_init.c + mcu_init.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\stm32l4xx_hal_msp.c + stm32l4xx_hal_msp.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\usart.c + usart.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\adc.c + adc.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\dac.c + dac.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\i2c.c + i2c.c + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\spi.c + spi.c + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\stm32l4xx_it_module.c + stm32l4xx_it_module.c + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\tim.c + tim.c + 0 + 0 + + + + + examples + 0 + 0 + 0 + 0 + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\examples\ota_download_through_qcloud_iot_explorer\entry.c + entry.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\examples\ota_download_through_qcloud_iot_explorer\ota_download_through_qcloud_iot_explorer_sample.c + ota_download_through_qcloud_iot_explorer_sample.c + 0 + 0 + + + + + Drivers/STM32L4xx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + stm32l4xx_hal_tim.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + stm32l4xx_hal_tim_ex.c + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + stm32l4xx_hal_uart.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + stm32l4xx_hal_uart_ex.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + stm32l4xx_hal.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + stm32l4xx_hal_i2c.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + stm32l4xx_hal_i2c_ex.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + stm32l4xx_hal_rcc.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + stm32l4xx_hal_rcc_ex.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + stm32l4xx_hal_flash.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + stm32l4xx_hal_flash_ex.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + stm32l4xx_hal_flash_ramfunc.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + stm32l4xx_hal_gpio.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + stm32l4xx_hal_dma.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + stm32l4xx_hal_dma_ex.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + stm32l4xx_hal_pwr.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + stm32l4xx_hal_pwr_ex.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + stm32l4xx_hal_cortex.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + stm32l4xx_hal_adc_ex.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + stm32l4xx_hal_adc.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + stm32l4xx_hal_dac.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + stm32l4xx_hal_dac_ex.c + 0 + 0 + + + 4 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + stm32l4xx_hal_spi.c + 0 + 0 + + + 4 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + stm32l4xx_hal_spi_ex.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 5 + 39 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Src\system_stm32l4xx.c + system_stm32l4xx.c + 0 + 0 + + + + + Hardware + 0 + 0 + 0 + 0 + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\DHT11\DHT11_BUS.c + DHT11_BUS.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\OLED\oled.c + oled.c + 0 + 0 + + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\BH1750\BH1750.c + BH1750.c + 0 + 0 + + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + onchip_flash.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + onchip_flash_ota.c + 0 + 0 + + + + + kernel + 0 + 0 + 0 + 0 + + 7 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_binary_heap.c + tos_binary_heap.c + 0 + 0 + + + 7 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_char_fifo.c + tos_char_fifo.c + 0 + 0 + + + 7 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_completion.c + tos_completion.c + 0 + 0 + + + 7 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_countdownlatch.c + tos_countdownlatch.c + 0 + 0 + + + 7 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_event.c + tos_event.c + 0 + 0 + + + 7 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_global.c + tos_global.c + 0 + 0 + + + 7 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mail_queue.c + tos_mail_queue.c + 0 + 0 + + + 7 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_message_queue.c + tos_message_queue.c + 0 + 0 + + + 7 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mmblk.c + tos_mmblk.c + 0 + 0 + + + 7 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mmheap.c + tos_mmheap.c + 0 + 0 + + + 7 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_mutex.c + tos_mutex.c + 0 + 0 + + + 7 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_pend.c + tos_pend.c + 0 + 0 + + + 7 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + tos_priority_mail_queue.c + 0 + 0 + + + 7 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_message_queue.c + tos_priority_message_queue.c + 0 + 0 + + + 7 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_priority_queue.c + tos_priority_queue.c + 0 + 0 + + + 7 + 60 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_ring_queue.c + tos_ring_queue.c + 0 + 0 + + + 7 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_robin.c + tos_robin.c + 0 + 0 + + + 7 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sched.c + tos_sched.c + 0 + 0 + + + 7 + 63 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sem.c + tos_sem.c + 0 + 0 + + + 7 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_sys.c + tos_sys.c + 0 + 0 + + + 7 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_task.c + tos_task.c + 0 + 0 + + + 7 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_tick.c + tos_tick.c + 0 + 0 + + + 7 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_time.c + tos_time.c + 0 + 0 + + + 7 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_timer.c + tos_timer.c + 0 + 0 + + + 7 + 69 + 1 + 0 + 0 + 0 + ..\..\..\..\..\kernel\core\tos_stopwatch.c + tos_stopwatch.c + 0 + 0 + + + + + cpu + 0 + 0 + 0 + 0 + + 8 + 70 + 2 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + port_s.S + 0 + 0 + + + 8 + 71 + 1 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + tos_cpu.c + 0 + 0 + + + 8 + 72 + 1 + 0 + 0 + 0 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + port_c.c + 0 + 0 + + + + + cmsis + 0 + 0 + 0 + 0 + + 9 + 73 + 1 + 0 + 0 + 0 + ..\..\..\..\..\osal\cmsis_os\cmsis_os.c + cmsis_os.c + 0 + 0 + + + + + module_wrapper + 0 + 0 + 0 + 0 + + 10 + 74 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\sal_module_wrapper\sal_module_wrapper.c + sal_module_wrapper.c + 0 + 0 + + + 10 + 75 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\lora_module_wrapper\lora_module_wrapper.c + lora_module_wrapper.c + 0 + 0 + + + 10 + 76 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\tencent_firmware_module_wrapper\tencent_firmware_module_wrapper.c + tencent_firmware_module_wrapper.c + 0 + 0 + + + + + devices + 0 + 0 + 0 + 0 + + 11 + 77 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\esp8266\esp8266.c + esp8266.c + 0 + 0 + + + 11 + 78 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\rhf76_lora\RHF76.c + RHF76.c + 0 + 0 + + + 11 + 79 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\bc35_28_95\bc35_28_95.c + bc35_28_95.c + 0 + 0 + + + 11 + 80 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\esp8266_tencent_firmware\esp8266_tencent_firmware.c + esp8266_tencent_firmware.c + 0 + 0 + + + 11 + 81 + 1 + 0 + 0 + 0 + ..\..\..\..\..\devices\sim800a\sim800a.c + sim800a.c + 0 + 0 + + + + + config + 0 + 0 + 0 + 0 + + 12 + 82 + 5 + 0 + 0 + 0 + ..\..\..\TOS-CONFIG\tos_config.h + tos_config.h + 0 + 0 + + + + + hal + 0 + 0 + 0 + 0 + + 13 + 83 + 1 + 0 + 0 + 0 + ..\..\..\..\..\platform\hal\st\stm32l4xx\src\tos_hal_uart.c + tos_hal_uart.c + 0 + 0 + + + + + at-framwork + 0 + 0 + 0 + 0 + + 14 + 84 + 1 + 0 + 0 + 0 + ..\..\..\..\..\net\at\src\tos_at.c + tos_at.c + 0 + 0 + + + + + mbedtls + 0 + 0 + 0 + 0 + + 15 + 85 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\entropy_hardware_alt.c + entropy_hardware_alt.c + 0 + 0 + + + 15 + 86 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\net_module_alt.c + net_module_alt.c + 0 + 0 + + + 15 + 87 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\timing_alt.c + timing_alt.c + 0 + 0 + + + 15 + 88 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aes.c + aes.c + 0 + 0 + + + 15 + 89 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aesni.c + aesni.c + 0 + 0 + + + 15 + 90 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\arc4.c + arc4.c + 0 + 0 + + + 15 + 91 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aria.c + aria.c + 0 + 0 + + + 15 + 92 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\asn1parse.c + asn1parse.c + 0 + 0 + + + 15 + 93 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\asn1write.c + asn1write.c + 0 + 0 + + + 15 + 94 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\base64.c + base64.c + 0 + 0 + + + 15 + 95 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\bignum.c + bignum.c + 0 + 0 + + + 15 + 96 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\blowfish.c + blowfish.c + 0 + 0 + + + 15 + 97 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\camellia.c + camellia.c + 0 + 0 + + + 15 + 98 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ccm.c + ccm.c + 0 + 0 + + + 15 + 99 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\certs.c + certs.c + 0 + 0 + + + 15 + 100 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\chacha20.c + chacha20.c + 0 + 0 + + + 15 + 101 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\chachapoly.c + chachapoly.c + 0 + 0 + + + 15 + 102 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cipher.c + cipher.c + 0 + 0 + + + 15 + 103 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cipher_wrap.c + cipher_wrap.c + 0 + 0 + + + 15 + 104 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cmac.c + cmac.c + 0 + 0 + + + 15 + 105 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ctr_drbg.c + ctr_drbg.c + 0 + 0 + + + 15 + 106 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\debug.c + debug.c + 0 + 0 + + + 15 + 107 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\des.c + des.c + 0 + 0 + + + 15 + 108 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\dhm.c + dhm.c + 0 + 0 + + + 15 + 109 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecdh.c + ecdh.c + 0 + 0 + + + 15 + 110 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecdsa.c + ecdsa.c + 0 + 0 + + + 15 + 111 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecjpake.c + ecjpake.c + 0 + 0 + + + 15 + 112 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecp.c + ecp.c + 0 + 0 + + + 15 + 113 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecp_curves.c + ecp_curves.c + 0 + 0 + + + 15 + 114 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\entropy.c + entropy.c + 0 + 0 + + + 15 + 115 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\entropy_poll.c + entropy_poll.c + 0 + 0 + + + 15 + 116 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\error.c + error.c + 0 + 0 + + + 15 + 117 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\gcm.c + gcm.c + 0 + 0 + + + 15 + 118 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\havege.c + havege.c + 0 + 0 + + + 15 + 119 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\hkdf.c + hkdf.c + 0 + 0 + + + 15 + 120 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\hmac_drbg.c + hmac_drbg.c + 0 + 0 + + + 15 + 121 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md.c + md.c + 0 + 0 + + + 15 + 122 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md_wrap.c + md_wrap.c + 0 + 0 + + + 15 + 123 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md2.c + md2.c + 0 + 0 + + + 15 + 124 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md4.c + md4.c + 0 + 0 + + + 15 + 125 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md5.c + md5.c + 0 + 0 + + + 15 + 126 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\memory_buffer_alloc.c + memory_buffer_alloc.c + 0 + 0 + + + 15 + 127 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\net_sockets.c + net_sockets.c + 0 + 0 + + + 15 + 128 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\nist_kw.c + nist_kw.c + 0 + 0 + + + 15 + 129 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\oid.c + oid.c + 0 + 0 + + + 15 + 130 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\padlock.c + padlock.c + 0 + 0 + + + 15 + 131 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pem.c + pem.c + 0 + 0 + + + 15 + 132 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pk.c + pk.c + 0 + 0 + + + 15 + 133 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pk_wrap.c + pk_wrap.c + 0 + 0 + + + 15 + 134 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs5.c + pkcs5.c + 0 + 0 + + + 15 + 135 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs11.c + pkcs11.c + 0 + 0 + + + 15 + 136 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs12.c + pkcs12.c + 0 + 0 + + + 15 + 137 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkparse.c + pkparse.c + 0 + 0 + + + 15 + 138 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkwrite.c + pkwrite.c + 0 + 0 + + + 15 + 139 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\platform.c + platform.c + 0 + 0 + + + 15 + 140 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\platform_util.c + platform_util.c + 0 + 0 + + + 15 + 141 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\poly1305.c + poly1305.c + 0 + 0 + + + 15 + 142 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ripemd160.c + ripemd160.c + 0 + 0 + + + 15 + 143 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\rsa.c + rsa.c + 0 + 0 + + + 15 + 144 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\rsa_internal.c + rsa_internal.c + 0 + 0 + + + 15 + 145 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha1.c + sha1.c + 0 + 0 + + + 15 + 146 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha256.c + sha256.c + 0 + 0 + + + 15 + 147 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha512.c + sha512.c + 0 + 0 + + + 15 + 148 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cache.c + ssl_cache.c + 0 + 0 + + + 15 + 149 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_ciphersuites.c + ssl_ciphersuites.c + 0 + 0 + + + 15 + 150 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cli.c + ssl_cli.c + 0 + 0 + + + 15 + 151 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cookie.c + ssl_cookie.c + 0 + 0 + + + 15 + 152 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_srv.c + ssl_srv.c + 0 + 0 + + + 15 + 153 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_ticket.c + ssl_ticket.c + 0 + 0 + + + 15 + 154 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_tls.c + ssl_tls.c + 0 + 0 + + + 15 + 155 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\threading.c + threading.c + 0 + 0 + + + 15 + 156 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\timing.c + timing.c + 0 + 0 + + + 15 + 157 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\version.c + version.c + 0 + 0 + + + 15 + 158 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\version_features.c + version_features.c + 0 + 0 + + + 15 + 159 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509.c + x509.c + 0 + 0 + + + 15 + 160 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_create.c + x509_create.c + 0 + 0 + + + 15 + 161 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_crl.c + x509_crl.c + 0 + 0 + + + 15 + 162 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_crt.c + x509_crt.c + 0 + 0 + + + 15 + 163 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_csr.c + x509_csr.c + 0 + 0 + + + 15 + 164 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509write_crt.c + x509write_crt.c + 0 + 0 + + + 15 + 165 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509write_csr.c + x509write_csr.c + 0 + 0 + + + 15 + 166 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\xtea.c + xtea.c + 0 + 0 + + + + + qcloud/port + 0 + 0 + 0 + 0 + + 16 + 167 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_AT_UART_tencentos_tiny.c + HAL_AT_UART_tencentos_tiny.c + 0 + 0 + + + 16 + 168 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_Device_tencentos_tiny.c + HAL_Device_tencentos_tiny.c + 0 + 0 + + + 16 + 169 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_OS_tencentos_tiny.c + HAL_OS_tencentos_tiny.c + 0 + 0 + + + 16 + 170 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_TCP_module.c + HAL_TCP_module.c + 0 + 0 + + + 16 + 171 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_Timer_tencentos_tiny.c + HAL_Timer_tencentos_tiny.c + 0 + 0 + + + 16 + 172 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_UDP_module.c + HAL_UDP_module.c + 0 + 0 + + + + + qcloud/protocol/mqtt + 0 + 0 + 0 + 0 + + 17 + 173 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client.c + mqtt_client.c + 0 + 0 + + + 17 + 174 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_common.c + mqtt_client_common.c + 0 + 0 + + + 17 + 175 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_connect.c + mqtt_client_connect.c + 0 + 0 + + + 17 + 176 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_net.c + mqtt_client_net.c + 0 + 0 + + + 17 + 177 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_publish.c + mqtt_client_publish.c + 0 + 0 + + + 17 + 178 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_subscribe.c + mqtt_client_subscribe.c + 0 + 0 + + + 17 + 179 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_unsubscribe.c + mqtt_client_unsubscribe.c + 0 + 0 + + + 17 + 180 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_yield.c + mqtt_client_yield.c + 0 + 0 + + + + + qcloud/utils + 0 + 0 + 0 + 0 + + 18 + 181 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\json_parser.c + json_parser.c + 0 + 0 + + + 18 + 182 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\json_token.c + json_token.c + 0 + 0 + + + 18 + 183 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_log.c + qcloud_iot_log.c + 0 + 0 + + + 18 + 184 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\string_utils.c + string_utils.c + 0 + 0 + + + 18 + 185 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_aes.c + utils_aes.c + 0 + 0 + + + 18 + 186 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_base64.c + utils_base64.c + 0 + 0 + + + 18 + 187 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_getopt.c + utils_getopt.c + 0 + 0 + + + 18 + 188 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_hmac.c + utils_hmac.c + 0 + 0 + + + 18 + 189 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_list.c + utils_list.c + 0 + 0 + + + 18 + 190 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_md5.c + utils_md5.c + 0 + 0 + + + 18 + 191 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_ringbuff.c + utils_ringbuff.c + 0 + 0 + + + 18 + 192 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_sha1.c + utils_sha1.c + 0 + 0 + + + 18 + 193 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_timer.c + utils_timer.c + 0 + 0 + + + 18 + 194 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_ca.c + qcloud_iot_ca.c + 0 + 0 + + + 18 + 195 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_device.c + qcloud_iot_device.c + 0 + 0 + + + + + qcloud/network + 0 + 0 + 0 + 0 + + 19 + 196 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\network_interface.c + network_interface.c + 0 + 0 + + + 19 + 197 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\socket\network_socket.c + network_socket.c + 0 + 0 + + + 19 + 198 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\tls\network_tls.c + network_tls.c + 0 + 0 + + + 19 + 199 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\platform\tls\mbedtls\HAL_DTLS_mbedtls.c + HAL_DTLS_mbedtls.c + 0 + 0 + + + 19 + 200 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\platform\tls\mbedtls\HAL_TLS_mbedtls.c + HAL_TLS_mbedtls.c + 0 + 0 + + + + + qcloud/services/ota + 0 + 0 + 0 + 0 + + 20 + 201 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_client.c + ota_client.c + 0 + 0 + + + 20 + 202 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_fetch.c + ota_fetch.c + 0 + 0 + + + 20 + 203 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_lib.c + ota_lib.c + 0 + 0 + + + 20 + 204 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_mqtt.c + ota_mqtt.c + 0 + 0 + + + + + qcloud/protocol/http + 0 + 0 + 0 + 0 + + 21 + 205 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\http\utils_httpc.c + utils_httpc.c + 0 + 0 + + + + + ota/common + 0 + 0 + 0 + 0 + + 22 + 206 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\flash\ota_flash.c + ota_flash.c + 0 + 0 + + + 22 + 207 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\crc\crc8.c + crc8.c + 0 + 0 + + + 22 + 208 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\image\ota_image.c + ota_image.c + 0 + 0 + + + 22 + 209 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\partition\ota_partition.c + ota_partition.c + 0 + 0 + + + 22 + 210 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\env\ota_env.c + ota_env.c + 0 + 0 + + + 22 + 211 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\ota\common\info\ota_info.c + ota_info.c + 0 + 0 + + + + + kv + 0 + 0 + 0 + 0 + + 23 + 212 + 1 + 0 + 0 + 0 + ..\..\..\..\..\components\fs\kv\tos_kv.c + tos_kv.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvprojx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvprojx new file mode 100644 index 00000000..d1cb67fd --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvprojx @@ -0,0 +1,1577 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + TencentOS_tiny + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + STM32L431RCTx + STMicroelectronics + Keil.STM32L4xx_DFP.2.0.0 + http://www.keil.com/pack + IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4") + + + + + + + + + + + + + + + $$Device:STM32L431RCTx$CMSIS\SVD\STM32L4x1.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\obj\ + TencentOS_tiny + 1 + 0 + 1 + 1 + 0 + .\list\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4107 + + 1 + STLink\ST-LINKIII-KEIL_SWO.dll + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32L431xx,MBEDTLS_CONFIG_FILE=<qcloud/tls_psk_config.h> + + ..\..\..\BSP\Inc;..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Inc;..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Legacy;..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Include;..\..\..\..\..\kernel\core\include;..\..\..\..\..\platform\arch\arm\cortex-m4\keil;..\..\..\..\..\kernel\pm\include;..\..\..\..\..\kernel\hal\include;..\..\..\..\..\arch\arm\arm-v7m\common\include;..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc;..\..\..\..\..\osal\cmsis_os;..\..\..\..\..\devices\esp8266;..\..\..\..\..\devices\rhf76_lora;..\..\..\..\..\devices\esp8266_tencent_firmware;..\..\..\..\..\devices\bc35_28_95;..\..\..\BSP\Hardware\DHT11;..\..\..\BSP\Hardware\OLED;..\..\..\BSP\Hardware\BH1750;..\..\..\TOS-CONFIG;..\..\..\..\..\examples\helloworld;..\..\..\..\..\components\security\mbedtls\3rdparty\include;..\..\..\..\..\components\security\mbedtls\wrapper\include;..\..\..\..\..\net\at\include;..\..\..\..\..\net\sal_module_wrapper;..\..\..\..\..\net\lora_module_wrapper;..\..\..\..\..\net\tencent_firmware_module_wrapper;..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\include;..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\include\exports;..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\internal_inc;..\..\..\..\..\components\fs\kv\include;..\..\..\..\..\components\ota\common\flash;..\..\..\..\..\components\ota\common\crc;..\..\..\..\..\components\ota\common\image;..\..\..\..\..\components\ota\common\partition;..\..\..\..\..\components\ota\common\env;..\..\..\..\..\components\ota\download\include;..\..\..\..\..\components\ota\common\info + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32l431xx.s + 2 + startup_stm32l431xx.s + + + + + Application/User + + + gpio.c + 1 + ..\..\..\BSP\Src\gpio.c + + + main.c + 1 + ..\..\..\BSP\Src\main.c + + + mcu_init.c + 1 + ..\..\..\BSP\Src\mcu_init.c + + + stm32l4xx_hal_msp.c + 1 + ..\..\..\BSP\Src\stm32l4xx_hal_msp.c + + + usart.c + 1 + ..\..\..\BSP\Src\usart.c + + + adc.c + 1 + ..\..\..\BSP\Src\adc.c + + + dac.c + 1 + ..\..\..\BSP\Src\dac.c + + + i2c.c + 1 + ..\..\..\BSP\Src\i2c.c + + + spi.c + 1 + ..\..\..\BSP\Src\spi.c + + + stm32l4xx_it_module.c + 1 + ..\..\..\BSP\Src\stm32l4xx_it_module.c + + + tim.c + 1 + ..\..\..\BSP\Src\tim.c + + + + + examples + + + entry.c + 1 + ..\..\..\..\..\examples\ota_download_through_qcloud_iot_explorer\entry.c + + + ota_download_through_qcloud_iot_explorer_sample.c + 1 + ..\..\..\..\..\examples\ota_download_through_qcloud_iot_explorer\ota_download_through_qcloud_iot_explorer_sample.c + + + + + Drivers/STM32L4xx_HAL_Driver + + + stm32l4xx_hal_tim.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + + + stm32l4xx_hal_tim_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + + + stm32l4xx_hal_uart.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + + + stm32l4xx_hal_uart_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + + + stm32l4xx_hal.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + + + stm32l4xx_hal_i2c.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + + + stm32l4xx_hal_i2c_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + + + stm32l4xx_hal_rcc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + + + stm32l4xx_hal_rcc_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + + + stm32l4xx_hal_flash.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + + + stm32l4xx_hal_flash_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + + + stm32l4xx_hal_flash_ramfunc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + + + stm32l4xx_hal_gpio.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + + + stm32l4xx_hal_dma.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + + + stm32l4xx_hal_dma_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + + + stm32l4xx_hal_pwr.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + + + stm32l4xx_hal_pwr_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + + + stm32l4xx_hal_cortex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + + + stm32l4xx_hal_adc_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + + + stm32l4xx_hal_adc.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + + + stm32l4xx_hal_dac.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + + + stm32l4xx_hal_dac_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + + + stm32l4xx_hal_spi.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + + + stm32l4xx_hal_spi_ex.c + 1 + ..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + + + + + Drivers/CMSIS + + + system_stm32l4xx.c + 1 + ..\..\..\BSP\Src\system_stm32l4xx.c + + + + + Hardware + + + DHT11_BUS.c + 1 + ..\..\..\BSP\Hardware\DHT11\DHT11_BUS.c + + + oled.c + 1 + ..\..\..\BSP\Hardware\OLED\oled.c + + + BH1750.c + 1 + ..\..\..\BSP\Hardware\BH1750\BH1750.c + + + onchip_flash.c + 1 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + + + onchip_flash_ota.c + 1 + ..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + + + + + kernel + + + tos_binary_heap.c + 1 + ..\..\..\..\..\kernel\core\tos_binary_heap.c + + + tos_char_fifo.c + 1 + ..\..\..\..\..\kernel\core\tos_char_fifo.c + + + tos_completion.c + 1 + ..\..\..\..\..\kernel\core\tos_completion.c + + + tos_countdownlatch.c + 1 + ..\..\..\..\..\kernel\core\tos_countdownlatch.c + + + tos_event.c + 1 + ..\..\..\..\..\kernel\core\tos_event.c + + + tos_global.c + 1 + ..\..\..\..\..\kernel\core\tos_global.c + + + tos_mail_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_mail_queue.c + + + tos_message_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_message_queue.c + + + tos_mmblk.c + 1 + ..\..\..\..\..\kernel\core\tos_mmblk.c + + + tos_mmheap.c + 1 + ..\..\..\..\..\kernel\core\tos_mmheap.c + + + tos_mutex.c + 1 + ..\..\..\..\..\kernel\core\tos_mutex.c + + + tos_pend.c + 1 + ..\..\..\..\..\kernel\core\tos_pend.c + + + tos_priority_mail_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + + + tos_priority_message_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_message_queue.c + + + tos_priority_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_priority_queue.c + + + tos_ring_queue.c + 1 + ..\..\..\..\..\kernel\core\tos_ring_queue.c + + + tos_robin.c + 1 + ..\..\..\..\..\kernel\core\tos_robin.c + + + tos_sched.c + 1 + ..\..\..\..\..\kernel\core\tos_sched.c + + + tos_sem.c + 1 + ..\..\..\..\..\kernel\core\tos_sem.c + + + tos_sys.c + 1 + ..\..\..\..\..\kernel\core\tos_sys.c + + + tos_task.c + 1 + ..\..\..\..\..\kernel\core\tos_task.c + + + tos_tick.c + 1 + ..\..\..\..\..\kernel\core\tos_tick.c + + + tos_time.c + 1 + ..\..\..\..\..\kernel\core\tos_time.c + + + tos_timer.c + 1 + ..\..\..\..\..\kernel\core\tos_timer.c + + + tos_stopwatch.c + 1 + ..\..\..\..\..\kernel\core\tos_stopwatch.c + + + + + cpu + + + port_s.S + 2 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + + + tos_cpu.c + 1 + ..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + + + port_c.c + 1 + ..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + + + + + cmsis + + + cmsis_os.c + 1 + ..\..\..\..\..\osal\cmsis_os\cmsis_os.c + + + + + module_wrapper + + + sal_module_wrapper.c + 1 + ..\..\..\..\..\net\sal_module_wrapper\sal_module_wrapper.c + + + lora_module_wrapper.c + 1 + ..\..\..\..\..\net\lora_module_wrapper\lora_module_wrapper.c + + + tencent_firmware_module_wrapper.c + 1 + ..\..\..\..\..\net\tencent_firmware_module_wrapper\tencent_firmware_module_wrapper.c + + + + + devices + + + esp8266.c + 1 + ..\..\..\..\..\devices\esp8266\esp8266.c + + + RHF76.c + 1 + ..\..\..\..\..\devices\rhf76_lora\RHF76.c + + + bc35_28_95.c + 1 + ..\..\..\..\..\devices\bc35_28_95\bc35_28_95.c + + + esp8266_tencent_firmware.c + 1 + ..\..\..\..\..\devices\esp8266_tencent_firmware\esp8266_tencent_firmware.c + + + sim800a.c + 1 + ..\..\..\..\..\devices\sim800a\sim800a.c + + + + + config + + + tos_config.h + 5 + ..\..\..\TOS-CONFIG\tos_config.h + + + + + hal + + + tos_hal_uart.c + 1 + ..\..\..\..\..\platform\hal\st\stm32l4xx\src\tos_hal_uart.c + + + + + at-framwork + + + tos_at.c + 1 + ..\..\..\..\..\net\at\src\tos_at.c + + + + + mbedtls + + + entropy_hardware_alt.c + 1 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\entropy_hardware_alt.c + + + net_module_alt.c + 1 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\net_module_alt.c + + + timing_alt.c + 1 + ..\..\..\..\..\components\security\mbedtls\wrapper\src\timing_alt.c + + + aes.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aes.c + + + aesni.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aesni.c + + + arc4.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\arc4.c + + + aria.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\aria.c + + + asn1parse.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\asn1parse.c + + + asn1write.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\asn1write.c + + + base64.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\base64.c + + + bignum.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\bignum.c + + + blowfish.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\blowfish.c + + + camellia.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\camellia.c + + + ccm.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ccm.c + + + certs.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\certs.c + + + chacha20.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\chacha20.c + + + chachapoly.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\chachapoly.c + + + cipher.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cipher.c + + + cipher_wrap.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cipher_wrap.c + + + cmac.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\cmac.c + + + ctr_drbg.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ctr_drbg.c + + + debug.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\debug.c + + + des.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\des.c + + + dhm.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\dhm.c + + + ecdh.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecdh.c + + + ecdsa.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecdsa.c + + + ecjpake.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecjpake.c + + + ecp.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecp.c + + + ecp_curves.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ecp_curves.c + + + entropy.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\entropy.c + + + entropy_poll.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\entropy_poll.c + + + error.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\error.c + + + gcm.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\gcm.c + + + havege.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\havege.c + + + hkdf.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\hkdf.c + + + hmac_drbg.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\hmac_drbg.c + + + md.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md.c + + + md_wrap.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md_wrap.c + + + md2.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md2.c + + + md4.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md4.c + + + md5.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\md5.c + + + memory_buffer_alloc.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\memory_buffer_alloc.c + + + net_sockets.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\net_sockets.c + + + nist_kw.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\nist_kw.c + + + oid.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\oid.c + + + padlock.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\padlock.c + + + pem.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pem.c + + + pk.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pk.c + + + pk_wrap.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pk_wrap.c + + + pkcs5.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs5.c + + + pkcs11.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs11.c + + + pkcs12.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkcs12.c + + + pkparse.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkparse.c + + + pkwrite.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\pkwrite.c + + + platform.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\platform.c + + + platform_util.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\platform_util.c + + + poly1305.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\poly1305.c + + + ripemd160.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ripemd160.c + + + rsa.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\rsa.c + + + rsa_internal.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\rsa_internal.c + + + sha1.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha1.c + + + sha256.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha256.c + + + sha512.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\sha512.c + + + ssl_cache.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cache.c + + + ssl_ciphersuites.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_ciphersuites.c + + + ssl_cli.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cli.c + + + ssl_cookie.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_cookie.c + + + ssl_srv.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_srv.c + + + ssl_ticket.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_ticket.c + + + ssl_tls.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\ssl_tls.c + + + threading.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\threading.c + + + timing.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\timing.c + + + version.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\version.c + + + version_features.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\version_features.c + + + x509.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509.c + + + x509_create.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_create.c + + + x509_crl.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_crl.c + + + x509_crt.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_crt.c + + + x509_csr.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509_csr.c + + + x509write_crt.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509write_crt.c + + + x509write_csr.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\x509write_csr.c + + + xtea.c + 1 + ..\..\..\..\..\components\security\mbedtls\3rdparty\src\xtea.c + + + + + qcloud/port + + + HAL_AT_UART_tencentos_tiny.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_AT_UART_tencentos_tiny.c + + + HAL_Device_tencentos_tiny.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_Device_tencentos_tiny.c + + + HAL_OS_tencentos_tiny.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_OS_tencentos_tiny.c + + + HAL_TCP_module.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_TCP_module.c + + + HAL_Timer_tencentos_tiny.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_Timer_tencentos_tiny.c + + + HAL_UDP_module.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\port\TencentOS_tiny\HAL_UDP_module.c + + + + + qcloud/protocol/mqtt + + + mqtt_client.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client.c + + + mqtt_client_common.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_common.c + + + mqtt_client_connect.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_connect.c + + + mqtt_client_net.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_net.c + + + mqtt_client_publish.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_publish.c + + + mqtt_client_subscribe.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_subscribe.c + + + mqtt_client_unsubscribe.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_unsubscribe.c + + + mqtt_client_yield.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\mqtt\mqtt_client_yield.c + + + + + qcloud/utils + + + json_parser.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\json_parser.c + + + json_token.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\json_token.c + + + qcloud_iot_log.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_log.c + + + string_utils.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\string_utils.c + + + utils_aes.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_aes.c + + + utils_base64.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_base64.c + + + utils_getopt.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_getopt.c + + + utils_hmac.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_hmac.c + + + utils_list.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_list.c + + + utils_md5.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_md5.c + + + utils_ringbuff.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_ringbuff.c + + + utils_sha1.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_sha1.c + + + utils_timer.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\utils_timer.c + + + qcloud_iot_ca.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_ca.c + + + qcloud_iot_device.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\utils\qcloud_iot_device.c + + + + + qcloud/network + + + network_interface.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\network_interface.c + + + network_socket.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\socket\network_socket.c + + + network_tls.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\network\tls\network_tls.c + + + HAL_DTLS_mbedtls.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\platform\tls\mbedtls\HAL_DTLS_mbedtls.c + + + HAL_TLS_mbedtls.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\platform\tls\mbedtls\HAL_TLS_mbedtls.c + + + + + qcloud/services/ota + + + ota_client.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_client.c + + + ota_fetch.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_fetch.c + + + ota_lib.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_lib.c + + + ota_mqtt.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\services\ota\ota_mqtt.c + + + + + qcloud/protocol/http + + + utils_httpc.c + 1 + ..\..\..\..\..\components\connectivity\qcloud-iot-explorer-sdk\3rdparty\sdk_src\protocol\http\utils_httpc.c + + + + + ota/common + + + ota_flash.c + 1 + ..\..\..\..\..\components\ota\common\flash\ota_flash.c + + + crc8.c + 1 + ..\..\..\..\..\components\ota\common\crc\crc8.c + + + ota_image.c + 1 + ..\..\..\..\..\components\ota\common\image\ota_image.c + + + ota_partition.c + 1 + ..\..\..\..\..\components\ota\common\partition\ota_partition.c + + + ota_env.c + 1 + ..\..\..\..\..\components\ota\common\env\ota_env.c + + + ota_info.c + 1 + ..\..\..\..\..\components\ota\common\info\ota_info.c + + + + + kv + + + tos_kv.c + 1 + ..\..\..\..\..\components\fs\kv\tos_kv.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/startup_stm32l431xx.s b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/startup_stm32l431xx.s new file mode 100644 index 00000000..6a5c15a5 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/startup_stm32l431xx.s @@ -0,0 +1,404 @@ +;********************** COPYRIGHT(c) 2017 STMicroelectronics ****************** +;* File Name : startup_stm32l431xx.s +;* Author : MCD Application Team +;* Description : STM32L431xx Ultra Low Power devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;* +;******************************************************************************* +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x100 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x100 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection + DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line + DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_IRQHandler ; ADC1 + DCD CAN1_TX_IRQHandler ; CAN1 TX + DCD CAN1_RX0_IRQHandler ; CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; CAN1 SCE + DCD EXTI9_5_IRQHandler ; External Line[9:5]s + DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15 + DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; External Line[15:10] + DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD 0 ; Reserved + DCD SPI3_IRQHandler ; SPI3 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD COMP_IRQHandler ; COMP Interrupt + DCD LPTIM1_IRQHandler ; LP TIM1 interrupt + DCD LPTIM2_IRQHandler ; LP TIM2 interrupt + DCD 0 ; Reserved + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 + DCD LPUART1_IRQHandler ; LP UART1 interrupt + DCD QUADSPI_IRQHandler ; Quad SPI global interrupt + DCD I2C3_EV_IRQHandler ; I2C3 event + DCD I2C3_ER_IRQHandler ; I2C3 error + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD 0 ; Reserved + DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt + DCD TSC_IRQHandler ; Touch Sense Controller global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD RNG_IRQHandler ; RNG global interrupt + DCD FPU_IRQHandler ; FPU + DCD CRS_IRQHandler ; CRS interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_PVM_IRQHandler [WEAK] + EXPORT TAMP_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK] + EXPORT TIM1_UP_TIM16_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT TIM6_DAC_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT DMA2_Channel6_IRQHandler [WEAK] + EXPORT DMA2_Channel7_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT QUADSPI_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SWPMI1_IRQHandler [WEAK] + EXPORT TSC_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_PVM_IRQHandler +TAMP_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_TIM15_IRQHandler +TIM1_UP_TIM16_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +SDMMC1_IRQHandler +SPI3_IRQHandler +TIM6_DAC_IRQHandler +TIM7_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +COMP_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +DMA2_Channel6_IRQHandler +DMA2_Channel7_IRQHandler +LPUART1_IRQHandler +QUADSPI_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SAI1_IRQHandler +SWPMI1_IRQHandler +TSC_IRQHandler +RNG_IRQHandler +FPU_IRQHandler +CRS_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_hal_conf.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_hal_conf.h new file mode 100644 index 00000000..96c68cbc --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_hal_conf.h @@ -0,0 +1,450 @@ +/** + ****************************************************************************** + * @file stm32l4xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_HAL_CONF_H +#define __STM32L4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_DMA2D_MODULE_ENABLED */ +/*#define HAL_DFSDM_MODULE_ENABLED */ +/*#define HAL_DSI_MODULE_ENABLED */ +/*#define HAL_FIREWALL_MODULE_ENABLED */ +/*#define HAL_GFXMMU_MODULE_ENABLED */ +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LTDC_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_MMC_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_SWPMI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_EXTI_MODULE_ENABLED */ +/*#define HAL_PSSI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)4000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/** + * @brief External clock source for SAI2 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI2_CLOCK_VALUE) + #define EXTERNAL_SAI2_CLOCK_VALUE ((uint32_t)48000U) /*!< Value of the SAI2 External clock source in Hz*/ +#endif /* EXTERNAL_SAI2_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l4xx_hal_rcc.h" + #include "stm32l4xx_hal_rcc_ex.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32l4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l4xx_hal_dma.h" + #include "stm32l4xx_hal_dma_ex.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32l4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32l4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32l4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32l4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32l4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l4xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32l4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32l4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32l4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32l4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32l4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l4xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32l4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32l4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + #include "stm32l4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_OSPI_MODULE_ENABLED + #include "stm32l4xx_hal_ospi.h" +#endif /* HAL_OSPI_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32l4xx_hal_pka.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32l4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32l4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32l4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SWPMI_MODULE_ENABLED + #include "stm32l4xx_hal_swpmi.h" +#endif /* HAL_SWPMI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l4xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32l4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32l4xx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED + #include "stm32l4xx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(char *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_it.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_it.h new file mode 100644 index 00000000..1bedbf68 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_it.h @@ -0,0 +1,69 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32l4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_IT_H +#define __STM32L4xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvoptx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvoptx new file mode 100644 index 00000000..085943b7 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvoptx @@ -0,0 +1,1801 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + TencentOS_tiny + 0x4 + ARM-ADS + + 80000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\list\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U303030303030303030303031 -O10446 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM) + + + + + 0 + 0 + 55 + 0 +
134240840
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\..\components\ota\common\lzma\wrapper\lzma_uncompress.c + + \\TencentOS_tiny\../../../../../../components/ota/common/lzma/wrapper/lzma_uncompress.c\55 +
+ + 1 + 0 + 119 + 0 +
134242160
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\..\components\ota\common\partition\ota_partition.c + + \\TencentOS_tiny\../../../../../../components/ota/common/partition/ota_partition.c\119 +
+ + 2 + 0 + 63 + 1 +
134240906
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\Src\main.c + + \\TencentOS_tiny\../Src/main.c\63 +
+ + 3 + 0 + 287 + 1 +
134243064
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery.c + + \\TencentOS_tiny\../../../../../../components/ota/recovery/ota_recovery.c\287 +
+ + 4 + 0 + 61 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\Src\main.c + + +
+ + 5 + 0 + 310 + 0 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery_xip.c + + +
+
+ + + 0 + 1 + pEraseInit->Page + pEraseInit->NbPages + + + 1 + 1 + page_index + + + + + 1 + 0 + app_addr + 0 + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + +
+
+ + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + startup_stm32l431xx.s + startup_stm32l431xx.s + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\Src\main.c + main.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\Src\stm32l4xx_hal_msp.c + stm32l4xx_hal_msp.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\Src\stm32l4xx_it.c + stm32l4xx_it.c + 0 + 0 + + + + + Drivers/STM32L4xx_HAL_Driver + 0 + 0 + 0 + 0 + + 3 + 5 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + stm32l4xx_hal_tim.c + 0 + 0 + + + 3 + 6 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + stm32l4xx_hal_tim_ex.c + 0 + 0 + + + 3 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + stm32l4xx_hal_uart.c + 0 + 0 + + + 3 + 8 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + stm32l4xx_hal_uart_ex.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + stm32l4xx_hal.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + stm32l4xx_hal_i2c.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + stm32l4xx_hal_i2c_ex.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + stm32l4xx_hal_rcc.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + stm32l4xx_hal_rcc_ex.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + stm32l4xx_hal_flash.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + stm32l4xx_hal_flash_ex.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + stm32l4xx_hal_flash_ramfunc.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + stm32l4xx_hal_gpio.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + stm32l4xx_hal_dma.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + stm32l4xx_hal_dma_ex.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + stm32l4xx_hal_pwr.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + stm32l4xx_hal_pwr_ex.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + stm32l4xx_hal_cortex.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + stm32l4xx_hal_adc_ex.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + stm32l4xx_hal_adc.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + stm32l4xx_hal_dac.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + stm32l4xx_hal_dac_ex.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + stm32l4xx_hal_spi.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + stm32l4xx_hal_spi_ex.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 4 + 29 + 1 + 0 + 0 + 0 + ..\Src\system_stm32l4xx.c + system_stm32l4xx.c + 0 + 0 + + + + + Hardware + 0 + 0 + 0 + 0 + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + onchip_flash.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + onchip_flash_ota.c + 0 + 0 + + + + + kernel + 0 + 0 + 0 + 0 + + 6 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_binary_heap.c + tos_binary_heap.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_char_fifo.c + tos_char_fifo.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_completion.c + tos_completion.c + 0 + 0 + + + 6 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_countdownlatch.c + tos_countdownlatch.c + 0 + 0 + + + 6 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_event.c + tos_event.c + 0 + 0 + + + 6 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_global.c + tos_global.c + 0 + 0 + + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_mail_queue.c + tos_mail_queue.c + 0 + 0 + + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_message_queue.c + tos_message_queue.c + 0 + 0 + + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_mmblk.c + tos_mmblk.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_mmheap.c + tos_mmheap.c + 0 + 0 + + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_mutex.c + tos_mutex.c + 0 + 0 + + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_pend.c + tos_pend.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + tos_priority_mail_queue.c + 0 + 0 + + + 6 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_priority_message_queue.c + tos_priority_message_queue.c + 0 + 0 + + + 6 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_priority_queue.c + tos_priority_queue.c + 0 + 0 + + + 6 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_ring_queue.c + tos_ring_queue.c + 0 + 0 + + + 6 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_robin.c + tos_robin.c + 0 + 0 + + + 6 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_sched.c + tos_sched.c + 0 + 0 + + + 6 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_sem.c + tos_sem.c + 0 + 0 + + + 6 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_sys.c + tos_sys.c + 0 + 0 + + + 6 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_task.c + tos_task.c + 0 + 0 + + + 6 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_tick.c + tos_tick.c + 0 + 0 + + + 6 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_time.c + tos_time.c + 0 + 0 + + + 6 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_timer.c + tos_timer.c + 0 + 0 + + + 6 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_barrier.c + tos_barrier.c + 0 + 0 + + + 6 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_bitmap.c + tos_bitmap.c + 0 + 0 + + + 6 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_rwlock.c + tos_rwlock.c + 0 + 0 + + + 6 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\kernel\core\tos_stopwatch.c + tos_stopwatch.c + 0 + 0 + + + + + cpu + 0 + 0 + 0 + 0 + + 7 + 60 + 2 + 0 + 0 + 0 + ..\..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + port_s.S + 0 + 0 + + + 7 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + tos_cpu.c + 0 + 0 + + + 7 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + port_c.c + 0 + 0 + + + + + config + 0 + 0 + 0 + 0 + + 8 + 63 + 5 + 0 + 0 + 0 + ..\TOS-CONFIG\tos_config.h + tos_config.h + 0 + 0 + + + + + ota_recovery + 0 + 0 + 0 + 0 + + 9 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery.c + ota_recovery.c + 0 + 0 + + + 9 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery_xip.c + ota_recovery_xip.c + 0 + 0 + + + 9 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\recovery\ota_patch.c + ota_patch.c + 0 + 0 + + + 9 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\recovery\ota_patch_xip.c + ota_patch_xip.c + 0 + 0 + + + + + ota_common + 0 + 0 + 0 + 0 + + 10 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\flash\ota_flash.c + ota_flash.c + 0 + 0 + + + 10 + 69 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\crc\crc8.c + crc8.c + 0 + 0 + + + 10 + 70 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\image\ota_image.c + ota_image.c + 0 + 0 + + + 10 + 71 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\env\ota_env.c + ota_env.c + 0 + 0 + + + 10 + 72 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\partition\ota_partition.c + ota_partition.c + 0 + 0 + + + 10 + 73 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\info\ota_info.c + ota_info.c + 0 + 0 + + + + + lzma + 0 + 0 + 0 + 0 + + 11 + 74 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zAlloc.c + 7zAlloc.c + 0 + 0 + + + 11 + 75 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zArcIn.c + 7zArcIn.c + 0 + 0 + + + 11 + 76 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zBuf.c + 7zBuf.c + 0 + 0 + + + 11 + 77 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zBuf2.c + 7zBuf2.c + 0 + 0 + + + 11 + 78 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zCrc.c + 7zCrc.c + 0 + 0 + + + 11 + 79 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zCrcOpt.c + 7zCrcOpt.c + 0 + 0 + + + 11 + 80 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zDec.c + 7zDec.c + 0 + 0 + + + 11 + 81 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zFile.c + 7zFile.c + 0 + 0 + + + 11 + 82 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zStream.c + 7zStream.c + 0 + 0 + + + 11 + 83 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Aes.c + Aes.c + 0 + 0 + + + 11 + 84 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\AesOpt.c + AesOpt.c + 0 + 0 + + + 11 + 85 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Alloc.c + Alloc.c + 0 + 0 + + + 11 + 86 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bcj2.c + Bcj2.c + 0 + 0 + + + 11 + 87 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bcj2Enc.c + Bcj2Enc.c + 0 + 0 + + + 11 + 88 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bra.c + Bra.c + 0 + 0 + + + 11 + 89 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bra86.c + Bra86.c + 0 + 0 + + + 11 + 90 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\BraIA64.c + BraIA64.c + 0 + 0 + + + 11 + 91 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\CpuArch.c + CpuArch.c + 0 + 0 + + + 11 + 92 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Delta.c + Delta.c + 0 + 0 + + + 11 + 93 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\DllSecur.c + DllSecur.c + 0 + 0 + + + 11 + 94 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzFind.c + LzFind.c + 0 + 0 + + + 11 + 95 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma2Dec.c + Lzma2Dec.c + 0 + 0 + + + 11 + 96 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma2Enc.c + Lzma2Enc.c + 0 + 0 + + + 11 + 97 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma86Dec.c + Lzma86Dec.c + 0 + 0 + + + 11 + 98 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma86Enc.c + Lzma86Enc.c + 0 + 0 + + + 11 + 99 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaDec.c + LzmaDec.c + 0 + 0 + + + 11 + 100 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaEnc.c + LzmaEnc.c + 0 + 0 + + + 11 + 101 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaLib.c + LzmaLib.c + 0 + 0 + + + 11 + 102 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7.c + Ppmd7.c + 0 + 0 + + + 11 + 103 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7Dec.c + Ppmd7Dec.c + 0 + 0 + + + 11 + 104 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7Enc.c + Ppmd7Enc.c + 0 + 0 + + + 11 + 105 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Sha256.c + Sha256.c + 0 + 0 + + + 11 + 106 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Sort.c + Sort.c + 0 + 0 + + + 11 + 107 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Xz.c + Xz.c + 0 + 0 + + + 11 + 108 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzCrc64.c + XzCrc64.c + 0 + 0 + + + 11 + 109 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzCrc64Opt.c + XzCrc64Opt.c + 0 + 0 + + + 11 + 110 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzDec.c + XzDec.c + 0 + 0 + + + 11 + 111 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzEnc.c + XzEnc.c + 0 + 0 + + + 11 + 112 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzIn.c + XzIn.c + 0 + 0 + + + + + lzma_wrapper + 0 + 0 + 0 + 0 + + 12 + 113 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\ota\common\lzma\wrapper\lzma_uncompress.c + lzma_uncompress.c + 0 + 0 + + + + + kv + 0 + 0 + 0 + 0 + + 13 + 114 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\components\fs\kv\tos_kv.c + tos_kv.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvprojx b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvprojx new file mode 100644 index 00000000..c4a3aaec --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvprojx @@ -0,0 +1,1037 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + TencentOS_tiny + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + STM32L431RCTx + STMicroelectronics + Keil.STM32L4xx_DFP.2.0.0 + http://www.keil.com/pack + IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4") + + + + + + + + + + + + + + + $$Device:STM32L431RCTx$CMSIS\SVD\STM32L4x1.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\obj\ + TencentOS_tiny + 1 + 0 + 1 + 1 + 0 + .\list\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4107 + + 1 + STLink\ST-LINKIII-KEIL_SWO.dll + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32L431xx, + + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Inc;..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Legacy;..\..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\..\..\platform\vendor_bsp\st\CMSIS\Include;..\..\..\..\..\..\kernel\core\include;..\TOS-CONFIG;..\..\..\..\..\..\platform\arch\arm\cortex-m4\keil;..\..\..\..\..\..\kernel\pm\include;..\..\..\..\..\..\arch\arm\arm-v7m\common\include;..\..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc;..\..\..\..\..\..\components\ota\recovery\include;..\..\..\..\..\..\components\ota\common\crc;..\..\..\..\..\..\components\ota\common\image;..\..\..\..\..\..\components\ota\common\flash;..\..\..\..\..\..\components\ota\common\bsdiff;..\..\..\..\..\..\components\ota\common\lzma\3rdparty;..\..\..\..\..\..\components\ota\common\lzma\wrapper;..\..\..\..\..\..\components\ota\common\partition;..\..\..\..\..\..\components\ota\common\env;..\..\..\..\..\..\components\fs\kv\include;..\..\..\..\..\..\components\ota\common\info;..\Inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32l431xx.s + 2 + startup_stm32l431xx.s + + + + + Application/User + + + main.c + 1 + ..\Src\main.c + + + stm32l4xx_hal_msp.c + 1 + ..\Src\stm32l4xx_hal_msp.c + + + stm32l4xx_it.c + 1 + ..\Src\stm32l4xx_it.c + + + + + Drivers/STM32L4xx_HAL_Driver + + + stm32l4xx_hal_tim.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + + + stm32l4xx_hal_tim_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + + + stm32l4xx_hal_uart.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + + + stm32l4xx_hal_uart_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + + + stm32l4xx_hal.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + + + stm32l4xx_hal_i2c.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + + + stm32l4xx_hal_i2c_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + + + stm32l4xx_hal_rcc.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + + + stm32l4xx_hal_rcc_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + + + stm32l4xx_hal_flash.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + + + stm32l4xx_hal_flash_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + + + stm32l4xx_hal_flash_ramfunc.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + + + stm32l4xx_hal_gpio.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + + + stm32l4xx_hal_dma.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + + + stm32l4xx_hal_dma_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + + + stm32l4xx_hal_pwr.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + + + stm32l4xx_hal_pwr_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + + + stm32l4xx_hal_cortex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + + + stm32l4xx_hal_adc_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + + + stm32l4xx_hal_adc.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + + + stm32l4xx_hal_dac.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac.c + + + stm32l4xx_hal_dac_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dac_ex.c + + + stm32l4xx_hal_spi.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + + + stm32l4xx_hal_spi_ex.c + 1 + ..\..\..\..\..\..\platform\vendor_bsp\st\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi_ex.c + + + + + Drivers/CMSIS + + + system_stm32l4xx.c + 1 + ..\Src\system_stm32l4xx.c + + + + + Hardware + + + onchip_flash.c + 1 + ..\..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash.c + + + onchip_flash_ota.c + 1 + ..\..\..\..\BSP\Hardware\ONCHIP_FLASH\onchip_flash_ota.c + + + + + kernel + + + tos_binary_heap.c + 1 + ..\..\..\..\..\..\kernel\core\tos_binary_heap.c + + + tos_char_fifo.c + 1 + ..\..\..\..\..\..\kernel\core\tos_char_fifo.c + + + tos_completion.c + 1 + ..\..\..\..\..\..\kernel\core\tos_completion.c + + + tos_countdownlatch.c + 1 + ..\..\..\..\..\..\kernel\core\tos_countdownlatch.c + + + tos_event.c + 1 + ..\..\..\..\..\..\kernel\core\tos_event.c + + + tos_global.c + 1 + ..\..\..\..\..\..\kernel\core\tos_global.c + + + tos_mail_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_mail_queue.c + + + tos_message_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_message_queue.c + + + tos_mmblk.c + 1 + ..\..\..\..\..\..\kernel\core\tos_mmblk.c + + + tos_mmheap.c + 1 + ..\..\..\..\..\..\kernel\core\tos_mmheap.c + + + tos_mutex.c + 1 + ..\..\..\..\..\..\kernel\core\tos_mutex.c + + + tos_pend.c + 1 + ..\..\..\..\..\..\kernel\core\tos_pend.c + + + tos_priority_mail_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_priority_mail_queue.c + + + tos_priority_message_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_priority_message_queue.c + + + tos_priority_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_priority_queue.c + + + tos_ring_queue.c + 1 + ..\..\..\..\..\..\kernel\core\tos_ring_queue.c + + + tos_robin.c + 1 + ..\..\..\..\..\..\kernel\core\tos_robin.c + + + tos_sched.c + 1 + ..\..\..\..\..\..\kernel\core\tos_sched.c + + + tos_sem.c + 1 + ..\..\..\..\..\..\kernel\core\tos_sem.c + + + tos_sys.c + 1 + ..\..\..\..\..\..\kernel\core\tos_sys.c + + + tos_task.c + 1 + ..\..\..\..\..\..\kernel\core\tos_task.c + + + tos_tick.c + 1 + ..\..\..\..\..\..\kernel\core\tos_tick.c + + + tos_time.c + 1 + ..\..\..\..\..\..\kernel\core\tos_time.c + + + tos_timer.c + 1 + ..\..\..\..\..\..\kernel\core\tos_timer.c + + + tos_barrier.c + 1 + ..\..\..\..\..\..\kernel\core\tos_barrier.c + + + tos_bitmap.c + 1 + ..\..\..\..\..\..\kernel\core\tos_bitmap.c + + + tos_rwlock.c + 1 + ..\..\..\..\..\..\kernel\core\tos_rwlock.c + + + tos_stopwatch.c + 1 + ..\..\..\..\..\..\kernel\core\tos_stopwatch.c + + + + + cpu + + + port_s.S + 2 + ..\..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_s.S + + + tos_cpu.c + 1 + ..\..\..\..\..\..\arch\arm\arm-v7m\common\tos_cpu.c + + + port_c.c + 1 + ..\..\..\..\..\..\arch\arm\arm-v7m\cortex-m4\armcc\port_c.c + + + + + config + + + tos_config.h + 5 + ..\TOS-CONFIG\tos_config.h + + + + + ota_recovery + + + ota_recovery.c + 1 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery.c + + + ota_recovery_xip.c + 1 + ..\..\..\..\..\..\components\ota\recovery\ota_recovery_xip.c + + + ota_patch.c + 1 + ..\..\..\..\..\..\components\ota\recovery\ota_patch.c + + + ota_patch_xip.c + 1 + ..\..\..\..\..\..\components\ota\recovery\ota_patch_xip.c + + + + + ota_common + + + ota_flash.c + 1 + ..\..\..\..\..\..\components\ota\common\flash\ota_flash.c + + + crc8.c + 1 + ..\..\..\..\..\..\components\ota\common\crc\crc8.c + + + ota_image.c + 1 + ..\..\..\..\..\..\components\ota\common\image\ota_image.c + + + ota_env.c + 1 + ..\..\..\..\..\..\components\ota\common\env\ota_env.c + + + ota_partition.c + 1 + ..\..\..\..\..\..\components\ota\common\partition\ota_partition.c + + + ota_info.c + 1 + ..\..\..\..\..\..\components\ota\common\info\ota_info.c + + + + + lzma + + + 7zAlloc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zAlloc.c + + + 7zArcIn.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zArcIn.c + + + 7zBuf.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zBuf.c + + + 7zBuf2.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zBuf2.c + + + 7zCrc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zCrc.c + + + 7zCrcOpt.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zCrcOpt.c + + + 7zDec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zDec.c + + + 7zFile.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zFile.c + + + 7zStream.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\7zStream.c + + + Aes.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Aes.c + + + AesOpt.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\AesOpt.c + + + Alloc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Alloc.c + + + Bcj2.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bcj2.c + + + Bcj2Enc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bcj2Enc.c + + + Bra.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bra.c + + + Bra86.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Bra86.c + + + BraIA64.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\BraIA64.c + + + CpuArch.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\CpuArch.c + + + Delta.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Delta.c + + + DllSecur.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\DllSecur.c + + + LzFind.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzFind.c + + + Lzma2Dec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma2Dec.c + + + Lzma2Enc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma2Enc.c + + + Lzma86Dec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma86Dec.c + + + Lzma86Enc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Lzma86Enc.c + + + LzmaDec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaDec.c + + + LzmaEnc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaEnc.c + + + LzmaLib.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\LzmaLib.c + + + Ppmd7.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7.c + + + Ppmd7Dec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7Dec.c + + + Ppmd7Enc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Ppmd7Enc.c + + + Sha256.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Sha256.c + + + Sort.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Sort.c + + + Xz.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\Xz.c + + + XzCrc64.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzCrc64.c + + + XzCrc64Opt.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzCrc64Opt.c + + + XzDec.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzDec.c + + + XzEnc.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzEnc.c + + + XzIn.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\3rdparty\XzIn.c + + + + + lzma_wrapper + + + lzma_uncompress.c + 1 + ..\..\..\..\..\..\components\ota\common\lzma\wrapper\lzma_uncompress.c + + + + + kv + + + tos_kv.c + 1 + ..\..\..\..\..\..\components\fs\kv\tos_kv.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/startup_stm32l431xx.s b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/startup_stm32l431xx.s new file mode 100644 index 00000000..aca97827 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/startup_stm32l431xx.s @@ -0,0 +1,404 @@ +;********************** COPYRIGHT(c) 2017 STMicroelectronics ****************** +;* File Name : startup_stm32l431xx.s +;* Author : MCD Application Team +;* Description : STM32L431xx Ultra Low Power devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;* +;******************************************************************************* +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x200 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU (0x2a00 + 0x2a00) + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection + DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line + DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_IRQHandler ; ADC1 + DCD CAN1_TX_IRQHandler ; CAN1 TX + DCD CAN1_RX0_IRQHandler ; CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; CAN1 SCE + DCD EXTI9_5_IRQHandler ; External Line[9:5]s + DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15 + DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; External Line[15:10] + DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD 0 ; Reserved + DCD SPI3_IRQHandler ; SPI3 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD COMP_IRQHandler ; COMP Interrupt + DCD LPTIM1_IRQHandler ; LP TIM1 interrupt + DCD LPTIM2_IRQHandler ; LP TIM2 interrupt + DCD 0 ; Reserved + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 + DCD LPUART1_IRQHandler ; LP UART1 interrupt + DCD QUADSPI_IRQHandler ; Quad SPI global interrupt + DCD I2C3_EV_IRQHandler ; I2C3 event + DCD I2C3_ER_IRQHandler ; I2C3 error + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD 0 ; Reserved + DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt + DCD TSC_IRQHandler ; Touch Sense Controller global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD RNG_IRQHandler ; RNG global interrupt + DCD FPU_IRQHandler ; FPU + DCD CRS_IRQHandler ; CRS interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_PVM_IRQHandler [WEAK] + EXPORT TAMP_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK] + EXPORT TIM1_UP_TIM16_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT TIM6_DAC_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT DMA2_Channel6_IRQHandler [WEAK] + EXPORT DMA2_Channel7_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT QUADSPI_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SWPMI1_IRQHandler [WEAK] + EXPORT TSC_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_PVM_IRQHandler +TAMP_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_TIM15_IRQHandler +TIM1_UP_TIM16_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +SDMMC1_IRQHandler +SPI3_IRQHandler +TIM6_DAC_IRQHandler +TIM7_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +COMP_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +DMA2_Channel6_IRQHandler +DMA2_Channel7_IRQHandler +LPUART1_IRQHandler +QUADSPI_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SAI1_IRQHandler +SWPMI1_IRQHandler +TSC_IRQHandler +RNG_IRQHandler +FPU_IRQHandler +CRS_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/main.c b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/main.c new file mode 100644 index 00000000..0e952e44 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/main.c @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +#include "stdio.h" +#include "stm32l4xx_hal.h" + +#include "ota_recovery.h" + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_USART2_UART_Init(void); + +UART_HandleTypeDef huart2; + +int fputc(int ch, FILE *f) +{ + while ((USART2->ISR & 0X40) == 0); + USART2->TDR = (uint8_t)ch; + return ch; +} + +extern ota_flash_drv_t stm32l4_norflash_onchip_drv_ota; +extern ota_flash_prop_t stm32l4_norflash_onchip_prop_ota; + +int main(void) +{ + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* Configure the system clock */ + SystemClock_Config(); + + MX_USART2_UART_Init(); + + uint32_t partition_addr = 0x08024800; + + if (ota_env_init(OTA_UPDATE_IN_POSITION, partition_addr, &stm32l4_norflash_onchip_drv_ota, &stm32l4_norflash_onchip_prop_ota) < 0) { + printf("env init failed!\n"); + return -1; + } + +#if 1 + if (ota_recovery_xip() != 0) { + printf("recovery failed!\n"); + } else { + printf("recovery successfully!\n"); + } +#else + if (ota_recovery() != 0) { + printf("recovery failed!\n"); + } else { + printf("recovery successfully!\n"); + } +#endif + + uint32_t jmp_addr, app_addr = ota_partition_start(OTA_PARTITION_ACTIVE_APP); + + /* test if user code is programmed starting from address app_addr */ + if (((*(uint32_t *)app_addr) & 0x2FFE0000) == 0x20000000) { + /* Jump to user application */ + jmp_addr = *(uint32_t *)(app_addr + 4); + + /* Initialize user application's Stack Pointer */ + __set_MSP(*(uint32_t *)app_addr); + ((void (*)(void))jmp_addr)(); + } +} + +void Error_Handler(void) +{ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 20; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2; + PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + /** Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief USART2 Initialization Function + * @param None + * @retval None + */ +static void MX_USART2_UART_Init(void) +{ + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; +#if 0 + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; +#else + huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; + huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; +#endif + if (HAL_UART_Init(&huart2) != HAL_OK) + { + Error_Handler(); + } +} + + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(char *file, uint32_t line) +{ +} + +#endif /* USE_FULL_ASSERT */ + diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_hal_msp.c b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_hal_msp.c new file mode 100644 index 00000000..30cc8fe0 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_hal_msp.c @@ -0,0 +1,155 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32l4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "stm32l4xx_hal.h" + +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief CRC MSP Initialization +* This function configures the hardware resources used in this example +* @param hcrc: CRC handle pointer +* @retval None +*/ +void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc) +{ + if(hcrc->Instance==CRC) + { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } + +} + +/** +* @brief CRC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hcrc: CRC handle pointer +* @retval None +*/ +void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc) +{ + if(hcrc->Instance==CRC) + { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } + +} + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + +} + +/** +* @brief UART MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_it.c b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_it.c new file mode 100644 index 00000000..39097b6c --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_it.c @@ -0,0 +1,202 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32l4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +__weak void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32L4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32l4xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/system_stm32l4xx.c b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/system_stm32l4xx.c new file mode 100644 index 00000000..26bd5179 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/system_stm32l4xx.c @@ -0,0 +1,337 @@ +/** + ****************************************************************************** + * @file system_stm32l4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the MSI (4 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | MSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 8 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * PLLSAI1_P | NA + *----------------------------------------------------------------------------- + * PLLSAI1_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI1_R | NA + *----------------------------------------------------------------------------- + * PLLSAI2_P | NA + *----------------------------------------------------------------------------- + * PLLSAI2_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI2_R | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l4xx_system + * @{ + */ + +/** @addtogroup STM32L4xx_System_Private_Includes + * @{ + */ + +#include "stm32l4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 4000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint32_t MSIRangeTable[12] = {100000U, 200000U, 400000U, 800000U, 1000000U, 2000000U, \ + 4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U}; +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U; + + /* Get MSI Range frequency--------------------------------------------------*/ + if((RCC->CR & RCC_CR_MSIRGSEL) == RESET) + { /* MSISRANGE from RCC_CSR applies */ + msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U; + } + else + { /* MSIRANGE from RCC_CR applies */ + msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; + + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ; + + switch (pllsource) + { + case 0x02: /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm); + break; + + case 0x03: /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm); + break; + + default: /* MSI used as PLL clock source */ + pllvco = (msirange / pllm); + break; + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U; + SystemCoreClock = pllvco/pllr; + break; + + default: + SystemCoreClock = msirange; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/event_driven/tos_config.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/event_driven/tos_config.h new file mode 100644 index 00000000..43493faf --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/event_driven/tos_config.h @@ -0,0 +1,19 @@ +#ifndef _TOS_CONFIG_H_ +#define _TOS_CONFIG_H_ + +#include "stm32l4xx.h" + +#define TOS_CFG_EVENT_DRIVEN_EN 1u + +#define TOS_CFG_MMHEAP_EN 1u + +#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x8000 + +#define TOS_CFG_PWR_MGR_EN 0u + +#define TOS_CFG_CPU_TICK_PER_SECOND 1000u + +#define TOS_CFG_CPU_CLOCK (SystemCoreClock) + +#endif + diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/mqtt_config.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/mqtt_config.h new file mode 100644 index 00000000..c2caeb53 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/mqtt_config.h @@ -0,0 +1,48 @@ +/* + * @Author: jiejie + * @Github: https://github.com/jiejieTop + * @Date: 2019-12-15 00:42:16 + * @LastEditTime: 2020-02-25 09:25:35 + * @Description: the code belongs to jiejie, please keep the author information and source code according to the license. + */ +#ifndef _MQTT_CONFIG_H_ +#define _MQTT_CONFIG_H_ + +//#define LOG_IS_SALOF + +#define LOG_LEVEL DEBUG_LEVEL //WARN_LEVEL DEBUG_LEVEL + +#ifdef LOG_IS_SALOF + #define USE_LOG (1U) + #define USE_SALOF (1U) + #define SALOF_OS USE_TENCENTOS + #define USE_IDLE_HOOK (0U) + #define LOG_COLOR (0U) + #define LOG_TS (0U) + #define LOG_TAR (0U) + #define SALOF_BUFF_SIZE (512U) + #define SALOF_FIFO_SIZE (1024U) + #define SALOF_TASK_STACK_SIZE (1024U) + #define SALOF_TASK_TICK (50U) +#endif + + +#define MQTT_MAX_PACKET_ID (0xFFFF - 1) +#define MQTT_TOPIC_LEN_MAX 64 +#define MQTT_ACK_HANDLER_NUM_MAX 64 +#define MQTT_DEFAULT_BUF_SIZE 1024 +#define MQTT_DEFAULT_CMD_TIMEOUT 4000 +#define MQTT_MAX_CMD_TIMEOUT 20000 +#define MQTT_MIN_CMD_TIMEOUT 1000 +#define MQTT_KEEP_ALIVE_INTERVAL 100 // unit: second +#define MQTT_VERSION 4 // 4 is mqtt 3.1.1 +#define MQTT_RECONNECT_DEFAULT_DURATION 1000 +#define MQTT_THREAD_STACK_SIZE 2048 +#define MQTT_THREAD_PRIO 5 +#define MQTT_THREAD_TICK 50 + +#define MQTT_NETSOCKET_USE_AT + +//#define MQTT_NETWORK_TYPE_TLS + +#endif /* _MQTT_CONFIG_H_ */ diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tickless/tos_config.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tickless/tos_config.h new file mode 100644 index 00000000..e02e32a2 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tickless/tos_config.h @@ -0,0 +1,41 @@ +#ifndef _TOS_CONFIG_H_ +#define _TOS_CONFIG_H_ + +#include "stm32l4xx.h" + +#define TOS_CFG_TASK_PRIO_MAX 10u + +#define TOS_CFG_ROUND_ROBIN_EN 1u + +#define TOS_CFG_OBJECT_VERIFY_EN 1u + +#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u + +#define TOS_CFG_EVENT_EN 1u + +#define TOS_CFG_MMBLK_EN 1u + +#define TOS_CFG_MMHEAP_EN 1u + +#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x6000 + +#define TOS_CFG_MUTEX_EN 1u + +#define TOS_CFG_TIMER_EN 1u + +#define TOS_CFG_PWR_MGR_EN 1u + +#define TOS_CFG_TICKLESS_EN 1u + +#define TOS_CFG_SEM_EN 1u + +#define TOS_CFG_IDLE_TASK_STK_SIZE 512u + +#define TOS_CFG_CPU_TICK_PER_SECOND 1000u + +#define TOS_CFG_CPU_CLOCK (SystemCoreClock) + +#define TOS_CFG_TIMER_AS_PROC 1u + +#endif + diff --git a/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tos_config.h b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tos_config.h new file mode 100644 index 00000000..62c6b3a7 --- /dev/null +++ b/board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tos_config.h @@ -0,0 +1,55 @@ +#ifndef _TOS_CONFIG_H_ +#define _TOS_CONFIG_H_ + +#include "stm32l4xx.h" + +#define TOS_CFG_TASK_PRIO_MAX 10u + +#define TOS_CFG_ROUND_ROBIN_EN 0u + +#define TOS_CFG_OBJECT_VERIFY_EN 1u + +#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u + +#define TOS_CFG_EVENT_EN 1u + +#define TOS_CFG_MMBLK_EN 1u + +#define TOS_CFG_MMHEAP_EN 0u + +#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN 1u + +#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x8000 + +#define TOS_CFG_MUTEX_EN 1u + +#define TOS_CFG_MESSAGE_QUEUE_EN 1u + +#define TOS_CFG_MAIL_QUEUE_EN 1u + +#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 0u + +#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 0u + +#define TOS_CFG_TIMER_EN 1u + +#define TOS_CFG_PWR_MGR_EN 0u + +#define TOS_CFG_TICKLESS_EN 0u + +#define TOS_CFG_SEM_EN 1u + +#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 1u + +#define TOS_CFG_FAULT_BACKTRACE_EN 0u + +#define TOS_CFG_IDLE_TASK_STK_SIZE 128u + +#define TOS_CFG_CPU_TICK_PER_SECOND 1000u + +#define TOS_CFG_CPU_CLOCK (SystemCoreClock) + +#define TOS_CFG_TIMER_AS_PROC 1u + +#endif + diff --git a/components/ota/common/crc/crc8.c b/components/ota/common/crc/crc8.c new file mode 100644 index 00000000..d2cfb00a --- /dev/null +++ b/components/ota/common/crc/crc8.c @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "crc8.h" + +uint8_t crc8(uint8_t crc, uint8_t *buf, int nbyte) +{ + int i; + +#define POLY 0x31 +#define WIDTH 8 +#define TOP_BIT 0x80 + + while (nbyte--) { + crc ^= *buf++; + for (i = 0; i < WIDTH; ++i) { + if (crc & TOP_BIT) { + crc = (crc << 1) ^ POLY; + } else { + crc <<= 1; + } + } + crc &= 0xFF; + } + + return crc; +} + diff --git a/components/ota/common/crc/crc8.h b/components/ota/common/crc/crc8.h new file mode 100644 index 00000000..2c1b1ec9 --- /dev/null +++ b/components/ota/common/crc/crc8.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _CRC8_H_ +#define _CRC8_H_ + +#include "stdint.h" + +uint8_t crc8(uint8_t crc, uint8_t *buf, int nbyte); + +#endif /* _CRC8_H_ */ + diff --git a/components/ota/common/diff/bsdiff.c b/components/ota/common/diff/bsdiff.c new file mode 100644 index 00000000..10ffc192 --- /dev/null +++ b/components/ota/common/diff/bsdiff.c @@ -0,0 +1,496 @@ +/*- + * Copyright 2003-2005 Colin Percival + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +#include "bsdiff.h" + +#include "wstream.h" +#include "lzma_compress.h" + +#define ERROR(msg) \ + printf("ERROR: line number[%d], function[%s] msg[%s]\n", __LINE__, __FUNCTION__, msg); \ + rc = -1; \ + goto OUT; + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +#define FOLD_N(x, n) ((n) * x) + +static void split(int32_t *I, int32_t *V, int32_t start, int32_t len, int32_t h) +{ + int32_t i, j, k, x, tmp, jj, kk; + + if (len < 16) { + for (k = start; k < start + len; k += j) { + j = 1; x = V[I[k] + h]; + for (i = 1; k + i < start + len; i++) { + if (V[I[k + i] + h] < x) { + x = V[I[k + i] + h]; + j = 0; + } + if(V[I[k + i] + h] == x) { + tmp = I[k + j]; I[k + j] = I[k + i]; I[k + i] = tmp; + j++; + } + } + for (i = 0; i < j; i++) { + V[I[k + i]] = k + j - 1; + } + if (j == 1) { + I[k] = -1; + } + } + return; + } + + x = V[I[start + len / 2] + h]; + jj = 0; kk = 0; + for (i = start; i < start + len; i++) { + if (V[I[i] + h] < x) { + jj++; + } + if (V[I[i] + h] == x) { + kk++; + } + } + jj += start; kk += jj; + + i = start; j = 0; k = 0; + while (i < jj) { + if (V[I[i] + h] < x) { + i++; + } else if (V[I[i] + h] == x) { + tmp = I[i]; I[i] = I[jj + j]; I[jj + j] = tmp; + j++; + } else { + tmp = I[i]; I[i] = I[kk + k]; I[kk + k] = tmp; + k++; + } + } + + while (jj + j < kk) { + if (V[I[jj + j] + h] == x) { + j++; + } else { + tmp = I[jj + j]; I[jj + j] = I[kk + k]; I[kk + k] = tmp; + k++; + } + } + + if (jj > start) { + split(I, V, start, jj - start, h); + } + + for (i = 0; i < kk - jj; i++) { + V[I[jj + i]] = kk - 1; + } + if (jj == kk - 1) { + I[jj] = -1; + } + + if (start + len > kk) { + split(I, V, kk, start + len - kk, h); + } +} + +static void qsufsort(int32_t *I, int32_t *V, uint8_t *old, int32_t oldsize) +{ + int32_t buckets[256]; + int32_t i, h, len; + + for (i = 0; i < 256; i++) { + buckets[i] = 0; + } + for (i = 0; i < oldsize; i++) { + buckets[old[i]]++; + } + for (i = 1; i < 256; i++) { + buckets[i] += buckets[i - 1]; + } + for (i = 255; i > 0; i--) { + buckets[i] = buckets[i - 1]; + } + buckets[0] = 0; + + for (i = 0; i < oldsize; i++) { + I[++buckets[old[i]]] = i; + } + I[0] = oldsize; + for (i = 0; i < oldsize; i++) { + V[i] = buckets[old[i]]; + } + V[oldsize] = 0; + for (i = 1; i < 256; i++) { + if (buckets[i] == buckets[i - 1] + 1) { + I[buckets[i]] = -1; + } + } + I[0] = -1; + + for (h = 1; I[0] != -(oldsize + 1); h += h) { + len = 0; + for (i = 0; i < oldsize + 1; ) { + if (I[i] < 0) { + len -= I[i]; + i -= I[i]; + } else { + if (len) { + I[i - len] = -len; + } + len = V[I[i]] + 1 - i; + split(I, V, i, len, h); + i += len; + len = 0; + }; + }; + if (len) { + I[i - len] = -len; + } + }; + + for (i = 0; i < oldsize + 1; i++) { + I[V[i]] = i; + } +} + +static int32_t matchlen(uint8_t *old, int32_t oldsize, uint8_t *new, int32_t newsize) +{ + int32_t i; + + for (i = 0; (i < oldsize) && (i < newsize); i++) { + if (old[i] != new[i]) { + break; + } + } + + return i; +} + +static int32_t search(int32_t *I, uint8_t *old, int32_t oldsize, uint8_t *new, int32_t newsize, int32_t st, int32_t en, int32_t *pos) +{ + int32_t x,y; + + if (en - st < 2) { + x = matchlen(old + I[st], oldsize - I[st], new, newsize); + y = matchlen(old + I[en], oldsize - I[en], new, newsize); + + if (x > y) { + *pos = I[st]; + return x; + } else { + *pos = I[en]; + return y; + } + }; + + x = st + (en - st) / 2; + if (memcmp(old + I[x], new, MIN(oldsize - I[x], newsize)) < 0) { + return search(I, old, oldsize, new, newsize, x, en, pos); + } else { + return search(I, old, oldsize, new, newsize, st, x, pos); + } +} + +static void offtout(int32_t x, uint8_t *buf) +{ + int32_t y; + + if (x < 0) { + y = -x; + } else { + y = x; + } + + buf[0] = y % 256; y -= buf[0]; + y = y / 256; buf[1] = y % 256; y -= buf[1]; + y = y / 256; buf[2] = y % 256; y -= buf[2]; + y = y / 256; buf[3] = y % 256; + + if (x < 0) { + buf[3] |= 0x80; + } +} + +int bsdiff(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, uint8_t **patch, size_t *patchsize) +{ + int rc = 0; + int32_t i; + + int32_t *I = NULL, *V; + int32_t scan, pos = 0, len; + int32_t lastscan, lastpos, lastoffset; + int32_t oldscore, scsc; + int32_t s, Sf, lenf, Sb, lenb; + int32_t overlap, Ss, lens; + int32_t dblen, eblen; + uint8_t *db = NULL, *eb = NULL; + uint8_t buf[FOLD_N(sizeof(int32_t) / sizeof(uint8_t), 1)]; + uint8_t header[FOLD_N(sizeof(int32_t) / sizeof(uint8_t), 3)]; + + wstream_t wstream; + uint8_t *wstream_buf, *the_patch; + size_t wstream_buf_size, the_patchsize; + + wstream_buf_size = FOLD_N(newsize, 5); + + if ((wstream_buf = malloc(wstream_buf_size)) == NULL) { + ERROR("malloc failed"); + } + + wstream_create(&wstream, wstream_buf, wstream_buf_size); + + if (((I = malloc((oldsize + 1) * sizeof(int32_t))) == NULL) || + ((V = malloc((oldsize + 1) * sizeof(int32_t))) == NULL)) { + ERROR("malloc failed"); + } + + qsufsort(I, V, old, oldsize); + + free(V); + + if (((db = malloc(newsize + 1)) == NULL) || + ((eb = malloc(newsize + 1)) == NULL)) { + ERROR("malloc failed"); + } + dblen = 0; + eblen = 0; + + /* Header is + 8 8 length of ctrl block + 16 8 length of diff block + 24 8 length of new file */ + /* File is + 0 32 Header + 32 ?? ctrl block + ?? ?? diff block + ?? ?? extra block */ + offtout(0, header + FOLD_N(sizeof(int32_t), 0)); + offtout(0, header + FOLD_N(sizeof(int32_t), 1)); + offtout(newsize, header + FOLD_N(sizeof(int32_t), 2)); + + if (wstream_write_stream(&wstream, header, sizeof(header)) != 0) { + ERROR("wstream full"); + } + + /* Compute the differences, writing ctrl as we go */ + scan = 0; len = 0; + lastscan = 0; lastpos = 0; lastoffset = 0; + while (scan < newsize) { + oldscore = 0; + + for (scsc = scan += len; scan < newsize; scan++) { + len = search(I, old, oldsize, new + scan, newsize - scan, 0, oldsize, &pos); + + for (; scsc < scan + len; scsc++) { + if ((scsc + lastoffset < oldsize) && + (old[scsc + lastoffset] == new[scsc])) { + oldscore++; + } + } + + if (((len == oldscore) && (len != 0)) || + (len > oldscore + 8)) { + break; + } + + if ((scan + lastoffset < oldsize) && + (old[scan + lastoffset] == new[scan])) { + oldscore--; + } + } + + if ((len != oldscore) || (scan == newsize)) { + s = 0; Sf = 0; lenf = 0; + for (i = 0; (lastscan + i < scan) && (lastpos + i < oldsize); ) { + if (old[lastpos + i] == new[lastscan + i]) { + s++; + } + i++; + if (s * 2 - i > Sf * 2 - lenf) { + Sf = s; lenf = i; + } + } + + lenb = 0; + if (scan < newsize) { + s = 0; Sb = 0; + for (i = 1; (scan >= lastscan + i) && (pos >= i); i++) { + if (old[pos - i] == new[scan - i]) { + s++; + } + if (s * 2 - i > Sb * 2 - lenb) { + Sb = s; lenb = i; + } + } + } + + if (lastscan + lenf > scan - lenb) { + overlap = (lastscan + lenf) - (scan - lenb); + s = 0; Ss = 0; lens = 0; + for (i = 0; i < overlap; i++) { + if (new[lastscan + lenf - overlap + i] == old[lastpos + lenf - overlap + i]) { + s++; + } + if (new[scan - lenb + i] == old[pos - lenb + i]) { + s--; + } + if (s > Ss) { + Ss = s; lens = i + 1; + } + } + + lenf += lens - overlap; + lenb -= lens; + } + + for (i = 0; i < lenf; i++) { + db[dblen + i] = new[lastscan + i] - old[lastpos + i]; + } + for (i = 0; i < (scan - lenb) - (lastscan + lenf); i++) { + eb[eblen + i] = new[lastscan + lenf + i]; + } + + dblen += lenf; + eblen += (scan - lenb) - (lastscan + lenf); + + offtout(lenf, buf); + if (wstream_write_stream(&wstream, buf, sizeof(buf)) != 0) { + ERROR("wstream full"); + } + + offtout((scan - lenb) - (lastscan + lenf), buf); + if (wstream_write_stream(&wstream, buf, sizeof(buf)) != 0) { + ERROR("wstream full"); + } + + offtout((pos - lenb) - (lastpos + lenf), buf); + if (wstream_write_stream(&wstream, buf, sizeof(buf)) != 0) { + ERROR("wstream full"); + } + + lastscan = scan - lenb; + lastpos = pos - lenb; + lastoffset = pos - scan; + }; + }; + + /* Compute size of ctrl data */ + /* ATTENTION: we DONNOT do data compress here */ + len = wstream_length_get(&wstream); + if (len == -1) { + ERROR("wstream invalid"); + } + + /* write size of ctrl data */ + offtout(len - sizeof(header), header + FOLD_N(sizeof(int32_t), 0)); + + /* Write diff data */ + /* ATTENTION: we DONNOT do data compress here */ + if (wstream_write_stream(&wstream, db, dblen) != 0) { + ERROR("wstream full"); + } + + /* Compute size of diff data */ + /* ATTENTION: we DONNOT do data compress here */ + newsize = wstream_length_get(&wstream); + if (newsize == -1) { + ERROR("wstream invalid"); + } + + /* write size of diff data */ + offtout(newsize - len, header + FOLD_N(sizeof(int32_t), 1)); + + /* Write extra data */ + /* ATTENTION: we DONNOT do data compress here */ + if (wstream_write_stream(&wstream, eb, eblen) != 0) { + ERROR("wstream full"); + } + + /* write header */ + if (wstream_write_stream_at(&wstream, 0, header, sizeof(header)) != 0) { + ERROR("wsream full"); + } + + the_patchsize = wstream_length_get(&wstream); + if (the_patchsize == -1) { + ERROR("wstream invalid!\n"); + } + + if ((the_patch = malloc(the_patchsize)) == NULL) { + ERROR("malloc failed"); + } + + memcpy(the_patch, wstream_buf_get(&wstream), the_patchsize); + *patch = the_patch; + *patchsize = the_patchsize; + +OUT: + /* Free the memory we used */ + if (db) { + free(db); + } + if (eb) { + free(eb); + } + if (I) { + free(I); + } + + if (wstream_buf) { + free(wstream_buf); + wstream_destroy(&wstream); + } + + if (rc) { + *patch = NULL; + *patchsize = 0; + } + + return rc; +} + diff --git a/components/ota/common/diff/bsdiff.h b/components/ota/common/diff/bsdiff.h new file mode 100644 index 00000000..24dd9977 --- /dev/null +++ b/components/ota/common/diff/bsdiff.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _BSDIFF_H_ +#define _BSDIFF_H_ + +#include "stdint.h" + +int bsdiff(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, uint8_t **patch, size_t *patchsize); + +#endif /* _BSDIFF_H_ */ + diff --git a/components/ota/common/diff/graph.c b/components/ota/common/diff/graph.c new file mode 100644 index 00000000..89a1b326 --- /dev/null +++ b/components/ota/common/diff/graph.c @@ -0,0 +1,561 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "assert.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "graph.h" + +int graph_create(graph_t *graph, int vertexs_n) +{ + int i = 0; + vertex_t *vertexs; + + if (!graph || vertexs_n <= 0) { + return -1; + } + + memset(graph, 0, sizeof(graph_t)); + + if ((vertexs = malloc(vertexs_n * sizeof(vertex_t))) == NULL) { + return -1; + } + + memset(vertexs, 0, vertexs_n * sizeof(vertex_t)); + + for (i = 0; i < vertexs_n; ++i) { + list_init(&vertexs[i].first_in); + list_init(&vertexs[i].first_out); + } + + graph->edges_n = 0; + graph->vertexs_n = vertexs_n; + graph->vertexs = vertexs; + + return 0; +} + +int graph_destroy(graph_t *graph) +{ + int i = 0; + vertex_t *vertex; + edge_t *edge, *tmp; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + for (i = 0; i < graph->vertexs_n; ++i) { + vertex = &graph->vertexs[i]; + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, tail_list, &vertex->first_out) { + list_del(&edge->tail_list); + free(edge); + } + } + + free(graph->vertexs); + + graph->edges_n = 0; + graph->vertexs_n = 0; + graph->vertexs = NULL; + + return 0; +} + +int graph_edge_add(graph_t *graph, int tail_vertex, int head_vertex) +{ + edge_t *edge; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (tail_vertex >= graph->vertexs_n || + head_vertex >= graph->vertexs_n || + tail_vertex < 0 || + head_vertex < 0) { + return -1; + } + + if ((edge = malloc(sizeof(edge_t))) == NULL) { + return -1; + } + + edge->head_vertex = head_vertex; + edge->tail_vertex = tail_vertex; + list_init(&edge->head_list); + list_init(&edge->tail_list); + + tail_v = &graph->vertexs[tail_vertex]; + head_v = &graph->vertexs[head_vertex]; + + list_add(&edge->tail_list, &tail_v->first_out); + ++tail_v->out_degree; + + list_add(&edge->head_list, &head_v->first_in); + ++head_v->in_degree; + + ++graph->edges_n; + + return 0; +} + +int graph_edge_rmv(graph_t *graph, int tail_vertex, int head_vertex) +{ + edge_t *edge, *tmp; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (tail_vertex >= graph->vertexs_n || + head_vertex >= graph->vertexs_n || + tail_vertex < 0 || + head_vertex < 0) { + return -1; + } + + tail_v = &graph->vertexs[tail_vertex]; + head_v = &graph->vertexs[head_vertex]; + + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, tail_list, &tail_v->first_out) { + if (edge->tail_vertex == tail_vertex && + edge->head_vertex == head_vertex) { + list_del(&edge->tail_list); + --tail_v->out_degree; + + list_del(&edge->head_list); + --head_v->in_degree; + + free(edge); + --graph->edges_n; + + return 0; + } + } + + return -1; +} + +int graph_edge_rmv_by_tail(graph_t *graph, int tail_vertex, graph_edge_delete_cb del_cb, void *cb_arg) +{ + edge_t *edge, *tmp; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (tail_vertex >= graph->vertexs_n || tail_vertex < 0) { + return -1; + } + + tail_v = &graph->vertexs[tail_vertex]; + + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, tail_list, &tail_v->first_out) { + if (edge->tail_vertex == tail_vertex) { + list_del(&edge->tail_list); + --tail_v->out_degree; + + list_del(&edge->head_list); + head_v = &graph->vertexs[edge->head_vertex]; + --head_v->in_degree; + + if (del_cb) { + del_cb(edge->tail_vertex, edge->head_vertex, cb_arg); + } + + free(edge); + --graph->edges_n; + } + } + + return 0; +} + +int graph_edge_rmv_one_by_tail(graph_t *graph, int tail_vertex) +{ + edge_t *edge, *tmp; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (tail_vertex >= graph->vertexs_n || tail_vertex < 0) { + return -1; + } + + tail_v = &graph->vertexs[tail_vertex]; + + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, tail_list, &tail_v->first_out) { + if (edge->tail_vertex == tail_vertex) { + list_del(&edge->tail_list); + --tail_v->out_degree; + + list_del(&edge->head_list); + head_v = &graph->vertexs[edge->head_vertex]; + --head_v->in_degree; + + free(edge); + --graph->edges_n; + + return 0; + } + } + + return -1; +} + +int graph_edge_rmv_by_head(graph_t *graph, int head_vertex, graph_edge_delete_cb del_cb, void *cb_arg) +{ + edge_t *edge, *tmp; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (head_vertex >= graph->vertexs_n || head_vertex < 0) { + return -1; + } + + head_v = &graph->vertexs[head_vertex]; + + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, head_list, &head_v->first_in) { + if (edge->head_vertex == head_vertex) { + list_del(&edge->tail_list); + tail_v = &graph->vertexs[edge->tail_vertex]; + --tail_v->out_degree; + + list_del(&edge->head_list); + --head_v->in_degree; + + if (del_cb) { + del_cb(edge->tail_vertex, edge->head_vertex, cb_arg); + } + + free(edge); + --graph->edges_n; + } + } + + return 0; +} + +int graph_edge_rmv_one_by_head(graph_t *graph, int head_vertex) +{ + edge_t *edge, *tmp; + vertex_t *tail_v, *head_v; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (head_vertex >= graph->vertexs_n || head_vertex < 0) { + return -1; + } + + head_v = &graph->vertexs[head_vertex]; + + LIST_FOR_EACH_ENTRY_SAFE(edge, tmp, edge_t, head_list, &head_v->first_in) { + if (edge->head_vertex == head_vertex) { + list_del(&edge->tail_list); + tail_v = &graph->vertexs[edge->tail_vertex]; + --tail_v->out_degree; + + list_del(&edge->head_list); + --head_v->in_degree; + + free(edge); + --graph->edges_n; + + return 0; + } + } + + return -1; +} + +int graph_edgesn_get(graph_t *graph) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + return graph->edges_n; +} + +int graph_vertex_max(graph_t *graph) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + return graph->vertexs_n; +} + +int graph_indegree_get(graph_t *graph, int vertex) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (vertex >= graph->vertexs_n || vertex < 0) { + return -1; + } + + return graph->vertexs[vertex].in_degree; +} + +int graph_outdegree_get(graph_t *graph, int vertex) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (vertex >= graph->vertexs_n || vertex < 0) { + return -1; + } + + return graph->vertexs[vertex].out_degree; +} + +int graph_tag_set(graph_t *graph, int vertex, v_tag_t tag) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (vertex >= graph->vertexs_n || vertex < 0) { + return -1; + } + + graph->vertexs[vertex].tag = tag; + return 0; +} + +int graph_tag_reset(graph_t *graph, int vertex) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + if (vertex >= graph->vertexs_n || vertex < 0) { + return -1; + } + + graph->vertexs[vertex].tag = 0; + return 0; +} + +v_tag_t graph_tag_get(graph_t *graph, int vertex) +{ + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return (v_tag_t)-1; + } + + if (vertex >= graph->vertexs_n || vertex < 0) { + return (v_tag_t)-1; + } + + return graph->vertexs[vertex].tag; +} + +int graph_dfs_create(dfs_t *dfs, graph_t *graph) +{ + if (!dfs || !graph) { + return -1; + } + + if (graph_vertex_max(graph) == 0) { + return -1; + } + + memset(dfs, 0, sizeof(dfs_t)); + + if (stack_create(&dfs->stack, graph_vertex_max(graph)) != 0) { + return 0; + } + + if (stack_push(&dfs->stack, 0) != 0) { + // push the first vertex of the graph into the stack + return -1; + } + + graph_vertex_set_visited(graph, 0); + + dfs->graph = graph; + + return 0; +} + +int graph_dfs_destroy(dfs_t *dfs) +{ + int i = 0; + + if (!dfs || !dfs->graph) { + return -1; + } + + for (i = 0; i < graph_vertex_max(dfs->graph); ++i) { + graph_tag_reset(dfs->graph, i); + } + + stack_destroy(&dfs->stack); + + dfs->graph = NULL; + + return 0; +} + +int graph_dfs_has_next(dfs_t *dfs) +{ + if (!dfs || !dfs->graph) { + return 0; + } + + return !stack_is_empty(&dfs->stack); +} + +int graph_dfs_ring_detect(dfs_t *dfs, int *ring_size) +{ + int i = 0; + edge_t *edge; + graph_t *graph; + vertex_t *vertex; + int vertex_idx, the_ring_size = 0, is_found = 0; + + assert(sizeof(int) == sizeof(element_type_t)); + + if (!dfs || !dfs->graph || !ring_size) { + return -1; + } + + graph = dfs->graph; + + while (!stack_is_empty(&dfs->stack)) { + vertex_idx = stack_top(&dfs->stack); + vertex = &graph->vertexs[vertex_idx]; + + is_found = 0; + + LIST_FOR_EACH_ENTRY(edge, edge_t, tail_list, &vertex->first_out) { + if (!graph_vertex_is_visited(graph, edge->head_vertex)) { + // still fresh neighbors here + stack_push(&dfs->stack, edge->head_vertex); + graph_vertex_set_visited(graph, edge->head_vertex); + is_found = 1; + break; + } + + if (graph_vertex_is_tnode(graph, edge->head_vertex) || + graph_vertex_is_rnode(graph, edge->head_vertex)) { + // already detected as a ring or a terminal node + continue; + } + + // set DFS_RING_NODE tag + graph_vertex_set_rnode(graph, edge->head_vertex); + + // if reach here, a ring is detected + stack_peek_init(&dfs->stack); + while ((vertex_idx = stack_peek(&dfs->stack)) != -1) { + ++the_ring_size; + if (vertex_idx == edge->head_vertex) { + *ring_size = the_ring_size; + return 0; + } + } + } + + // no fresh neighbors anymore + if (!is_found) { + stack_pop(&dfs->stack); + graph_vertex_set_tnode(graph, vertex_idx); + } + } + + /* if here, graph may still has isolated nodes there: multi-connected-component in the graph */ + for (i = 0; i < graph_vertex_max(graph); ++i) { + if (!graph_vertex_is_visited(graph, i)) { + stack_push(&dfs->stack, i); + graph_vertex_set_visited(graph, i); + break; + } + } + + return -1; +} + +int graph_out_print(graph_t *graph) +{ + int i = 0; + edge_t *edge; + vertex_t *vertex; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + for (i = 0; i < graph->vertexs_n; ++i) { + vertex = &graph->vertexs[i]; + + if (vertex->out_degree == 0) { + continue; + } + + printf("\nvertex: %d\n", i); + + LIST_FOR_EACH_ENTRY(edge, edge_t, tail_list, &vertex->first_out) { + printf(" - %d -> %d\n", edge->tail_vertex, edge->head_vertex); + } + } + + return 0; +} + +int graph_in_print(graph_t *graph) +{ + int i = 0; + edge_t *edge; + vertex_t *vertex; + + if (!graph || !graph->vertexs || !graph->vertexs_n) { + return -1; + } + + for (i = 0; i < graph->vertexs_n; ++i) { + vertex = &graph->vertexs[i]; + + if (vertex->in_degree == 0) { + continue; + } + + printf("\nvertex: %d\n", i); + + LIST_FOR_EACH_ENTRY(edge, edge_t, head_list, &vertex->first_in) { + printf(" - %d -> %d\n", edge->tail_vertex, edge->head_vertex); + } + } + + return 0; +} + diff --git a/components/ota/common/diff/graph.h b/components/ota/common/diff/graph.h new file mode 100644 index 00000000..2e2483f2 --- /dev/null +++ b/components/ota/common/diff/graph.h @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _GRAPH_H_ +#define _GRAPH_H_ + +#include "list.h" +#include "stack.h" + +// visited +#define DFS_VISITED (1 << 0) + +// ring node +#define DFS_R_NODE (1 << 1) + +// terminal node +#define DFS_T_NODE (1 << 2) + +#define IS_VISITED(tag) ((tag) & DFS_VISITED) + +#define IS_T_NODE(tag) ((tag) & DFS_R_NODE) + +#define IS_R_NODE(tag) ((tag) & DFS_T_NODE) + +#define SET_VISITED(tag) ((tag) | DFS_VISITED) + +#define SET_R_NODE(tag) ((tag) | DFS_R_NODE) + +#define SET_T_NODE(tag) ((tag) | DFS_T_NODE) + +typedef uint8_t vertex_tag_t; +typedef vertex_tag_t v_tag_t; + +/* + head + ^ + | + | + | + tail + */ +typedef struct edge_st { + int tail_vertex; + int head_vertex; + + list_t tail_list; /* all the egdes with the same tail with us */ + list_t head_list; /* with same head */ +} edge_t; + +typedef struct vertex_st { + list_t first_in; + list_t first_out; + + int in_degree; + int out_degree; + + v_tag_t tag; +} vertex_t; + +typedef struct graph_st { + vertex_t *vertexs; + + int vertexs_n; + int edges_n; +} graph_t; + +typedef struct depth_first_search_st { + stack_t stack; + graph_t *graph; +} dfs_t; + +typedef void (*graph_edge_delete_cb)(int tail_vertex, int head_vertex, void *cb_arg); + +int graph_create(graph_t *graph, int vertexs_n); + +int graph_destroy(graph_t *graph); + +int graph_edge_add(graph_t *graph, int tail_vertex, int head_vertex); + +int graph_edge_rmv(graph_t *graph, int tail_vertex, int head_vertex); + +int graph_edge_rmv_by_tail(graph_t *graph, int tail_vertex, graph_edge_delete_cb del_cb, void *cb_arg); + +int graph_edge_rmv_one_by_tail(graph_t *graph, int tail_vertex); + +int graph_edge_rmv_by_head(graph_t *graph, int head_vertex, graph_edge_delete_cb del_cb, void *cb_arg); + +int graph_edge_rmv_one_by_head(graph_t *graph, int head_vertex); + +int graph_edgesn_get(graph_t *graph); + +int graph_vertex_max(graph_t *graph); + +int graph_indegree_get(graph_t *graph, int vertex); + +int graph_outdegree_get(graph_t *graph, int vertex); + +int graph_tag_set(graph_t *graph, int vertex, v_tag_t tag); + +int graph_tag_reset(graph_t *graph, int vertex); + +v_tag_t graph_tag_get(graph_t *graph, int vertex); + +int graph_dfs_create(dfs_t *dfs, graph_t *graph); + +int graph_dfs_destroy(dfs_t *dfs); + +int graph_dfs_has_next(dfs_t *dfs); + +int graph_dfs_ring_detect(dfs_t *dfs, int *ring_size); + +int graph_out_print(graph_t *graph); + +int graph_in_print(graph_t *graph); + +static inline void graph_vertex_set_visited(graph_t *graph, int vertex) +{ + graph_tag_set(graph, vertex, SET_VISITED(graph_tag_get(graph, vertex))); +} + +static inline void graph_vertex_set_rnode(graph_t *graph, int vertex) +{ + graph_tag_set(graph, vertex, SET_R_NODE(graph_tag_get(graph, vertex))); +} + +static inline void graph_vertex_set_tnode(graph_t *graph, int vertex) +{ + graph_tag_set(graph, vertex, SET_T_NODE(graph_tag_get(graph, vertex))); +} + +static inline int graph_vertex_is_visited(graph_t *graph, int vertex) +{ + return IS_VISITED(graph_tag_get(graph, vertex)); +} + +static inline int graph_vertex_is_rnode(graph_t *graph, int vertex) +{ + return IS_R_NODE(graph_tag_get(graph, vertex)); +} + +static inline int graph_vertex_is_tnode(graph_t *graph, int vertex) +{ + return IS_T_NODE(graph_tag_get(graph, vertex)); +} + +#endif + diff --git a/components/ota/common/diff/list.h b/components/ota/common/diff/list.h new file mode 100644 index 00000000..c4edab60 --- /dev/null +++ b/components/ota/common/diff/list.h @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _LIST_H_ +#define _LIST_H_ + +#include "stdint.h" + +typedef struct list_node_st { + struct list_node_st *next; + struct list_node_st *prev; +} list_t; + +#define OFFSET_OF_FIELD(type, field) \ + ((uint32_t)&(((type *)0)->field)) + +#define CONTAINER_OF_FIELD(ptr, type, field) \ + ((type *)((uint8_t *)(ptr) - OFFSET_OF_FIELD(type, field))) + +#define LIST_NODE(node) \ + { &(node), &(node) } + +#define LIST_DEFINE(list) \ + dlist_t list = { &(list), &(list) } + +#define LIST_ENTRY(node, type, field) \ + CONTAINER_OF_FIELD(node, type, field) + +#define LIST_FIRST_ENTRY(list, type, field) \ + LIST_ENTRY((list)->next, type, field) + +#define LIST_FIRST_ENTRY_OR_NULL(list, type, field) \ + (list_empty(list) ? K_NULL : LIST_FIRST_ENTRY(list, type, field)) + +#define LIST_FOR_EACH(curr, list) \ + for (curr = (list)->next; curr != (list); curr = curr->next) + +#define LIST_FOR_EACH_PREV(curr, list) \ + for (curr = (list)->prev; curr != (list); curr = curr->prev) + +#define LIST_FOR_EACH_SAFE(curr, next, list) \ + for (curr = (list)->next, next = curr->next; curr != (list); \ + curr = next, next = curr->next) + +#define LIST_FOR_EACH_PREV_SAFE(curr, next, list) \ + for (curr = (list)->prev, next = curr->prev; \ + curr != (list); \ + curr = next, next = curr->prev) + +#define LIST_FOR_EACH_ENTRY(entry, type, field, list) \ + for (entry = LIST_ENTRY((list)->next, type, field); \ + &entry->field != (list); \ + entry = LIST_ENTRY(entry->field.next, type, field)) + +#define LIST_FOR_EACH_ENTRY_REVERSE(entry, type, field, list) \ + for (entry = LIST_ENTRY((list)->prev, type, field); \ + &entry->field != (list); \ + entry = LIST_ENTRY(entry->field.prev, type, field)) + +#define LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, type, field, list) \ + for (entry = LIST_ENTRY((list)->next, type, field), \ + tmp = LIST_ENTRY(entry->field.next, type, field); \ + &entry->field != (list); \ + entry = tmp, tmp = LIST_ENTRY(entry->field.next, type, field)) + +#define LIST_FOR_EACH_ENTRY_SAFE_REVERSE(entry, tmp, type, field, list) \ + for (entry = LIST_ENTRY((list)->prev, type, field), \ + tmp = LIST_ENTRY(entry->field.prev, type, field); \ + &entry->field != (list); \ + entry = tmp, tmp = LIST_ENTRY(entry->field.prev, type, field)) + +static inline void _list_add(list_t *node, list_t *prev, list_t *next) +{ + next->prev = node; + node->next = next; + node->prev = prev; + prev->next = node; +} + +static inline void _list_del(list_t *prev, list_t *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void _list_del_node(list_t *node) +{ + _list_del(node->prev, node->next); +} + +static inline void list_init(list_t *list) +{ + list->next = list; + list->prev = list; +} + +static inline void list_add(list_t *node, list_t *list) +{ + _list_add(node, list, list->next); +} + +static inline void list_add_tail(list_t *node, list_t *list) +{ + _list_add(node, list->prev, list); +} + +static inline void list_del(list_t *node) +{ + _list_del(node->prev, node->next); +} + +static inline void list_del_init(list_t *node) +{ + _list_del_node(node); + list_init(node); +} + +static inline void list_move(list_t *node, list_t *list) +{ + _list_del_node(node); + list_add(node, list); +} + +static inline void list_move_tail(list_t *node, list_t *list) +{ + _list_del_node(node); + list_add_tail(node, list); +} + +static inline int list_empty(const list_t *list) +{ + return list->next == list; +} + +#endif /* _LIST_H_ */ + diff --git a/components/ota/common/diff/ota_diff.c b/components/ota/common/diff/ota_diff.c new file mode 100644 index 00000000..9b8732a3 --- /dev/null +++ b/components/ota/common/diff/ota_diff.c @@ -0,0 +1,1364 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +#include "bsdiff.h" +#include "wstream.h" +#include "proc_bar.h" +#include "graph.h" +#include "stack.h" +#include "topo_sorting.h" +#include "segment_tree.h" +#include "lzma_compress.h" +#include "lzma_uncompress.h" + +#include "ota_diff.h" + +old_blk_info_t *old_blk_infos = NULL; +new_blk_info_t *new_blk_infos = NULL; + +summary_t summary = { + .ring_cnt = 0, + .ring_size_max = 0, + .ring_size_min = INT_MAX, + + .patch_size = 0, + + .block_len = 0, + .block_cnt = 0, + + .zipped_patch4block_size_max = 0, + .zipped_patch4block_size_min = INT_MAX, + + .patch4block_size_max = 0, + .patch4block_size_min = INT_MAX, + + .safe_block_cnt = 0, + .is_safe_block_ignored = 0, +}; + +static int32_t offtin(uint8_t *buf) +{ + int32_t y; + + y = buf[3] & 0x7F; + y = y * 256; y += buf[2]; + y = y * 256; y += buf[1]; + y = y * 256; y += buf[0]; + + if (buf[3] & 0x80) { + y = -y; + } + + return y; +} + +static uint16_t offtin_u16(uint8_t *buf) +{ + int32_t y; + + y = buf[1]; + y = y * 256; y += buf[0]; + + return y; +} + +static void offtout_u16(uint16_t y, uint8_t *buf) +{ + buf[0] = y % 256; y -= buf[0]; + y = y / 256; buf[1] = y % 256; +} + +static void relied_insert_by_new_idx_from(relied_detail_t *detail, list_t *list) +{ + relied_detail_t *iter; + + LIST_FOR_EACH_ENTRY(iter, relied_detail_t, list, list) { + if (iter->new_blk_idx > detail->new_blk_idx) { + break; + } + + if (iter->new_blk_idx == detail->new_blk_idx && + iter->new_from > detail->new_from) { + break; + } + } + list_add_tail(&detail->list, &iter->list); +} + +static int old_relied_add(int32_t old_blk_idx, int32_t new_blk_idx, int32_t new_from, int32_t old_from, int32_t diff_from, int32_t step) +{ + relied_detail_t *detail; + old_blk_info_t *old_blk_info; + + if ((detail = malloc(sizeof(relied_detail_t))) == NULL) { + printf("malloc failed"); + return -1; + } + + old_blk_info = &old_blk_infos[old_blk_idx]; + + list_init(&detail->list); + detail->new_blk_idx = new_blk_idx; + detail->new_from = new_from; + detail->old_from = old_from; + detail->diff_from = diff_from; + detail->step = step; + + relied_insert_by_new_idx_from(detail, &old_blk_info->relied_list); + ++old_blk_info->relied_cnt; + + return 0; +} + +static void cmd_insert_by_new_from(cmd_t *cmd, list_t *list) +{ + cmd_t *iter; + + LIST_FOR_EACH_ENTRY(iter, cmd_t, list, list) { + if (iter->new_from > cmd->new_from) { + break; + } + } + list_add_tail(&cmd->list, &iter->list); +} + +static int extra_cmd_add(int32_t new_blk_idx, int32_t new_from, int32_t extra_from, int32_t step) +{ + cmd_t *cmd; + new_blk_info_t *new_blk_info; + + if ((cmd = malloc(sizeof(cmd_t))) == NULL) { + printf("malloc failed"); + return -1; + } + + new_blk_info = &new_blk_infos[new_blk_idx]; + + cmd->type = CMD_TYPE_EXTRA; + cmd->new_from = new_from; + cmd->step = step; + + cmd->detail.extra_detail.extra_from = extra_from; + + list_init(&cmd->list); + cmd_insert_by_new_from(cmd, &new_blk_info->cmd_list); + + ++new_blk_info->cmd_cnt; + + return 0; +} + +static int diff_cmd_add(int32_t new_blk_idx, int32_t new_from, int32_t old_from, int32_t diff_from, int32_t step) +{ + cmd_t *cmd; + new_blk_info_t *new_blk_info; + + if ((cmd = malloc(sizeof(cmd_t))) == NULL) { + printf("malloc failed"); + return -1; + } + + new_blk_info = &new_blk_infos[new_blk_idx]; + + cmd->type = CMD_TYPE_DIFF; + cmd->new_from = new_from; + cmd->step = step; + + cmd->detail.diff_detail.diff_from = diff_from; + cmd->detail.diff_detail.old_from = old_from; + + list_init(&cmd->list); + cmd_insert_by_new_from(cmd, &new_blk_info->cmd_list); + + ++new_blk_info->cmd_cnt; + + return 0; +} + +static int blk_cmd_verify(size_t oldsize, size_t newsize, size_t blk_len) +{ + int rc = 0, i = 0; + cmd_t *cmd; + stree_t stree; + new_blk_info_t *new_blk_info; + int32_t new_blk_cnt = BLK_CNT(newsize, blk_len); + int32_t lower_bound; + size_t cmd_newsize = 0; + + if (segtree_create(&stree, 0, blk_len) != 0) { + ERROR("segment tree create failed!\n"); + } + + for (i = 0; i < new_blk_cnt; ++i) { + new_blk_info = &new_blk_infos[i]; + lower_bound = BLK_LOWER_BOUND(i, blk_len); + + LIST_FOR_EACH_ENTRY(cmd, cmd_t, list, &new_blk_info->cmd_list) { + if (segtree_query(&stree, cmd->new_from - lower_bound, cmd->new_from + cmd->step - lower_bound)) { + ERROR("corrupt blk cmd!\n"); + } + segtree_insert(&stree, cmd->new_from - lower_bound, cmd->new_from + cmd->step - lower_bound); + } + + if (i != new_blk_cnt - 1 && + segtree_cal(&stree) != blk_len) { + ERROR("incompleted cmd!\n"); + } + + if (i == new_blk_cnt - 1 && + segtree_cal(&stree) != BLK_EXTRA(newsize, blk_len)) { + ERROR("incompleted cmd!\n"); + } + cmd_newsize += segtree_cal(&stree); + + segtree_reset(&stree); + } + + if (cmd_newsize != newsize) { + ERROR("incompleted cmd for newsize!\n"); + } + +OUT: + segtree_destroy(&stree); + + return rc; +} + +static int old_blk_safe_refresh(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, size_t blk_len, uint8_t *diff_blk, uint8_t *extra_blk) +{ + int rc = 0, i = 0, j = 0; + int32_t old_blk_cnt = BLK_CNT(oldsize, blk_len); + int32_t new_blk_cnt = BLK_CNT(newsize, blk_len); + int32_t lower_bound; + + cmd_t *cmd; + old_blk_info_t *old_blk_info; + new_blk_info_t *new_blk_info; + uint8_t *buf = NULL; + size_t size2cmp; + + if ((buf = malloc(blk_len)) == NULL) { + ERROR("malloc failed!\n"); + } + + for (i = 0; i < MIN(old_blk_cnt, new_blk_cnt); ++i) { + old_blk_info = &old_blk_infos[i]; + new_blk_info = &new_blk_infos[i]; + + memset(buf, 0, blk_len); + + LIST_FOR_EACH_ENTRY(cmd, cmd_t, list, &new_blk_info->cmd_list) { + lower_bound = BLK_LOWER_BOUND(i, blk_len); + + if (cmd->type == CMD_TYPE_DIFF) { + for (j = 0; j < cmd->step; ++j) { + (buf + cmd->new_from - lower_bound)[j] = (old + cmd->detail.diff_detail.old_from)[j] + ((int8_t *)diff_blk + cmd->detail.diff_detail.diff_from)[j]; + } + } else if (cmd->type == CMD_TYPE_EXTRA) { + memcpy(buf + cmd->new_from - lower_bound, extra_blk + cmd->detail.extra_detail.extra_from, cmd->step); + } + } + + size2cmp = (i == new_blk_cnt - 1 ? BLK_EXTRA(newsize, blk_len) : blk_len); + + if (memcmp(buf, THE_BUF(new, i, blk_len), size2cmp) != 0) { + ERROR("wrong bspatch block cmd!\n"); + } + + if (memcmp(buf, THE_BUF(old, i, blk_len), size2cmp) == 0) { + /* this block is all the same after patch */ + old_blk_info->is_safe = 1; + } + } + +OUT: + FREE(buf); + + return rc; +} + +static int blk_info_build(int32_t X, int32_t Y, int32_t new_from, int32_t old_from, int32_t diff_from, int32_t extra_from, size_t blk_len) +{ + /* + "add x bytes + from oldfile to x bytes from the diff block; copy y bytes from the + extra block; seek forwards in oldfile by z bytes". + */ + int rc = 0; + + int32_t step; + + int32_t old_blk_idx = BLK_IDX(old_from, blk_len); + int32_t old_blk_upper_bound = BLK_UPPER_BOUND(old_from, blk_len); + int32_t old_blk_remaining = old_blk_upper_bound - old_from; + + int32_t new_blk_idx = BLK_IDX(new_from, blk_len); + int32_t new_blk_upper_bound = BLK_UPPER_BOUND(new_from, blk_len); + int32_t new_blk_remaining = new_blk_upper_bound - new_from; + + while (X) { + step = MIN_TRIPLE(new_blk_remaining, old_blk_remaining, X); + + new_blk_remaining -= step; + old_blk_remaining -= step; + X -= step; + + if (diff_cmd_add(new_blk_idx, new_from, old_from, diff_from, step) != 0) { + ERROR("diff cmd add failed"); + } + + if (old_relied_add(old_blk_idx, new_blk_idx, new_from, old_from, diff_from, step) != 0) { + ERROR("old relied add failed"); + } + + new_from += step; + old_from += step; + diff_from += step; + + if (new_blk_remaining == 0) { + new_blk_idx = BLK_IDX(new_from, blk_len); + new_blk_upper_bound = BLK_UPPER_BOUND(new_from, blk_len); + new_blk_remaining = new_blk_upper_bound - new_from; + } + + if (old_blk_remaining == 0) { + old_blk_idx = BLK_IDX(old_from, blk_len); + old_blk_upper_bound = BLK_UPPER_BOUND(old_from, blk_len); + old_blk_remaining = old_blk_upper_bound - old_from; + } + } + + while (Y) { + step = MIN(new_blk_remaining, Y); + + new_blk_remaining -= step; + Y -= step; + + if (extra_cmd_add(new_blk_idx, new_from, extra_from, step) != 0) { + ERROR("extra cmd add failed"); + } + + new_from += step; + extra_from += step; + + if (new_blk_remaining == 0) { + new_blk_idx = BLK_IDX(new_from, blk_len); + new_blk_upper_bound = BLK_UPPER_BOUND(new_from, blk_len); + new_blk_remaining = new_blk_upper_bound - new_from; + } + } + +OUT: + return rc; +} + +static int bspatch_parse(size_t oldsize, size_t newsize, size_t blk_len, uint8_t *patch, size_t patchsize, uint8_t **the_diff_blk, uint8_t **the_extra_blk) +{ + int rc = 0; + + int32_t X, Y, Z; + int32_t new_from = 0, old_from = 0; + + int32_t ctl_len, diff_len, new_len; + int32_t ctl_from = 0, diff_from = 0, extra_from = 0; + uint8_t *ctl_blk, *diff_blk, *extra_blk; + + ctl_len = offtin(patch); + patch += sizeof(int32_t); + diff_len = offtin(patch); + patch += sizeof(int32_t); + new_len = offtin(patch); + patch += sizeof(int32_t); + + if (new_len != newsize) { + ERROR("invalid bspatch"); + } + + ctl_blk = patch; + diff_blk = patch + ctl_len; + extra_blk = patch + ctl_len + diff_len; + + while (ctl_from < ctl_len) { + /* read the original X, Y, Z from ctl block */ + X = offtin(ctl_blk + ctl_from); + ctl_from += sizeof(int32_t); + + Y = offtin(ctl_blk + ctl_from); + ctl_from += sizeof(int32_t); + + Z = offtin(ctl_blk + ctl_from); + ctl_from += sizeof(int32_t); + + blk_info_build(X, Y, new_from, old_from, diff_from, extra_from, blk_len); + + new_from += X + Y; + old_from += X + Z; + diff_from += X; + extra_from += Y; + } + + *the_diff_blk = diff_blk; + *the_extra_blk = extra_blk; + +OUT: + return rc; +} + +static int blk_info_create(size_t oldsize, size_t newsize, size_t blk_len) +{ + int rc = 0, i = 0; + + int32_t old_blk_cnt = BLK_CNT(oldsize, blk_len); + int32_t new_blk_cnt = BLK_CNT(newsize, blk_len); + + if ((old_blk_infos = malloc(old_blk_cnt * sizeof(old_blk_info_t))) == NULL) { + ERROR("malloc failed"); + } + + if ((new_blk_infos = malloc(new_blk_cnt * sizeof(new_blk_info_t))) == NULL) { + ERROR("malloc failed"); + } + + memset(old_blk_infos, 0, old_blk_cnt * sizeof(old_blk_info_t)); + memset(new_blk_infos, 0, new_blk_cnt * sizeof(new_blk_info_t)); + + for (i = 0; i < old_blk_cnt; ++i) { + list_init(&old_blk_infos[i].relied_list); + list_init(&old_blk_infos[i].simplified_relied_list); + } + + for (i = 0; i < new_blk_cnt; ++i) { + list_init(&new_blk_infos[i].cmd_list); + } + + return 0; + +OUT: + if (old_blk_infos) { + free(old_blk_infos); + } + + if (new_blk_infos) { + free(new_blk_infos); + } + + return rc; +} + +static void blk_info_destroy(size_t oldsize, size_t newsize, size_t blk_len) +{ + int i = 0; + cmd_t *cmd, *c_tmp; + relied_detail_t *detail, *d_tmp; + smpl_relied_detail_t *smpl_detail, *sd_tmp; + + int32_t old_blk_cnt = BLK_CNT(oldsize, blk_len); + int32_t new_blk_cnt = BLK_CNT(newsize, blk_len); + + old_blk_info_t *old_blk_info; + new_blk_info_t *new_blk_info; + + if (old_blk_infos) { + for (i = 0; i < old_blk_cnt; ++i) { + old_blk_info = &old_blk_infos[i]; + + LIST_FOR_EACH_ENTRY_SAFE(detail, d_tmp, relied_detail_t, list, &old_blk_info->relied_list) { + list_del(&detail->list); + free(detail); + } + + LIST_FOR_EACH_ENTRY_SAFE(smpl_detail, sd_tmp, smpl_relied_detail_t, list, &old_blk_info->simplified_relied_list) { + list_del(&smpl_detail->list); + free(smpl_detail); + } + } + + free(old_blk_infos); + } + + if (new_blk_infos) { + for (i = 0; i < new_blk_cnt; ++i) { + new_blk_info = &new_blk_infos[i]; + + LIST_FOR_EACH_ENTRY_SAFE(cmd, c_tmp, cmd_t, list, &new_blk_info->cmd_list) { + list_del(&cmd->list); + free(cmd); + } + } + + free(new_blk_infos); + } + + old_blk_infos = NULL; + new_blk_infos = NULL; +} + +static void verbose_print(graph_t *graph, size_t oldsize, size_t newsize, size_t blk_len) +{ + int i = 0; + old_blk_info_t *old_blk_info; + int32_t old_blk_cnt = BLK_CNT(oldsize, blk_len); + + smpl_relied_detail_t *smpl_detail; + +#if 0 + int is_safe; + cmd_t *cmd; + new_blk_info_t *new_blk_info; + int32_t new_blk_cnt = BLK_CNT(newsize, blk_len); + relied_detail_t *detail; + + printf("====== patch cmd list ======\n"); + for (i = 0; i < new_blk_cnt; ++i) { + is_safe = 0; + + new_blk_info = &new_blk_infos[i]; + + if (i < old_blk_cnt) { + is_safe = old_blk_infos[i].is_safe; + } + printf("\nnew block idx: %-4d%s\n", i, is_safe ? "(SAFE)" : ""); + + LIST_FOR_EACH_ENTRY(cmd, cmd_t, list, &new_blk_info->cmd_list) { + printf(" - (%s)new_from: %-8d step: %-5d", cmd->type == CMD_TYPE_DIFF ? "DIFF " : "EXTRA", cmd->new_from, cmd->step); + if (cmd->type == CMD_TYPE_DIFF) { + printf(" old_from: %-8d(%-4d) diff_from: %-8d\n", + cmd->detail.diff_detail.old_from, + BLK_IDX(cmd->detail.diff_detail.old_from, blk_len), + cmd->detail.diff_detail.diff_from); + } else { + printf(" extra_from: %-8d\n", cmd->detail.extra_detail.extra_from); + } + } + } + + printf("\n\n====== relied relationship list ======\n"); + for (i = 0; i < old_blk_cnt; ++i) { + old_blk_info = &old_blk_infos[i]; + printf("\nold block idx: %-4d%s\n", i, old_blk_info->is_safe ? "(SAFE)" : ""); + + LIST_FOR_EACH_ENTRY(detail, relied_detail_t, list, &old_blk_info->relied_list) { + printf(" - new block idx: %-4d new_from: %-8d old_from: %-8d step: %-5d diff_from: %-8d\n", detail->new_blk_idx, detail->new_from, detail->old_from, detail->step, detail->diff_from); + } + } +#endif + + printf("\n\n====== simplified relied relationship list ======\n"); + for (i = 0; i < old_blk_cnt; ++i) { + old_blk_info = &old_blk_infos[i]; + if (old_blk_info->simplified_relied_cnt == 0) { + continue; + } + + printf("\nold block idx: %-4d%s\n", i, old_blk_info->is_safe ? "(SAFE)" : ""); + + LIST_FOR_EACH_ENTRY(smpl_detail, smpl_relied_detail_t, list, &old_blk_info->simplified_relied_list) { + printf(" - new block idx: %-4d\n", smpl_detail->new_blk_idx); + } + } + printf("\n==================================================\n\n"); + +#if 0 + printf("\n\n====== graph of relied relationship ======\n"); + graph_in_print(graph); +#endif +} + +static void summary_print(void) +{ + printf("\n============= summary =============\n"); + printf("RINGs in graph : %8d\n", summary.ring_cnt); + if (summary.ring_cnt != 0) { + printf("RING size MAX : %8d\n", summary.ring_size_max); + printf("RING size MIN : %8d\n", summary.ring_size_min); + } + + printf("\n"); + printf("PATCH size : %8d\n", summary.patch_size); + + printf("\n"); + printf("BLOCK size : %8d\n", summary.block_len); + printf("BLOCK count : %8d\n", summary.block_cnt); + + printf("\n"); + printf("ZIPPED patch4block MAX : %8d\n", summary.zipped_patch4block_size_max); + printf("ZIPPED patch4block MIN : %8d\n", summary.zipped_patch4block_size_min); + + printf("\n"); + printf("PATCH4BLOCK MAX : %8d\n", summary.patch4block_size_max); + printf("PATCH4BLOCK MIN : %8d\n", summary.patch4block_size_min); + + printf("\n"); + printf("SAFE block count : %8d%s\n", summary.safe_block_cnt, summary.is_safe_block_ignored ? "(IGNORED)" : ""); + printf("===================================\n"); +} + +static int relied_simplify(size_t oldsize, size_t blk_len, graph_t *graph) +{ + int i = 0; + int32_t last_new_blk_idx = -1; + relied_detail_t *detail, *d_tmp; + old_blk_info_t *old_blk_info; + smpl_relied_detail_t *smpl_detail; + int32_t old_blk_cnt = BLK_CNT(oldsize, blk_len); + + for (i = 0; i < old_blk_cnt; ++i) { + old_blk_info = &old_blk_infos[i]; + + last_new_blk_idx = -1; + LIST_FOR_EACH_ENTRY_SAFE(detail, d_tmp, relied_detail_t, list, &old_blk_info->relied_list) { + if (detail->new_blk_idx == last_new_blk_idx) { + continue; + } + + if (detail->new_blk_idx == i) { + last_new_blk_idx = detail->new_blk_idx; + continue; + } + + last_new_blk_idx = detail->new_blk_idx; + if ((smpl_detail = malloc(sizeof(smpl_relied_detail_t))) == NULL) { + return -1; + } + + smpl_detail->new_blk_idx = detail->new_blk_idx; + list_init(&smpl_detail->list); + + list_add(&smpl_detail->list, &old_blk_info->simplified_relied_list); + + ++old_blk_info->simplified_relied_cnt; + + /* we use a graph to record the dependency(relied) relationship */ + /* use topological sorting to find the order sequence to restore the new block */ + if (i < graph_vertex_max(graph)) { + /* point from tail(rely-ing) to head(relied) */ + /* detail->new_blk_idx(tail) relied on old block i(head)*/ + graph_edge_add(graph, detail->new_blk_idx, i); + } + } + } + + return 0; +} + +int analysing_dependency(graph_t *graph) +{ + dfs_t dfs; + int ring_size; + + if (graph_dfs_create(&dfs, graph) != 0) { + return -1; + } + + while (graph_dfs_has_next(&dfs)) { + if (graph_dfs_ring_detect(&dfs, &ring_size) == 0) { + // printf("$$$ %d\n", ring_size); + if (ring_size < summary.ring_size_min) { + summary.ring_size_min = ring_size; + } + if (ring_size > summary.ring_size_max) { + summary.ring_size_max = ring_size; + } + ++summary.ring_cnt; + } + } + + graph_dfs_destroy(&dfs); + + return 0; +} + +static int is_all_zeros(uint8_t *buf, size_t size) +{ + int i = 0; + + for (i = 0; i < size; ++i) { + if (buf[i] != 0) { + return 0; + } + } + + return 1; +} + +static int patch4block_assemble(int new_blk_idx, size_t blk_len, uint8_t *diff_blk, uint8_t *extra_blk, uint8_t *patch4blk, size_t patch4blk_size, size_t *the_patch4blk_size) +{ + int rc = 0, i = 0; + int32_t len, the_len; + size_t the_patchsize; + + cmd_t *cmd, *tmp; + wstream_t ws; + new_blk_info_t *new_blk_info = &new_blk_infos[new_blk_idx]; + + uint8_t *diff = NULL, *extra = NULL; + uint32_t diff_len = 0, extra_len = 0; + /* + format of patch for one block: + 0 2 I block index of the patch + 2 2 N count of cmd + 4 2 C sizeof(control block) + 6 2 D sizeof(diff block) + + 8 C control block + 8 + C D diff block + 8 + C + D ? extra block + */ + /* control block: + with a leading 8bit domain, indicating the cmd type, 0 for DIFF, 1 for EXTRA + + if current is a CMD_COPY(X, Y, Z) cmd: + X is 0(COPY) + locate old to Z, copy Y bytes from oldfile + + if current is a CMD_DIFF(X, Y, Z) cmd: + X is 1(DIFF) + locate old to Z, add Y bytes from oldfile to Y bytes from the diff block + + if current is a CMD_EXTRA(X, Y) cmd: + X is 2(EXTRA) + copy Y bytes from the extra block + */ + uint8_t X; + int is_diff_all_zeros = 0; + uint16_t I = (uint16_t)new_blk_idx, N = (uint16_t)new_blk_info->cmd_cnt, Y, Z; + uint8_t header[FOLD_N(sizeof(uint16_t) / sizeof(uint8_t), 4)]; + uint8_t buf[FOLD_N(sizeof(uint16_t) / sizeof(uint8_t), 1)]; + + if ((diff = malloc(blk_len)) == NULL) { + ERROR("malloc failed!\n"); + } + + if ((extra = malloc(blk_len)) == NULL) { + ERROR("malloc failed!\n"); + } + + wstream_create(&ws, patch4blk, patch4blk_size); + /* reserve space for C & D */ + if (wstream_write_stream(&ws, header, sizeof(header)) != 0) { + ERROR("wstream full!\n"); + } + + LIST_FOR_EACH_ENTRY_SAFE(cmd, tmp, cmd_t, list, &new_blk_info->cmd_list) { + if (cmd->type == CMD_TYPE_DIFF) { + Y = cmd->step; + Z = cmd->detail.diff_detail.old_from; + + is_diff_all_zeros = is_all_zeros(&diff_blk[cmd->detail.diff_detail.diff_from], Y); + X = is_diff_all_zeros ? CMD_COPY : CMD_DIFF; + + /* write control */ + if (wstream_write_byte(&ws, X) != 0) { + ERROR("wstream full!\n"); + } + offtout_u16(Y, buf); + if (wstream_write_stream(&ws, buf, sizeof(buf)) != 0) { + ERROR("wstream full!\n"); + } + offtout_u16(Z, buf); + if (wstream_write_stream(&ws, buf, sizeof(buf)) != 0) { + ERROR("wstream full!\n"); + } + + if (is_diff_all_zeros) { + continue; + } + + for (i = 0; i < Y; ++i) { + diff[diff_len++] = diff_blk[cmd->detail.diff_detail.diff_from + i]; + } + } else if (cmd->type == CMD_TYPE_EXTRA) { + X = CMD_EXTRA; + Y = cmd->step; + + /* write control */ + if (wstream_write_byte(&ws, X) != 0) { + ERROR("wstream full!\n"); + } + offtout_u16(Y, buf); + if (wstream_write_stream(&ws, buf, sizeof(buf)) != 0) { + ERROR("wstream full!\n"); + } + + for (i = 0; i < Y; ++i) { + extra[extra_len++] = extra_blk[cmd->detail.extra_detail.extra_from + i]; + } + } + + list_del(&cmd->list); + free(cmd); + } + + /* compute size of ctrl data */ + len = wstream_length_get(&ws); + if (len == -1) { + ERROR("wstream invalid!\n"); + } + + /* write block index */ + offtout_u16(I, header + FOLD_N(sizeof(uint16_t), 0)); + + /* write cmd count */ + offtout_u16(N, header + FOLD_N(sizeof(uint16_t), 1)); + + /* write size of ctrl data */ + offtout_u16(len - sizeof(header), header + FOLD_N(sizeof(uint16_t), 2)); + + /* write diff data */ + if (wstream_write_stream(&ws, diff, diff_len) != 0) { + ERROR("wstream full!\n"); + } + + /* compute size of diff data */ + the_len = wstream_length_get(&ws); + if (the_len == -1) { + ERROR("wstream invalid!\n"); + } + + /* write size of diff data */ + offtout_u16(the_len - len, header + FOLD_N(sizeof(uint16_t), 3)); + + /* write extra data */ + if (wstream_write_stream(&ws, extra, extra_len) != 0) { + ERROR("wstream full!\n"); + } + + /* write header */ + if (wstream_write_stream_at(&ws, 0, header, sizeof(header)) != 0) { + ERROR("wstream full!\n"); + } + + the_patchsize = wstream_length_get(&ws); + if (the_patchsize == -1) { + ERROR("wstream invalid!\n"); + } + + *the_patch4blk_size = the_patchsize; + +OUT: + FREE(diff); + FREE(extra); + + wstream_destroy(&ws); + + return rc; +} + +static int make_patch(graph_t *graph, size_t oldsize, size_t newsize, size_t blk_len, uint8_t *diff_blk, uint8_t *extra_blk, int is_safe_ignored, uint8_t **patch, size_t *patchsize) +{ + int rc = 0; + int new_blk_idx; + lzma_err_t err; + + wstream_t ws; + topo_sorting_t topo_sorting; + proc_bar_t proc_bar; + + uint8_t *final_patch = NULL, *patch4blk = NULL, *zipped_patch4blk = NULL; + size_t final_patch_size = FOLD_N(newsize, 3); + size_t patch4blk_size = FOLD_N(blk_len, 3); + size_t zippped_patch4blk_size = FOLD_N(blk_len, 3); + size_t the_patch4blk_size, the_zipped_patch4blk_size; + + uint8_t patch_hdr[FOLD_N(sizeof(uint16_t) / sizeof(uint8_t), 2)]; + uint8_t patch4blk_hdr[FOLD_N(sizeof(uint16_t) / sizeof(uint8_t), 2)]; + + uint16_t blk_cnt = 0; + + /* how many rings are there in the graph */ + uint16_t ring_cnt = 0; + + /* + format of patch: + patch_hdr + (patch4blk_hdr + patch4blk) * N + + patch_hdr: + 0 2 length of one block + 2 2 total count of blocks in the patch + + patch4blk_hdr: + 0 2 original length of the patch + 2 2 zipped length of the patch + */ + + if ((final_patch = malloc(final_patch_size * sizeof(uint8_t))) == NULL) { + ERROR("malloc failed!\n"); + } + + if ((patch4blk = malloc(patch4blk_size * sizeof(uint8_t))) == NULL) { + ERROR("malloc failed!\n"); + } + + if ((zipped_patch4blk = malloc(zippped_patch4blk_size * sizeof(uint8_t))) == NULL) { + ERROR("malloc failed!\n"); + } + + wstream_create(&ws, final_patch, final_patch_size); + /* reserve space for patch_hdr */ + if (wstream_write_stream(&ws, patch_hdr, sizeof(patch_hdr)) != 0) { + ERROR("wstream full!\n"); + } + + if (topo_sorting_create(&topo_sorting, graph) != 0) { + ERROR("malloc failed!\n"); + } + + proc_bar_init(&proc_bar, BLK_CNT(newsize, blk_len)); + +MAKE_PATCH: + while (topo_sorting_has_next(&topo_sorting)) { + new_blk_idx = topo_sorting_next(&topo_sorting); + + if (new_blk_idx < BLK_CNT(oldsize, blk_len) && + old_blk_infos[new_blk_idx].is_safe) { + /* this is a safe block, and we wanna ignore it */ + ++summary.safe_block_cnt; + + if (is_safe_ignored) { + summary.is_safe_block_ignored = 1; + proc_bar_update(&proc_bar); + continue; + } + } + + /* assemble the army! */ + if (patch4block_assemble(new_blk_idx, + blk_len, + diff_blk, + extra_blk, + patch4blk, + patch4blk_size, + &the_patch4blk_size) != 0) { + ERROR("patch4block_assemble failed!\n"); + } + + the_zipped_patch4blk_size = zippped_patch4blk_size; + err = lzma_compress(zipped_patch4blk, &the_zipped_patch4blk_size, patch4blk, the_patch4blk_size); + if (err != LZMA_ERR_OK) { + ERROR("lzma compress failed"); + } + + offtout_u16((uint16_t)the_patch4blk_size, patch4blk_hdr); + offtout_u16((uint16_t)the_zipped_patch4blk_size, patch4blk_hdr + sizeof(uint16_t)); + + if (wstream_write_stream(&ws, patch4blk_hdr, sizeof(patch4blk_hdr)) != 0) { + ERROR("wstream full!\n"); + } + + if (wstream_write_stream(&ws, zipped_patch4blk, the_zipped_patch4blk_size) != 0) { + ERROR("wstream full!\n"); + } + + proc_bar_update(&proc_bar); + + if (the_patch4blk_size > summary.patch4block_size_max) { + summary.patch4block_size_max = the_patch4blk_size; + } + if (the_patch4blk_size < summary.patch4block_size_min) { + summary.patch4block_size_min = the_patch4blk_size; + } + if (the_zipped_patch4blk_size > summary.zipped_patch4block_size_max) { + summary.zipped_patch4block_size_max = the_zipped_patch4blk_size; + } + if (the_zipped_patch4blk_size < summary.zipped_patch4block_size_min) { + summary.zipped_patch4block_size_min = the_zipped_patch4blk_size; + } + + ++blk_cnt; + } + + /* still edges left? there's at least one ring in the graph */ + if (topo_has_ring(&topo_sorting)) { + ++ring_cnt; + topo_ring_break(&topo_sorting); + goto MAKE_PATCH; + } + + offtout_u16((uint16_t)blk_len, patch_hdr); + offtout_u16((uint16_t)blk_cnt, patch_hdr + sizeof(uint16_t)); + if (wstream_write_stream_at(&ws, 0, patch_hdr, sizeof(patch_hdr)) != 0) { + ERROR("wstream full!\n"); + } + + *patchsize = wstream_length_get(&ws); + *patch = final_patch; + + summary.block_cnt = blk_cnt; + summary.block_len = blk_len; + + summary.patch_size = *patchsize; + +OUT: + FREE(patch4blk); + FREE(zipped_patch4blk); + + topo_sorting_destroy(&topo_sorting); + + return rc; +} + +static int backup_map_create(bkup_map_t *bkup_map, uint8_t *backup_buf, const size_t backup_n, uint16_t blk_len) +{ + uint16_t i = 0; + uint16_t *cache = NULL; + + memset(bkup_map, 0, sizeof(bkup_map_t)); + + if ((cache = malloc(backup_n * sizeof(uint16_t))) == NULL) { + return -1; + } + + for (i = 0; i < backup_n; ++i) { + cache[i] = (uint16_t)-1; + } + + bkup_map->buf = backup_buf; + bkup_map->blk_len = blk_len; + bkup_map->cache = cache; + bkup_map->backup_n = backup_n; + bkup_map->cursor = 0; + + return 0; +} + +static int backup_map_destroy(bkup_map_t *bkup_map) +{ + if (bkup_map->cache) { + free(bkup_map->cache); + } + return 0; +} + +static int backup_map_add(bkup_map_t *bkup_map, uint16_t blk_idx, uint8_t *backup_ed_addr) +{ + uint16_t slot = bkup_map->cursor; + uint16_t blk_len = bkup_map->blk_len; + uint8_t *backup_ee_addr = THE_BUF(bkup_map->buf, slot, bkup_map->blk_len); + + memcpy(backup_ee_addr, backup_ed_addr, blk_len); + + bkup_map->cache[slot] = blk_idx; + bkup_map->cursor = (slot + 1) % bkup_map->backup_n; + return 0; +} + +static uint8_t *backup_map_query(bkup_map_t *bkup_map, uint16_t blk_idx) +{ + uint16_t i = 0; + + for (i = 0; i < bkup_map->backup_n; ++i) { + if (bkup_map->cache[i] == blk_idx) { + return THE_BUF(bkup_map->buf, i, bkup_map->blk_len); + } + } + + return NULL; +} + +static int patch_test(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, size_t the_blk_len, uint8_t *patch, size_t patchsize) +{ + int rc = 0, i = 0; + uint8_t *the_new = NULL, *the_old = NULL; + + uint8_t *backup = NULL; + const uint16_t backup_n = 3; + bkup_map_t bkup_map; + uint8_t *backup_buf; + + uint8_t *patch4blk = NULL; + uint16_t blk_len, blk_cnt; + uint16_t unzipped_len, zipped_len; + size_t the_unzipped_len; + size_t the_zipped_len; + + /* + format of patch: + patch_hdr + (patch4blk_hdr + zipped(patch4blk)) * N + + patch_hdr: + 0 2 length of one block + 4 2 total count of blocks in the patch + + patch4blk_hdr: + 4 2 original length of the patch + 8 2 zipped length of the patch + */ + blk_len = offtin_u16(patch); + patch += sizeof(uint16_t); + blk_cnt = offtin_u16(patch); + patch += sizeof(uint16_t); + + if (blk_len != the_blk_len) { + ERROR("wrong patch!\n"); + } + + if ((the_new = malloc(ALIGN_UP(newsize, the_blk_len))) == NULL) { + ERROR("malloc failed\n"); + } + + if ((the_old = malloc(ALIGN_UP(oldsize, the_blk_len))) == NULL) { + ERROR("malloc failed\n"); + } + + memcpy(the_new, old, MIN(oldsize, newsize)); + memcpy(the_old, old, oldsize); + + if ((patch4blk = malloc(FOLD_N(blk_len, 3))) == NULL) { + ERROR("malloc failed\n"); + } + + /* simulation of ota partition for backup */ + if ((backup = malloc(FOLD_N(blk_len, backup_n))) == NULL) { + ERROR("malloc failed\n"); + } + + if (backup_map_create(&bkup_map, backup, backup_n, blk_len) != 0) { + ERROR("backup_map_create failed\n"); + } + + while (blk_cnt--) { + unzipped_len = offtin_u16(patch); + patch += sizeof(uint16_t); + zipped_len = offtin_u16(patch); + patch += sizeof(uint16_t); + + the_unzipped_len = unzipped_len; + the_zipped_len = zipped_len; + if (lzma_uncompress(patch4blk, &the_unzipped_len, patch, &the_zipped_len) != LZMA_ERR_OK) { + ERROR("uncompress failed"); + } + + patch += zipped_len; + + /* + format of patch for one block: + 0 2 I block index of the patch + 2 2 N count of cmd + 4 2 C sizeof(control block) + 6 2 D sizeof(diff block) + + 6 C control block + 6 + C D diff block + 6 + C + D ? extra block + */ + + /* control block: + with a leading 8bit domain, indicating the cmd type, 0 for DIFF, 1 for EXTRA + + if current is a CMD_COPY(X, Y, Z) cmd: + X is 0(COPY) + locate old to Z, copy Y bytes from oldfile + + if current is a CMD_DIFF(X, Y, Z) cmd: + X is 1(DIFF) + locate old to Z, add Y bytes from oldfile to Y bytes from the diff block + + if current is a CMD_EXTRA(X, Y) cmd: + X is 2(EXTRA) + copy Y bytes from the extra block + */ + uint8_t X; + uint16_t I, N, Y, Z, C, D; + uint8_t *ctrl_blk, *diff_blk, *extra_blk; + uint16_t cursor = 0, size2cmp = 0; + uint16_t old_idx, old_offset; + + I = offtin_u16(patch4blk + FOLD_N(sizeof(uint16_t), 0)); + N = offtin_u16(patch4blk + FOLD_N(sizeof(uint16_t), 1)); + C = offtin_u16(patch4blk + FOLD_N(sizeof(uint16_t), 2)); + D = offtin_u16(patch4blk + FOLD_N(sizeof(uint16_t), 3)); + + ctrl_blk = patch4blk + FOLD_N(sizeof(uint16_t), 4); + diff_blk = patch4blk + FOLD_N(sizeof(uint16_t), 4) + C; + extra_blk = patch4blk + FOLD_N(sizeof(uint16_t), 4) + C + D; + + memset(THE_BUF(the_new, I, blk_len), 0, blk_len); + + /* backup the old block I first */ + backup_map_add(&bkup_map, I, THE_BUF(the_old, I, blk_len)); + + while (N--) { + X = *(uint8_t *)ctrl_blk; + ctrl_blk += 1; + + if (X == CMD_COPY || X == CMD_DIFF) { // a COPY or DIFF cmd + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + Z = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + old_idx = BLK_IDX(Z, blk_len); + old_offset = Z - BLK_LOWER_BOUND(old_idx, blk_len); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR("wrong patch!"); + } + + backup_buf = backup_map_query(&bkup_map, old_idx); + if (!backup_buf) { + memcpy(THE_BUF(the_new, I, blk_len) + cursor, the_old + Z, Y); + } else { + memcpy(THE_BUF(the_new, I, blk_len) + cursor, backup_buf + old_offset, Y); + } + + if (X == CMD_DIFF) { + for (i = 0; i < Y; ++i) { + (THE_BUF(the_new, I, blk_len) + cursor)[i] += *(int8_t *)(diff_blk + i); + } + diff_blk += Y; + } + } else if (X == CMD_EXTRA){ // a EXTRA cmd + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR("wrong patch!"); + } + + memcpy(THE_BUF(the_new, I, blk_len) + cursor, extra_blk, Y); + extra_blk += Y; + } else { + ERROR("wrong patch!"); + } + + cursor += Y; + size2cmp += Y; + + /* sanity check */ + if (cursor > blk_len) { + ERROR("wrong patch!"); + } + } + + /* simulation of earse of the flash and write of the new firmware block */ + if (I < BLK_CNT(oldsize, blk_len)) { + memcpy(THE_BUF(the_old, I, blk_len), THE_BUF(the_new, I, blk_len), size2cmp); + } + + if (memcmp(THE_BUF(the_new, I, blk_len), THE_BUF(new, I, blk_len), size2cmp) != 0) { + ERROR("wrong patch!"); + } + } + + if (memcmp(the_new, new, newsize) != 0) { + ERROR("wrong patch!"); + } + +OUT: + FREE(the_new); + FREE(the_old); + FREE(patch4blk); + FREE(backup); + + backup_map_destroy(&bkup_map); + + return rc; +} + +int ota_diff(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, size_t blk_len, int is_safe_ignored, int is_verbose, uint8_t **patch, size_t *patchsize) +{ + int rc = 0; + graph_t graph; + + uint8_t *bs_patch = NULL; + size_t bs_patchsize; + uint8_t *diff_blk, *extra_blk; + + /* build a graph */ + if (graph_create(&graph, BLK_CNT(newsize, blk_len)) != 0) { + ERROR("graph build failed!"); + } + + printf("RUN bsdiff algorithm ...\n"); + /* the bsdiff algorithm */ + if (bsdiff(old, oldsize, new, newsize, &bs_patch, &bs_patchsize) != 0) { + ERROR("generate bspatch failed!"); + } + + /* some malloc */ + if (blk_info_create(oldsize, newsize, blk_len) != 0) { + ERROR("block info create failed!"); + } + + /* divide the bsdiff patch into cmds by block */ + printf("PARSING bspatch ...\n"); + if (bspatch_parse(oldsize, newsize, blk_len, bs_patch, bs_patchsize, &diff_blk, &extra_blk) != 0) { + ERROR("bspatch parse failed!"); + } + + /* check whether cmds of each block can assemble an integral block */ + printf("VERIFY cmd integrity ...\n"); + if (blk_cmd_verify(oldsize, newsize, blk_len) != 0) { + ERROR("blk cmd check failed!"); + } + + /* check whether cmds can assemble each blocks correctly and which block[s] are safe */ + /* safe means all the same after do the patch, that means nothing should patched to the old block */ + printf("SEARCHING safe block ...\n"); + if (old_blk_safe_refresh(old, oldsize, new, newsize, blk_len, diff_blk, extra_blk) != 0) { + ERROR("old blk safe refresh failed!"); + } + + /* make relied relationship simple */ + printf("BUILD dependency graph ...\n"); + if (relied_simplify(oldsize, blk_len, &graph) != 0) { + ERROR("relied simplify failed!"); + } + + printf("ANALYSING dependency graph ...\n"); + if (analysing_dependency(&graph)) { + ERROR("analysing_dependency failed!"); + } + + /* verbose*/ + if (is_verbose) { + verbose_print(&graph, oldsize, newsize, blk_len); + } + + /* make the real patch */ + printf("MAKING final patch ...\n"); + if (make_patch(&graph, oldsize, newsize, blk_len, diff_blk, extra_blk, is_safe_ignored, patch, patchsize) != 0) { + ERROR("make patch failed!"); + } + + /* test the patch if is correct */ + printf("\nTESTING final patch ...\n"); + if (patch_test(old, oldsize, new, newsize, blk_len, *patch, *patchsize) != 0) { + ERROR("patch test failed!"); + } + + printf("DONE!\n"); + if (is_verbose) { + summary_print(); + } + +OUT: + FREE(bs_patch); + + graph_destroy(&graph); + blk_info_destroy(oldsize, newsize, blk_len); + + return rc; +} + diff --git a/components/ota/common/diff/ota_diff.h b/components/ota/common/diff/ota_diff.h new file mode 100644 index 00000000..0b4abbd7 --- /dev/null +++ b/components/ota/common/diff/ota_diff.h @@ -0,0 +1,154 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_DIFF_H_ +#define _OTA_DIFF_H_ + +#include "list.h" + +#define ERROR(msg) \ + printf("ERROR: line number[%d], function[%s] msg[%s]\n", __LINE__, __FUNCTION__, msg); \ + rc = -1; \ + goto OUT; + +#ifndef INT_MAX +#define INT_MAX ((~(unsigned int)0) >> 1) +#endif + +#define BLK_CNT(size, blk_len) (((size) + (blk_len) - 1) / (blk_len)) + +#define BLK_EXTRA(size, blk_len) ((size) % (blk_len)) + +#define THE_BUF(buf, idx, blk_len) ((buf) + (idx) * (blk_len)) + +#define BLK_IDX(off, blk_len) ((off) / (blk_len)) + +#define ALIGN_UP(v, align) (((v) + ((align) - 1)) & ~((align) - 1)) + +#define BLK_UPPER_BOUND(off, blk_len) (ALIGN_UP((off) + 1, (blk_len))) + +#define BLK_LOWER_BOUND(idx, blk_len) ((idx) * (blk_len)) + +#define FOLD_N(x, n) ((n) * (x)) + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define MIN_TRIPLE(x, y, z) (MIN(x, MIN(y, z))) + +#define FREE(p) if (p) { free(p); } + +#define CMD_COPY 0 + +#define CMD_DIFF 1 + +#define CMD_EXTRA 2 + +typedef struct backup_map_t { + uint16_t *cache; + uint16_t backup_n; + uint16_t cursor; + uint16_t blk_len; + uint8_t *buf; +} bkup_map_t; + +typedef struct relied_detail_st { + list_t list; + + int32_t new_blk_idx; + + int32_t new_from; + int32_t old_from; + int32_t diff_from; + + int32_t step; +} relied_detail_t; + +typedef struct simplified_relied_detail_st { + list_t list; + + int32_t new_blk_idx; +} smpl_relied_detail_t; + +typedef struct old_block_info_st { + list_t relied_list; + int relied_cnt; + + list_t simplified_relied_list; + int simplified_relied_cnt; + + int is_safe; +} old_blk_info_t; + +typedef enum cmd_type_en { + CMD_TYPE_DIFF, + CMD_TYPE_EXTRA, +} cmd_type_t; + +typedef struct diff_detail_st { + int32_t old_from; + int32_t diff_from; +} diff_detail_t; + +typedef struct extra_detail_st { + int32_t extra_from; +} extra_detail_t; + +typedef union cmd_detail_un { + diff_detail_t diff_detail; + extra_detail_t extra_detail; +} cmd_detail_t; + +typedef struct cmd_st { + list_t list; + + int32_t new_from; + int32_t step; + + cmd_type_t type; + + cmd_detail_t detail; +} cmd_t; + +typedef struct new_block_info_st { + list_t cmd_list; + int cmd_cnt; +} new_blk_info_t; + +typedef struct summary_st { + int ring_cnt; + int ring_size_max; + int ring_size_min; + + int patch_size; + + int block_len; + int block_cnt; + + int zipped_patch4block_size_max; + int zipped_patch4block_size_min; + + int patch4block_size_max; + int patch4block_size_min; + + int safe_block_cnt; + int is_safe_block_ignored; +} summary_t; + +int ota_diff(uint8_t *old, size_t oldsize, uint8_t *new, size_t newsize, size_t blk_len, int is_safe_ignored, int is_verbose, uint8_t **patch, size_t *patchsize); + +#endif /* _OTA_DIFF_H_ */ + diff --git a/components/ota/common/diff/proc_bar.c b/components/ota/common/diff/proc_bar.c new file mode 100644 index 00000000..f79f4f29 --- /dev/null +++ b/components/ota/common/diff/proc_bar.c @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "stdio.h" +#include "string.h" +#include "proc_bar.h" + +int proc_bar_init(proc_bar_t *proc_bar, int max) +{ + const char *stat = { "-\\|/" }; + + if (!proc_bar || max <= 0) { + return -1; + } + + memset(proc_bar->buf, 0, sizeof(proc_bar->buf)); + proc_bar->cursor = 0; + proc_bar->max = max; + + printf("[%-101s][%%%d]%c\r", proc_bar->buf, 0, stat[proc_bar->cursor % 4]); + fflush(stdout); + + return 0; +} + +int proc_bar_update(proc_bar_t *proc_bar) +{ + int percentage, i = 0; + const char *stat = { "-\\|/" }; + + if (!proc_bar || proc_bar->cursor >= proc_bar->max) { + return -1; + } + + percentage = (++proc_bar->cursor) * 100 / proc_bar->max; + + for (i = 0; i <= percentage; ++i) { + proc_bar->buf[i] = '#'; + } + + printf("[%-101s][%%%d]%c\r", proc_bar->buf, percentage, stat[proc_bar->cursor % 4]); + fflush(stdout); + + return 0; +} + diff --git a/components/ota/common/diff/proc_bar.h b/components/ota/common/diff/proc_bar.h new file mode 100644 index 00000000..2ce1832f --- /dev/null +++ b/components/ota/common/diff/proc_bar.h @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PROC_BAR_H_ +#define _PROC_BAR_H_ + +typedef struct process_bar_st { + int cursor; + int max; + char buf[102]; +} proc_bar_t; + +int proc_bar_init(proc_bar_t *proc_bar, int max); + +int proc_bar_update(proc_bar_t *proc_bar); + +#endif + diff --git a/components/ota/common/diff/segment_tree.c b/components/ota/common/diff/segment_tree.c new file mode 100644 index 00000000..3888b358 --- /dev/null +++ b/components/ota/common/diff/segment_tree.c @@ -0,0 +1,233 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "stdlib.h" +#include "string.h" +#include "segment_tree.h" + +#define ROOT 1 +#define NODES_N(len) (3 * len) + +static void segtree_build(stree_node_t *nodes, int left, int right, int root) +{ + stree_node_t *node; + + node = &nodes[root]; + node->left = left; + node->right = right; + node->mid = (left + right) / 2; + node->is_covered = 0; + + if (left + 1 != right) { + segtree_build(nodes, left, node->mid, 2 * root); + segtree_build(nodes, node->mid, right, 2 * root + 1); + } +} + +int segtree_create(stree_t *stree, int left, int right) +{ + int length; + stree_node_t *nodes; + + if (!stree) { + return -1; + } + + length = right - left; + if (length <= 0) { + return -1; + } + + memset(stree, 0, sizeof(stree_t)); + + if ((nodes = (stree_node_t *)malloc(NODES_N(length) * sizeof(stree_node_t))) == NULL) { + return -1; + } + + memset(nodes, 0, NODES_N(length) * sizeof(stree_node_t)); + + segtree_build(nodes, left, right, ROOT); + + stree->nodes = nodes; + stree->length = length; + stree->left = left; + stree->right = right; + + return 0; +} + +int segtree_destroy(stree_t *stree) +{ + if (!stree || !stree->nodes || !stree->length) { + return -1; + } + + free(stree->nodes); + return 0; +} + +int segtree_reset(stree_t *stree) +{ + if (!stree || !stree->nodes || !stree->length) { + return -1; + } + + memset(stree->nodes, 0, NODES_N(stree->length) * sizeof(stree_node_t)); + + segtree_build(stree->nodes, stree->left, stree->right, ROOT); + + return 0; +} + +static void segtree_do_insert(stree_node_t *nodes, int left, int right, int root) +{ + stree_node_t *node; + + node = &nodes[root]; + + if (node->left == left && node->right == right) { + node->is_covered = 1; + return; + } + + if (right <= node->mid) { + segtree_do_insert(nodes, left, right, 2 * root); + } else if (left >= node->mid) { + segtree_do_insert(nodes, left, right, 2 * root + 1); + } else { + segtree_do_insert(nodes, left, node->mid, 2 * root); + segtree_do_insert(nodes, node->mid, right, 2 * root + 1); + } +} + +int segtree_insert(stree_t *stree, int left, int right) +{ + if (!stree || !stree->nodes) { + return -1; + } + + if (right - left < 0) { + return -1; + } + + segtree_do_insert(stree->nodes, left, right, ROOT); + + return 0; +} + +static int segtree_do_delete(stree_node_t *nodes, int left, int right, int root) +{ + int is_covered = 0; + stree_node_t *node; + + node = &nodes[root]; + + if (node->left + 1 == node->right) { + is_covered = node->is_covered; + node->is_covered = 0; + return is_covered; + } + + if (node->is_covered) { + node->is_covered = 0; + nodes[2 * root].is_covered = 1; + nodes[2 * root + 1].is_covered = 1; + } + + if (right <= node->mid) { + return segtree_do_delete(nodes, left, right, 2 * root); + } else if (left >= node->mid) { + return segtree_do_delete(nodes, left, right, 2 * root + 1); + } else { + return segtree_do_delete(nodes, left, node->mid, 2 * root) && + segtree_do_delete(nodes, node->mid, right, 2 * root + 1); + } +} + +int segtree_delete(stree_t *stree, int left, int right) +{ + if (!stree || !stree->nodes) { + return -1; + } + + if (right - left < 0) { + return -1; + } + + return segtree_do_delete(stree->nodes, left, right, ROOT); +} + +static int segtree_do_query(stree_node_t *nodes, int left, int right, int root) +{ + stree_node_t *node; + + node = &nodes[root]; + + if (node->left + 1 == node->right) { + return node->is_covered; + } + + if (right <= node->mid) { + return segtree_do_query(nodes, left, right, 2 * root); + } else if (left >= node->mid) { + return segtree_do_query(nodes, left, right, 2 * root + 1); + } else { + return segtree_do_query(nodes, left, node->mid, 2 * root) && + segtree_do_query(nodes, node->mid, right, 2 * root + 1); + } + +} + +int segtree_query(stree_t *stree, int left, int right) +{ + if (!stree || !stree->nodes) { + return -1; + } + + if (right - left < 0) { + return -1; + } + + return segtree_do_query(stree->nodes, left, right, ROOT); +} + +static int segtree_do_cal(stree_node_t *nodes, int root) +{ + stree_node_t *node; + + node = &nodes[root]; + + if (node->is_covered) { + return node->right - node->left; + } + + if (node->left + 1 == node->right) { + return 0; + } + + return segtree_do_cal(nodes, 2 * root ) + segtree_do_cal(nodes, 2 * root + 1); +} + +int segtree_cal(stree_t *stree) +{ + if (!stree || !stree->nodes) { + return -1; + } + + return segtree_do_cal(stree->nodes, ROOT); +} + diff --git a/components/ota/common/diff/segment_tree.h b/components/ota/common/diff/segment_tree.h new file mode 100644 index 00000000..3c5f16a4 --- /dev/null +++ b/components/ota/common/diff/segment_tree.h @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _SEGMENT_TREE_H_ +#define _SEGMENT_TREE_H_ + +typedef struct segment_tree_node_st { + int left; + int right; + int mid; + int is_covered; +} stree_node_t; + +typedef struct segment_tree_st { + stree_node_t *nodes; + int length; + int left; + int right; +} stree_t; + +int segtree_create(stree_t *stree, int left, int right); + +int segtree_destroy(stree_t *stree); + +int segtree_reset(stree_t *stree); + +int segtree_insert(stree_t *stree, int left, int right); + +int segtree_delete(stree_t *stree, int left, int right); + +int segtree_query(stree_t *stree, int left, int right); + +int segtree_cal(stree_t *stree); + +#endif + diff --git a/components/ota/common/diff/stack.c b/components/ota/common/diff/stack.c new file mode 100644 index 00000000..f3a02561 --- /dev/null +++ b/components/ota/common/diff/stack.c @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "stdlib.h" +#include "string.h" +#include "stack.h" + +int stack_create(stack_t *stack, int element_max) +{ + e_type_t *elements; + + if (!stack || element_max <= 0) { + return -1; + } + + memset(stack, 0, sizeof(stack_t)); + + if ((elements = malloc(element_max * sizeof(e_type_t))) == NULL) { + return -1; + } + + stack->top = 0; + stack->element_max = element_max; + stack->elements = elements; + + return 0; +} + +int stack_destroy(stack_t *stack) +{ + if (!stack || !stack->elements) { + return -1; + } + + free(stack->elements); + + return 0; +} + +int stack_push(stack_t *stack, e_type_t element) +{ + if (!stack || !stack->elements) { + return -1; + } + + if (stack_is_full(stack)) { + return -1; + } + + stack->elements[stack->top++] = element; + + return 0; +} + +e_type_t stack_pop(stack_t *stack) +{ + if (!stack || !stack->elements) { + return -1; + } + + if (stack_is_empty(stack)) { + return -1; + } + + return stack->elements[--stack->top]; +} + +e_type_t stack_top(stack_t *stack) +{ + if (!stack || !stack->elements) { + return -1; + } + + if (stack_is_empty(stack)) { + return -1; + } + + return stack->elements[stack->top - 1]; +} + + +int stack_peek_init(stack_t *stack) +{ + if (!stack || !stack->elements) { + return -1; + } + + stack->peek_top = stack->top; + + return 0; +} + +e_type_t stack_peek(stack_t *stack) +{ + if (!stack || !stack->elements) { + return -1; + } + + if (stack->peek_top == 0) { + return -1; + } + + return stack->elements[--stack->peek_top]; +} + +int stack_is_empty(stack_t *stack) +{ + if (!stack || !stack->elements) { + return 0; + } + + return stack->top == 0; +} + +int stack_is_full(stack_t *stack) +{ + if (!stack || !stack->elements) { + return 0; + } + + return stack->top == stack->element_max; +} + diff --git a/components/ota/common/diff/stack.h b/components/ota/common/diff/stack.h new file mode 100644 index 00000000..0cb00237 --- /dev/null +++ b/components/ota/common/diff/stack.h @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _STACK_H_ +#define _STACK_H_ + +typedef int element_type_t; +typedef element_type_t e_type_t; + +typedef struct stack_st { + e_type_t *elements; + int element_max; + + int peek_top; + int top; +} stack_t; + +int stack_create(stack_t *stack, int element_max); + +int stack_destroy(stack_t *stack); + +int stack_push(stack_t *stack, e_type_t element); + +e_type_t stack_pop(stack_t *stack); + +e_type_t stack_top(stack_t *stack); + +int stack_peek_init(stack_t *stack); + +e_type_t stack_peek(stack_t *stack); + +int stack_is_empty(stack_t *stack); + +int stack_is_full(stack_t *stack); + +#endif + diff --git a/components/ota/common/diff/topo_sorting.c b/components/ota/common/diff/topo_sorting.c new file mode 100644 index 00000000..6a3e2ec9 --- /dev/null +++ b/components/ota/common/diff/topo_sorting.c @@ -0,0 +1,148 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "assert.h" +#include "string.h" +#include "topo_sorting.h" + +int topo_sorting_create(topo_sorting_t *topo_sorting, graph_t *graph) +{ + int i = 0; + + if (!topo_sorting || !graph) { + return -1; + } + + memset(topo_sorting, 0, sizeof(topo_sorting_t)); + + if (stack_create(&topo_sorting->stack, graph_vertex_max(graph)) != 0) { + return 0; + } + + for (i = 0; i < graph_vertex_max(graph); ++i) { + if (graph_indegree_get(graph, i) == 0 && + graph_tag_get(graph, i) != TOPO_VISITED) { + stack_push(&topo_sorting->stack, i); + graph_tag_set(graph, i, TOPO_VISITED); + } + } + + topo_sorting->graph = graph; + + return 0; +} + +int topo_sorting_destroy(topo_sorting_t *topo_sorting) +{ + int i = 0; + + if (!topo_sorting || !topo_sorting->graph) { + return -1; + } + + for (i = 0; i < graph_vertex_max(topo_sorting->graph); ++i) { + graph_tag_reset(topo_sorting->graph, i); + } + + stack_destroy(&topo_sorting->stack); + + topo_sorting->graph = NULL; + + return 0; +} + +int topo_sorting_has_next(topo_sorting_t *topo_sorting) +{ + if (!topo_sorting || !topo_sorting->graph) { + return 0; + } + + return !stack_is_empty(&topo_sorting->stack); +} + +static void push2stack(int tail_vertex, int head_vertex, void *arg) +{ + topo_sorting_t *topo_sorting = (topo_sorting_t *)arg; + + if (graph_indegree_get(topo_sorting->graph, head_vertex) == 0) { + stack_push(&topo_sorting->stack, head_vertex); + graph_tag_set(topo_sorting->graph, head_vertex, TOPO_VISITED); + } +} + +int topo_sorting_next(topo_sorting_t *topo_sorting) +{ + int vertex; + + assert(sizeof(e_type_t) == sizeof(int)); + + if (!topo_sorting || !topo_sorting->graph) { + return -1; + } + + if (stack_is_empty(&topo_sorting->stack)) { + return -1; + } + + vertex = stack_pop(&topo_sorting->stack); + + graph_edge_rmv_by_tail(topo_sorting->graph, vertex, push2stack, (void *)topo_sorting); + + return vertex; +} + +int topo_has_ring(topo_sorting_t *topo_sorting) +{ + if (!topo_sorting || !topo_sorting->graph) { + return -1; + } + + return graph_edgesn_get(topo_sorting->graph) != 0; +} + +int topo_ring_break(topo_sorting_t *topo_sorting) +{ + int i = 0; + graph_t *graph; + + if (!topo_sorting || !topo_sorting->graph) { + return -1; + } + + graph = topo_sorting->graph; + + for (i = 0; i < graph_vertex_max(graph); ++i) { + if (graph_indegree_get(graph, i) != 0 && + graph_outdegree_get(graph, i) != 0 && + graph_tag_get(graph, i) != TOPO_VISITED) { + /* remove one edge from the graph */ + graph_edge_rmv_one_by_head(graph, i); + break; + } + } + + for (i = 0; i < graph_vertex_max(graph); ++i) { + if (graph_indegree_get(graph, i) == 0 && + graph_tag_get(graph, i) != TOPO_VISITED) { + stack_push(&topo_sorting->stack, i); + graph_tag_set(graph, i, TOPO_VISITED); + } + } + + return 0; +} + diff --git a/components/ota/common/diff/topo_sorting.h b/components/ota/common/diff/topo_sorting.h new file mode 100644 index 00000000..839d79e7 --- /dev/null +++ b/components/ota/common/diff/topo_sorting.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _TOPO_SORTING_H_ +#define _TOPO_SORTING_H_ + +#include "stack.h" +#include "graph.h" + +#define TOPO_VISITED 1 + +typedef struct topo_sorting_st { + stack_t stack; + graph_t *graph; +} topo_sorting_t; + +int topo_sorting_create(topo_sorting_t *topo_sorting, graph_t *graph); + +int topo_sorting_destroy(topo_sorting_t *topo_sorting); + +int topo_sorting_has_next(topo_sorting_t *topo_sorting); + +int topo_sorting_next(topo_sorting_t *topo_sorting); + +int topo_has_ring(topo_sorting_t *topo_sorting); + +int topo_ring_break(topo_sorting_t *topo_sorting); + +#endif + diff --git a/components/ota/common/diff/version b/components/ota/common/diff/version new file mode 100644 index 00000000..69df05f3 --- /dev/null +++ b/components/ota/common/diff/version @@ -0,0 +1 @@ +4.3 diff --git a/components/ota/common/diff/wstream.c b/components/ota/common/diff/wstream.c new file mode 100644 index 00000000..c35ed2fd --- /dev/null +++ b/components/ota/common/diff/wstream.c @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "stdlib.h" + +#include "wstream.h" + +int wstream_create(wstream_t *wstream, uint8_t *buf, int buf_size) +{ + if (!wstream || !buf) { + return -1; + } + + wstream->buf = buf; + wstream->buf_size = buf_size; + wstream->cursor = 0; + + return 0; +} + +int wstream_destroy(wstream_t *wstream) +{ + WSTREAM_SANITY_CHECK(wstream); + + wstream->buf = (uint8_t *)0; + wstream->buf_size = 0; + wstream->cursor = 0; + return 0; +} + +int wstream_reset(wstream_t *wstream) +{ + WSTREAM_SANITY_CHECK(wstream); + + wstream->cursor = 0; + return 0; +} + +int wstream_write_byte(wstream_t *wstream, uint8_t byte) +{ + WSTREAM_SANITY_CHECK(wstream); + + if (wstream->buf_size == wstream->cursor) { + return -1; + } + + wstream->buf[wstream->cursor++] = byte; + + return 0; +} + +int wstream_write_byte_at(wstream_t *wstream, int offset, uint8_t byte) +{ + WSTREAM_SANITY_CHECK(wstream); + + if (offset >= wstream->buf_size) { + return -1; + } + + wstream->buf[offset] = byte; + + return 0; +} + +int wstream_write_stream(wstream_t *wstream, uint8_t *stream, int stream_size) +{ + int i = 0; + + WSTREAM_SANITY_CHECK(wstream); + + if (wstream->buf_size - wstream->cursor < stream_size) { + return -1; + } + + for (i = 0; i < stream_size; ++i) { + wstream_write_byte(wstream, stream[i]); + } + + return 0; +} + +int wstream_write_stream_at(wstream_t *wstream, int offset, uint8_t *stream, int stream_size) +{ + int i = 0; + + WSTREAM_SANITY_CHECK(wstream); + + if (wstream->buf_size - offset < stream_size) { + return -1; + } + + for (i = 0; i < stream_size; ++i) { + wstream_write_byte_at(wstream, offset++, stream[i]); + } + + return 0; +} + +int wstream_length_get(wstream_t *wstream) +{ + WSTREAM_SANITY_CHECK(wstream); + + return wstream->cursor; +} + +uint8_t *wstream_buf_get(wstream_t *wstream) +{ + WSTREAM_SANITY_CHECK_RC(wstream, NULL); + + return wstream->buf; +} + diff --git a/components/ota/common/diff/wstream.h b/components/ota/common/diff/wstream.h new file mode 100644 index 00000000..bb9736de --- /dev/null +++ b/components/ota/common/diff/wstream.h @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _WSTREAM_H_ +#define _WSTREAM_H_ + +#include "stdint.h" + +typedef struct write_stream_st { + int buf_size; + uint8_t *buf; + int cursor; +} wstream_t; + +#define WSTREAM_SANITY_CHECK(wstream) \ + if (!wstream || !wstream->buf) { \ + return -1; \ + } + +#define WSTREAM_SANITY_CHECK_RC(wstream, rc) \ + if (!wstream || !wstream->buf) { \ + return rc; \ + } + +int wstream_create(wstream_t *wstream, uint8_t *buf, int buf_size); + +int wstream_destroy(wstream_t *wstream); + +int wstream_reset(wstream_t *wstream); + +int wstream_write_byte(wstream_t *wstream, uint8_t byte); + +int wstream_write_byte_at(wstream_t *wstream, int offset, uint8_t byte); + +int wstream_write_stream(wstream_t *wstream, uint8_t *stream, int stream_size); + +int wstream_write_stream_at(wstream_t *wstream, int offset, uint8_t *stream, int stream_size); + +int wstream_length_get(wstream_t *wstream); + +uint8_t *wstream_buf_get(wstream_t *wstream); + +#endif /* _WSTREAM_H_ */ + diff --git a/components/ota/common/env/ota_env.c b/components/ota/common/env/ota_env.c new file mode 100644 index 00000000..4fcfaaaa --- /dev/null +++ b/components/ota/common/env/ota_env.c @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos_kv.h" +#include "ota_env.h" +#include "ota_partition.h" + +int ota_env_init(ota_updt_type_t updt_type, uint32_t partition_addr, ota_flash_drv_t *flash_drv, ota_flash_prop_t *flash_prop) +{ + if (ota_flash_init(flash_drv, flash_prop) < 0) { + return -1; + } + + if (ota_partition_load(updt_type, partition_addr) < 0) { + return -1; + } + + if (tos_kv_init(ota_partition_start(OTA_PARTITION_KV), + ota_partition_end(OTA_PARTITION_KV), + (kv_flash_drv_t *)flash_drv, + (kv_flash_prop_t *)flash_prop) != KV_ERR_NONE) { + return -1; + } + + return 0; +} + diff --git a/components/ota/common/env/ota_env.h b/components/ota/common/env/ota_env.h new file mode 100644 index 00000000..833e0eb8 --- /dev/null +++ b/components/ota/common/env/ota_env.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_ENV_H_ +#define _OTA_ENV_H_ + +#include "stdint.h" +#include "ota_flash.h" +#include "ota_partition.h" + +int ota_env_init(ota_updt_type_t updt_type, uint32_t partition_addr, ota_flash_drv_t *flash_drv, ota_flash_prop_t *flash_prop); + +#endif /* _OTA_ENV_H_ */ + diff --git a/components/ota/common/flash/ota_flash.c b/components/ota/common/flash/ota_flash.c new file mode 100644 index 00000000..9b531f91 --- /dev/null +++ b/components/ota/common/flash/ota_flash.c @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "ota_flash.h" + +static ota_flash_ctl_t flash_ctl; + +int ota_flash_init(ota_flash_drv_t *flash_drv, ota_flash_prop_t *flash_prop) +{ + if (!flash_drv || !flash_prop) { + return -1; + } + + memcpy(&flash_ctl.flash_drv, flash_drv, sizeof(ota_flash_drv_t)); + + OTA_FLASH_SECTOR_SIZE_LOG2 = flash_prop->sector_size_log2; + + if (flash_prop->pgm_type == OTA_FLASH_PROGRAM_TYPE_BYTE) { + OTA_FLASH_WRITE_ALIGN = sizeof(ota_byte_t); + } else if (flash_prop->pgm_type == OTA_FLASH_PROGRAM_TYPE_HALFWORD) { + OTA_FLASH_WRITE_ALIGN = sizeof(ota_hword_t); + } else if (flash_prop->pgm_type == OTA_FLASH_PROGRAM_TYPE_WORD) { + OTA_FLASH_WRITE_ALIGN = sizeof(ota_word_t); + } else if (flash_prop->pgm_type == OTA_FLASH_PROGRAM_TYPE_DOUBLEWORD) { + OTA_FLASH_WRITE_ALIGN = sizeof(ota_dword_t); + } + + return 0; +} + +int ota_flash_read(uint32_t addr, void *buf, size_t buf_size) +{ + if (OTA_FLASH_READ(addr, buf, buf_size) < 0) { + return -1; + } + return 0; +} + +int ota_flash_write(uint32_t addr, void *buf, size_t buf_size) +{ + if (OTA_FLASH_WRITE(addr, buf, buf_size) < 0) { + return -1; + } + return 0; +} + +int ota_flash_erase(uint32_t start, size_t len) +{ + if (OTA_FLASH_ERASE(start, len) < 0) { + return -1; + } + return 0; +} + +int ota_flash_erase_blocks(uint32_t start, size_t len) +{ + return ota_flash_erase(start, OTA_ALIGN_UP(len, OTA_FLASH_SECTOR_SIZE)); +} + +size_t ota_flash_write_size_aligned_get(size_t len) +{ + return OTA_ALIGN_UP(len, OTA_FLASH_WRITE_ALIGN); +} + +int ota_flash_size_is_aligned(size_t len) +{ + return OTA_IS_ALINGED(len, OTA_FLASH_WRITE_ALIGN); +} + diff --git a/components/ota/common/flash/ota_flash.h b/components/ota/common/flash/ota_flash.h new file mode 100644 index 00000000..dd7a7376 --- /dev/null +++ b/components/ota/common/flash/ota_flash.h @@ -0,0 +1,85 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_FLASH_H_ +#define _OTA_FLASH_H_ + +#include "stdint.h" +#include "stdlib.h" +#include "string.h" + +#define OTA_FLASH_SECTOR_SIZE_LOG2 (flash_ctl.sector_size_log2) +#define OTA_FLASH_SECTOR_SIZE (1 << OTA_FLASH_SECTOR_SIZE_LOG2) +#define OTA_FLASH_WRITE_ALIGN (flash_ctl.flash_write_align) + +#define OTA_FLASH_WRITE ((ota_flash_write_t)(flash_ctl.flash_drv.write)) +#define OTA_FLASH_READ ((ota_flash_read_t)(flash_ctl.flash_drv.read)) +#define OTA_FLASH_ERASE ((ota_flash_erase_t)(flash_ctl.flash_drv.erase)) + +#define OTA_ALIGN_UP(v, align) (((v) + ((align) - 1)) & ~((align) - 1)) +#define OTA_IS_ALINGED(v, align) ((v) % (align) == 0) + +typedef uint8_t ota_byte_t; // byte +typedef uint16_t ota_hword_t; // half word +typedef uint32_t ota_word_t; // word +typedef uint64_t ota_dword_t; // double word + +typedef enum ota_flash_program_type_en { + OTA_FLASH_PROGRAM_TYPE_BYTE, /*!< Program byte (8-bit) at a specified address */ + OTA_FLASH_PROGRAM_TYPE_HALFWORD, /*!< Program a half-word (16-bit) at a specified address */ + OTA_FLASH_PROGRAM_TYPE_WORD, /*!< Program a word (32-bit) at a specified address */ + OTA_FLASH_PROGRAM_TYPE_DOUBLEWORD, /*!< Program a double word (64-bit) at a specified address */ +} ota_flash_pgm_type_t; + +typedef int (*ota_flash_write_t)(uint32_t addr, const void *buf, size_t len); +typedef int (*ota_flash_read_t)(uint32_t addr, void *buf, size_t len); +typedef int (*ota_flash_erase_t)(uint32_t addr, size_t len); + +typedef struct ota_flash_drv_st { + ota_flash_write_t write; + ota_flash_read_t read; + ota_flash_erase_t erase; +} ota_flash_drv_t; + +typedef struct ota_flash_property_st { + uint8_t sector_size_log2; + ota_flash_pgm_type_t pgm_type; +} ota_flash_prop_t; + +typedef struct ota_flash_control_st { + uint8_t sector_size_log2; + uint8_t flash_write_align; + + ota_flash_drv_t flash_drv; +} ota_flash_ctl_t; + +int ota_flash_init(ota_flash_drv_t *flash_drv, ota_flash_prop_t *flash_prop); + +int ota_flash_read(uint32_t addr, void *buf, size_t buf_size); + +int ota_flash_write(uint32_t addr, void *buf, size_t buf_size); + +int ota_flash_erase(uint32_t start, size_t len); + +int ota_flash_erase_blocks(uint32_t start, size_t len); + +size_t ota_flash_write_size_aligned_get(size_t len); + +int ota_flash_size_is_aligned(size_t len); + +#endif /* _OTA_FLASH_H_ */ + diff --git a/components/ota/common/image/ota_image.c b/components/ota/common/image/ota_image.c new file mode 100644 index 00000000..66e8dd3d --- /dev/null +++ b/components/ota/common/image/ota_image.c @@ -0,0 +1,22 @@ +#include "crc8.h" +#include "ota_image.h" + +uint8_t ota_img_hdr_crc(ota_img_hdr_t *img_hdr) +{ + uint8_t crc = 0; + + crc = crc8(crc, (uint8_t *)&img_hdr->magic, sizeof(uint16_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->new_version, sizeof(ota_img_vs_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->old_version, sizeof(ota_img_vs_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->new_crc, sizeof(uint8_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->new_size, sizeof(uint32_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->old_crc, sizeof(uint8_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->old_size, sizeof(uint32_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->patch_size, sizeof(uint32_t)); + + return crc; +} + diff --git a/components/ota/common/image/ota_image.h b/components/ota/common/image/ota_image.h new file mode 100644 index 00000000..8cb0090d --- /dev/null +++ b/components/ota/common/image/ota_image.h @@ -0,0 +1,32 @@ +#ifndef _OTA_IMAGE_H_ +#define _OTA_IMAGE_H_ + +#include "stdint.h" + +#define OTA_IMAGE_MAGIC 0xBADE + +typedef struct ota_image_version_st { + uint8_t major; /* major version number */ + uint8_t minor; /* minor version number */ +} ota_img_vs_t; + +#pragma pack(push, 1) +typedef struct ota_image_header_st { + uint16_t magic; + ota_img_vs_t new_version; + ota_img_vs_t old_version; + + uint8_t new_crc; + uint8_t old_crc; + uint8_t patch_crc; + + uint32_t new_size; + uint32_t old_size; + uint32_t patch_size; +} ota_img_hdr_t; +#pragma pack(pop) + +uint8_t ota_img_hdr_crc(ota_img_hdr_t *img_hdr); + +#endif /* _OTA_IMAGE_H_ */ + diff --git a/components/ota/common/info/ota_info.c b/components/ota/common/info/ota_info.c new file mode 100644 index 00000000..0a1414b3 --- /dev/null +++ b/components/ota/common/info/ota_info.c @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos_kv.h" +#include "ota_image.h" +#include "ota_info.h" +#include "ota_partition.h" + +ota_img_vs_t ota_info_curr_version(void) +{ + size_t version_len; + ota_img_vs_t version; + + if (tos_kv_get("cur_version", &version, sizeof(version), &version_len) != KV_ERR_NONE) { + /* no "version" key, means we have never do a update yet + just return the initial version + */ + return ota_partition_init_version_get(); + } + + return version; +} + +int ota_info_update(ota_img_vs_t new_version) +{ + kv_err_t err; + + err = tos_kv_del("new_version"); + if (err != KV_ERR_NONE && err != KV_ERR_NOT_EXIST) { + return -1; + } + + if (tos_kv_set("cur_version", &new_version, sizeof(ota_img_vs_t)) != KV_ERR_NONE) { + return -1; + } + + return 0; +} + diff --git a/components/ota/common/info/ota_info.h b/components/ota/common/info/ota_info.h new file mode 100644 index 00000000..0320e916 --- /dev/null +++ b/components/ota/common/info/ota_info.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_INFO_H_ +#define _OTA_INFO_H_ + +ota_img_vs_t ota_info_curr_version(void); + +int ota_info_update(ota_img_vs_t new_version); + +#endif /* _OTA_INFO_H_ */ + diff --git a/components/ota/common/lzma/3rdparty/7z.h b/components/ota/common/lzma/3rdparty/7z.h new file mode 100644 index 00000000..6c7886e3 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7z.h @@ -0,0 +1,202 @@ +/* 7z.h -- 7z interface +2017-04-03 : Igor Pavlov : Public domain */ + +#ifndef __7Z_H +#define __7Z_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define k7zStartHeaderSize 0x20 +#define k7zSignatureSize 6 + +extern const Byte k7zSignature[k7zSignatureSize]; + +typedef struct +{ + const Byte *Data; + size_t Size; +} CSzData; + +/* CSzCoderInfo & CSzFolder support only default methods */ + +typedef struct +{ + size_t PropsOffset; + UInt32 MethodID; + Byte NumStreams; + Byte PropsSize; +} CSzCoderInfo; + +typedef struct +{ + UInt32 InIndex; + UInt32 OutIndex; +} CSzBond; + +#define SZ_NUM_CODERS_IN_FOLDER_MAX 4 +#define SZ_NUM_BONDS_IN_FOLDER_MAX 3 +#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4 + +typedef struct +{ + UInt32 NumCoders; + UInt32 NumBonds; + UInt32 NumPackStreams; + UInt32 UnpackStream; + UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; + CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX]; + CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; +} CSzFolder; + + +SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd); + +typedef struct +{ + UInt32 Low; + UInt32 High; +} CNtfsFileTime; + +typedef struct +{ + Byte *Defs; /* MSB 0 bit numbering */ + UInt32 *Vals; +} CSzBitUi32s; + +typedef struct +{ + Byte *Defs; /* MSB 0 bit numbering */ + // UInt64 *Vals; + CNtfsFileTime *Vals; +} CSzBitUi64s; + +#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) + +#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) + +typedef struct +{ + UInt32 NumPackStreams; + UInt32 NumFolders; + + UInt64 *PackPositions; // NumPackStreams + 1 + CSzBitUi32s FolderCRCs; // NumFolders + + size_t *FoCodersOffsets; // NumFolders + 1 + UInt32 *FoStartPackStreamIndex; // NumFolders + 1 + UInt32 *FoToCoderUnpackSizes; // NumFolders + 1 + Byte *FoToMainUnpackSizeIndex; // NumFolders + UInt64 *CoderUnpackSizes; // for all coders in all folders + + Byte *CodersData; +} CSzAr; + +UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); + +SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, + ILookInStream *stream, UInt64 startPos, + Byte *outBuffer, size_t outSize, + ISzAllocPtr allocMain); + +typedef struct +{ + CSzAr db; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + + UInt32 NumFiles; + + UInt64 *UnpackPositions; // NumFiles + 1 + // Byte *IsEmptyFiles; + Byte *IsDirs; + CSzBitUi32s CRCs; + + CSzBitUi32s Attribs; + // CSzBitUi32s Parents; + CSzBitUi64s MTime; + CSzBitUi64s CTime; + + UInt32 *FolderToFile; // NumFolders + 1 + UInt32 *FileToFolder; // NumFiles + + size_t *FileNameOffsets; /* in 2-byte steps */ + Byte *FileNames; /* UTF-16-LE */ +} CSzArEx; + +#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i)) + +#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc); +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); + +/* +if dest == NULL, the return value specifies the required size of the buffer, + in 16-bit characters, including the null-terminating character. +if dest != NULL, the return value specifies the number of 16-bit characters that + are written to the dest, including the null-terminating character. */ + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); + +/* +size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex); +UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); +*/ + + + +/* + SzArEx_Extract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +SRes SzArEx_Extract( + const CSzArEx *db, + ILookInStream *inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp); + + +/* +SzArEx_Open Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, + ISzAllocPtr allocMain, ISzAllocPtr allocTemp); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zAlloc.c b/components/ota/common/lzma/3rdparty/7zAlloc.c new file mode 100644 index 00000000..c924a529 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zAlloc.c @@ -0,0 +1,80 @@ +/* 7zAlloc.c -- Allocation functions +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zAlloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef _SZ_ALLOC_DEBUG + +#ifdef _WIN32 +#include +#endif + +#include +int g_allocCount = 0; +int g_allocCountTemp = 0; + +#endif + +void *SzAlloc(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p); + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount); + g_allocCount++; + #endif + return malloc(size); +} + +void SzFree(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p); + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCount--; + fprintf(stderr, "\nFree; count = %10d", g_allocCount); + } + #endif + free(address); +} + +void *SzAllocTemp(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p); + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp); + g_allocCountTemp++; + #ifdef _WIN32 + return HeapAlloc(GetProcessHeap(), 0, size); + #endif + #endif + return malloc(size); +} + +void SzFreeTemp(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p); + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCountTemp--; + fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); + } + #ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, address); + return; + #endif + #endif + free(address); +} diff --git a/components/ota/common/lzma/3rdparty/7zAlloc.h b/components/ota/common/lzma/3rdparty/7zAlloc.h new file mode 100644 index 00000000..44778f9b --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zAlloc.h @@ -0,0 +1,19 @@ +/* 7zAlloc.h -- Allocation functions +2017-04-03 : Igor Pavlov : Public domain */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void *SzAlloc(ISzAllocPtr p, size_t size); +void SzFree(ISzAllocPtr p, void *address); + +void *SzAllocTemp(ISzAllocPtr p, size_t size); +void SzFreeTemp(ISzAllocPtr p, void *address); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zArcIn.c b/components/ota/common/lzma/3rdparty/7zArcIn.c new file mode 100644 index 00000000..f74d0fad --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zArcIn.c @@ -0,0 +1,1771 @@ +/* 7zArcIn.c -- 7z Input functions +2018-12-31 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7z.h" +#include "7zBuf.h" +#include "7zCrc.h" +#include "CpuArch.h" + +#define MY_ALLOC(T, p, size, alloc) { \ + if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } + +#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } + +#define MY_ALLOC_AND_CPY(to, size, from, alloc) \ + { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); } + +#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \ + { if ((size) == 0) to = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } } + +#define k7zMajorVersion 0 + +enum EIdEnum +{ + k7zIdEnd, + k7zIdHeader, + k7zIdArchiveProperties, + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + k7zIdSize, + k7zIdCRC, + k7zIdFolder, + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttrib, + k7zIdComment, + k7zIdEncodedHeader, + k7zIdStartPos, + k7zIdDummy + // k7zNtSecure, + // k7zParent, + // k7zIsReal +}; + +const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + +#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } + +static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) +{ + if (num == 0) + { + p->Defs = NULL; + p->Vals = NULL; + } + else + { + MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc); + MY_ALLOC(UInt32, p->Vals, num, alloc); + } + return SZ_OK; +} + +void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; +} + +#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } + +void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; +} + + +static void SzAr_Init(CSzAr *p) +{ + p->NumPackStreams = 0; + p->NumFolders = 0; + + p->PackPositions = NULL; + SzBitUi32s_Init(&p->FolderCRCs); + + p->FoCodersOffsets = NULL; + p->FoStartPackStreamIndex = NULL; + p->FoToCoderUnpackSizes = NULL; + p->FoToMainUnpackSizeIndex = NULL; + p->CoderUnpackSizes = NULL; + + p->CodersData = NULL; +} + +static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->PackPositions); + SzBitUi32s_Free(&p->FolderCRCs, alloc); + + ISzAlloc_Free(alloc, p->FoCodersOffsets); + ISzAlloc_Free(alloc, p->FoStartPackStreamIndex); + ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes); + ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); + ISzAlloc_Free(alloc, p->CoderUnpackSizes); + + ISzAlloc_Free(alloc, p->CodersData); + + SzAr_Init(p); +} + + +void SzArEx_Init(CSzArEx *p) +{ + SzAr_Init(&p->db); + + p->NumFiles = 0; + p->dataPos = 0; + + p->UnpackPositions = NULL; + p->IsDirs = NULL; + + p->FolderToFile = NULL; + p->FileToFolder = NULL; + + p->FileNameOffsets = NULL; + p->FileNames = NULL; + + SzBitUi32s_Init(&p->CRCs); + SzBitUi32s_Init(&p->Attribs); + // SzBitUi32s_Init(&p->Parents); + SzBitUi64s_Init(&p->MTime); + SzBitUi64s_Init(&p->CTime); +} + +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->UnpackPositions); + ISzAlloc_Free(alloc, p->IsDirs); + + ISzAlloc_Free(alloc, p->FolderToFile); + ISzAlloc_Free(alloc, p->FileToFolder); + + ISzAlloc_Free(alloc, p->FileNameOffsets); + ISzAlloc_Free(alloc, p->FileNames); + + SzBitUi32s_Free(&p->CRCs, alloc); + SzBitUi32s_Free(&p->Attribs, alloc); + // SzBitUi32s_Free(&p->Parents, alloc); + SzBitUi64s_Free(&p->MTime, alloc); + SzBitUi64s_Free(&p->CTime, alloc); + + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); +} + + +static int TestSignatureCandidate(const Byte *testBytes) +{ + unsigned i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; } + +#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++; +#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) +#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++; + +#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } +#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } + +#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \ + dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4); + +static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte, mask; + unsigned i; + UInt32 v; + + SZ_READ_BYTE(firstByte); + if ((firstByte & 0x80) == 0) + { + *value = firstByte; + return SZ_OK; + } + SZ_READ_BYTE(v); + if ((firstByte & 0x40) == 0) + { + *value = (((UInt32)firstByte & 0x3F) << 8) | v; + return SZ_OK; + } + SZ_READ_BYTE(mask); + *value = v | ((UInt32)mask << 8); + mask = 0x20; + for (i = 2; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); + *value |= (highPart << (8 * i)); + return SZ_OK; + } + SZ_READ_BYTE(b); + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + + +static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) +{ + Byte firstByte; + UInt64 value64; + if (sd->Size == 0) + return SZ_ERROR_ARCHIVE; + firstByte = *sd->Data; + if ((firstByte & 0x80) == 0) + { + *value = firstByte; + sd->Data++; + sd->Size--; + return SZ_OK; + } + RINOK(ReadNumber(sd, &value64)); + if (value64 >= (UInt32)0x80000000 - 1) + return SZ_ERROR_UNSUPPORTED; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4))) + return SZ_ERROR_UNSUPPORTED; + *value = (UInt32)value64; + return SZ_OK; +} + +#define ReadID(sd, value) ReadNumber(sd, value) + +static SRes SkipData(CSzData *sd) +{ + UInt64 size; + RINOK(ReadNumber(sd, &size)); + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA(sd, size); + return SZ_OK; +} + +static SRes WaitId(CSzData *sd, UInt32 id) +{ + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)); + if (type == id) + return SZ_OK; + if (type == k7zIdEnd) + return SZ_ERROR_ARCHIVE; + RINOK(SkipData(sd)); + } +} + +static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v) +{ + UInt32 numBytes = (numItems + 7) >> 3; + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + *v = sd->Data; + SKIP_DATA(sd, numBytes); + return SZ_OK; +} + +static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) +{ + Byte b = 0; + unsigned m = 0; + UInt32 sum = 0; + for (; numItems != 0; numItems--) + { + if (m == 0) + { + b = *bits++; + m = 8; + } + m--; + sum += ((b >> m) & 1); + } + return sum; +} + +static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) +{ + Byte allAreDefined; + Byte *v2; + UInt32 numBytes = (numItems + 7) >> 3; + *v = NULL; + SZ_READ_BYTE(allAreDefined); + if (numBytes == 0) + return SZ_OK; + if (allAreDefined == 0) + { + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc); + SKIP_DATA(sd, numBytes); + return SZ_OK; + } + MY_ALLOC(Byte, *v, numBytes, alloc); + v2 = *v; + memset(v2, 0xFF, (size_t)numBytes); + { + unsigned numBits = (unsigned)numItems & 7; + if (numBits != 0) + v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); + } + return SZ_OK; +} + +static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +{ + UInt32 i; + CSzData sd; + UInt32 *vals; + const Byte *defs; + MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc); + sd = *sd2; + defs = crcs->Defs; + vals = crcs->Vals; + for (i = 0; i < numItems; i++) + if (SzBitArray_Check(defs, i)) + { + SZ_READ_32(vals[i]); + } + else + vals[i] = 0; + *sd2 = sd; + return SZ_OK; +} + +static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +{ + SzBitUi32s_Free(crcs, alloc); + RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); + return ReadUi32s(sd, numItems, crcs, alloc); +} + +static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) +{ + Byte allAreDefined; + UInt32 numDefined = numItems; + SZ_READ_BYTE(allAreDefined); + if (!allAreDefined) + { + size_t numBytes = (numItems + 7) >> 3; + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + numDefined = CountDefinedBits(sd->Data, numItems); + SKIP_DATA(sd, numBytes); + } + if (numDefined > (sd->Size >> 2)) + return SZ_ERROR_ARCHIVE; + SKIP_DATA(sd, (size_t)numDefined * 4); + return SZ_OK; +} + +static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) +{ + RINOK(SzReadNumber32(sd, &p->NumPackStreams)); + + RINOK(WaitId(sd, k7zIdSize)); + MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc); + { + UInt64 sum = 0; + UInt32 i; + UInt32 numPackStreams = p->NumPackStreams; + for (i = 0; i < numPackStreams; i++) + { + UInt64 packSize; + p->PackPositions[i] = sum; + RINOK(ReadNumber(sd, &packSize)); + sum += packSize; + if (sum < packSize) + return SZ_ERROR_ARCHIVE; + } + p->PackPositions[i] = sum; + } + + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + /* CRC of packed streams is unused now */ + RINOK(SkipBitUi32s(sd, p->NumPackStreams)); + continue; + } + RINOK(SkipData(sd)); + } +} + +/* +static SRes SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; +} +*/ + +#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) + +SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) +{ + UInt32 numCoders, i; + UInt32 numInStreams = 0; + const Byte *dataStart = sd->Data; + + f->NumCoders = 0; + f->NumBonds = 0; + f->NumPackStreams = 0; + f->UnpackStream = 0; + + RINOK(SzReadNumber32(sd, &numCoders)); + if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CSzCoderInfo *coder = f->Coders + i; + unsigned idSize, j; + UInt64 id; + + SZ_READ_BYTE(mainByte); + if ((mainByte & 0xC0) != 0) + return SZ_ERROR_UNSUPPORTED; + + idSize = (unsigned)(mainByte & 0xF); + if (idSize > sizeof(id)) + return SZ_ERROR_UNSUPPORTED; + if (idSize > sd->Size) + return SZ_ERROR_ARCHIVE; + id = 0; + for (j = 0; j < idSize; j++) + { + id = ((id << 8) | *sd->Data); + sd->Data++; + sd->Size--; + } + if (id > (UInt32)0xFFFFFFFF) + return SZ_ERROR_UNSUPPORTED; + coder->MethodID = (UInt32)id; + + coder->NumStreams = 1; + coder->PropsOffset = 0; + coder->PropsSize = 0; + + if ((mainByte & 0x10) != 0) + { + UInt32 numStreams; + + RINOK(SzReadNumber32(sd, &numStreams)); + if (numStreams > k_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + coder->NumStreams = (Byte)numStreams; + + RINOK(SzReadNumber32(sd, &numStreams)); + if (numStreams != 1) + return SZ_ERROR_UNSUPPORTED; + } + + numInStreams += coder->NumStreams; + + if (numInStreams > k_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + + if ((mainByte & 0x20) != 0) + { + UInt32 propsSize = 0; + RINOK(SzReadNumber32(sd, &propsSize)); + if (propsSize > sd->Size) + return SZ_ERROR_ARCHIVE; + if (propsSize >= 0x80) + return SZ_ERROR_UNSUPPORTED; + coder->PropsOffset = sd->Data - dataStart; + coder->PropsSize = (Byte)propsSize; + sd->Data += (size_t)propsSize; + sd->Size -= (size_t)propsSize; + } + } + + /* + if (numInStreams == 1 && numCoders == 1) + { + f->NumPackStreams = 1; + f->PackStreams[0] = 0; + } + else + */ + { + Byte streamUsed[k_NumCodersStreams_in_Folder_MAX]; + UInt32 numBonds, numPackStreams; + + numBonds = numCoders - 1; + if (numInStreams < numBonds) + return SZ_ERROR_ARCHIVE; + if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + f->NumBonds = numBonds; + + numPackStreams = numInStreams - numBonds; + if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + f->NumPackStreams = numPackStreams; + + for (i = 0; i < numInStreams; i++) + streamUsed[i] = False; + + if (numBonds != 0) + { + Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX]; + + for (i = 0; i < numCoders; i++) + coderUsed[i] = False; + + for (i = 0; i < numBonds; i++) + { + CSzBond *bp = f->Bonds + i; + + RINOK(SzReadNumber32(sd, &bp->InIndex)); + if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex]) + return SZ_ERROR_ARCHIVE; + streamUsed[bp->InIndex] = True; + + RINOK(SzReadNumber32(sd, &bp->OutIndex)); + if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex]) + return SZ_ERROR_ARCHIVE; + coderUsed[bp->OutIndex] = True; + } + + for (i = 0; i < numCoders; i++) + if (!coderUsed[i]) + { + f->UnpackStream = i; + break; + } + + if (i == numCoders) + return SZ_ERROR_ARCHIVE; + } + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams; i++) + if (!streamUsed[i]) + break; + if (i == numInStreams) + return SZ_ERROR_ARCHIVE; + f->PackStreams[0] = i; + } + else + for (i = 0; i < numPackStreams; i++) + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)); + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + f->PackStreams[i] = index; + } + } + + f->NumCoders = numCoders; + + return SZ_OK; +} + + +static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) +{ + CSzData sd; + sd = *sd2; + for (; num != 0; num--) + { + Byte firstByte, mask; + unsigned i; + SZ_READ_BYTE_2(firstByte); + if ((firstByte & 0x80) == 0) + continue; + if ((firstByte & 0x40) == 0) + { + if (sd.Size == 0) + return SZ_ERROR_ARCHIVE; + sd.Size--; + sd.Data++; + continue; + } + mask = 0x20; + for (i = 2; i < 8 && (firstByte & mask) != 0; i++) + mask >>= 1; + if (i > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, i); + } + *sd2 = sd; + return SZ_OK; +} + + +#define k_Scan_NumCoders_MAX 64 +#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + + +static SRes ReadUnpackInfo(CSzAr *p, + CSzData *sd2, + UInt32 numFoldersMax, + const CBuf *tempBufs, UInt32 numTempBufs, + ISzAllocPtr alloc) +{ + CSzData sd; + + UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex; + const Byte *startBufPtr; + Byte external; + + RINOK(WaitId(sd2, k7zIdFolder)); + + RINOK(SzReadNumber32(sd2, &numFolders)); + if (numFolders > numFoldersMax) + return SZ_ERROR_UNSUPPORTED; + p->NumFolders = numFolders; + + SZ_READ_BYTE_SD(sd2, external); + if (external == 0) + sd = *sd2; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd2, &index)); + if (index >= numTempBufs) + return SZ_ERROR_ARCHIVE; + sd.Data = tempBufs[index].data; + sd.Size = tempBufs[index].size; + } + + MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc); + MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc); + MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc); + MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc); + + startBufPtr = sd.Data; + + packStreamIndex = 0; + numCodersOutStreams = 0; + + for (fo = 0; fo < numFolders; fo++) + { + UInt32 numCoders, ci, numInStreams = 0; + + p->FoCodersOffsets[fo] = sd.Data - startBufPtr; + + RINOK(SzReadNumber32(&sd, &numCoders)); + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (ci = 0; ci < numCoders; ci++) + { + Byte mainByte; + unsigned idSize; + UInt32 coderInStreams; + + SZ_READ_BYTE_2(mainByte); + if ((mainByte & 0xC0) != 0) + return SZ_ERROR_UNSUPPORTED; + idSize = (mainByte & 0xF); + if (idSize > 8) + return SZ_ERROR_UNSUPPORTED; + if (idSize > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, idSize); + + coderInStreams = 1; + + if ((mainByte & 0x10) != 0) + { + UInt32 coderOutStreams; + RINOK(SzReadNumber32(&sd, &coderInStreams)); + RINOK(SzReadNumber32(&sd, &coderOutStreams)); + if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1) + return SZ_ERROR_UNSUPPORTED; + } + + numInStreams += coderInStreams; + + if ((mainByte & 0x20) != 0) + { + UInt32 propsSize; + RINOK(SzReadNumber32(&sd, &propsSize)); + if (propsSize > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, propsSize); + } + } + + { + UInt32 indexOfMainStream = 0; + UInt32 numPackStreams = 1; + + if (numCoders != 1 || numInStreams != 1) + { + Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX]; + Byte coderUsed[k_Scan_NumCoders_MAX]; + + UInt32 i; + UInt32 numBonds = numCoders - 1; + if (numInStreams < numBonds) + return SZ_ERROR_ARCHIVE; + + if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (i = 0; i < numInStreams; i++) + streamUsed[i] = False; + for (i = 0; i < numCoders; i++) + coderUsed[i] = False; + + for (i = 0; i < numBonds; i++) + { + UInt32 index; + + RINOK(SzReadNumber32(&sd, &index)); + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + + RINOK(SzReadNumber32(&sd, &index)); + if (index >= numCoders || coderUsed[index]) + return SZ_ERROR_ARCHIVE; + coderUsed[index] = True; + } + + numPackStreams = numInStreams - numBonds; + + if (numPackStreams != 1) + for (i = 0; i < numPackStreams; i++) + { + UInt32 index; + RINOK(SzReadNumber32(&sd, &index)); + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + } + + for (i = 0; i < numCoders; i++) + if (!coderUsed[i]) + { + indexOfMainStream = i; + break; + } + + if (i == numCoders) + return SZ_ERROR_ARCHIVE; + } + + p->FoStartPackStreamIndex[fo] = packStreamIndex; + p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; + p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; + numCodersOutStreams += numCoders; + if (numCodersOutStreams < numCoders) + return SZ_ERROR_UNSUPPORTED; + if (numPackStreams > p->NumPackStreams - packStreamIndex) + return SZ_ERROR_ARCHIVE; + packStreamIndex += numPackStreams; + } + } + + p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; + + { + size_t dataSize = sd.Data - startBufPtr; + p->FoStartPackStreamIndex[fo] = packStreamIndex; + p->FoCodersOffsets[fo] = dataSize; + MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc); + } + + if (external != 0) + { + if (sd.Size != 0) + return SZ_ERROR_ARCHIVE; + sd = *sd2; + } + + RINOK(WaitId(&sd, k7zIdCodersUnpackSize)); + + MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc); + { + UInt32 i; + for (i = 0; i < numCodersOutStreams; i++) + { + RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)); + } + } + + for (;;) + { + UInt64 type; + RINOK(ReadID(&sd, &type)); + if (type == k7zIdEnd) + { + *sd2 = sd; + return SZ_OK; + } + if (type == k7zIdCRC) + { + RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)); + continue; + } + RINOK(SkipData(&sd)); + } +} + + +UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex) +{ + return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]]; +} + + +typedef struct +{ + UInt32 NumTotalSubStreams; + UInt32 NumSubDigests; + CSzData sdNumSubStreams; + CSzData sdSizes; + CSzData sdCRCs; +} CSubStreamInfo; + + +static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) +{ + UInt64 type = 0; + UInt32 numSubDigests = 0; + UInt32 numFolders = p->NumFolders; + UInt32 numUnpackStreams = numFolders; + UInt32 numUnpackSizesInData = 0; + + for (;;) + { + RINOK(ReadID(sd, &type)); + if (type == k7zIdNumUnpackStream) + { + UInt32 i; + ssi->sdNumSubStreams.Data = sd->Data; + numUnpackStreams = 0; + numSubDigests = 0; + for (i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + if (numUnpackStreams > numUnpackStreams + numStreams) + return SZ_ERROR_UNSUPPORTED; + numUnpackStreams += numStreams; + if (numStreams != 0) + numUnpackSizesInData += (numStreams - 1); + if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i)) + numSubDigests += numStreams; + } + ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data; + continue; + } + if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd) + break; + RINOK(SkipData(sd)); + } + + if (!ssi->sdNumSubStreams.Data) + { + numSubDigests = numFolders; + if (p->FolderCRCs.Defs) + numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders); + } + + ssi->NumTotalSubStreams = numUnpackStreams; + ssi->NumSubDigests = numSubDigests; + + if (type == k7zIdSize) + { + ssi->sdSizes.Data = sd->Data; + RINOK(SkipNumbers(sd, numUnpackSizesInData)); + ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data; + RINOK(ReadID(sd, &type)); + } + + for (;;) + { + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + ssi->sdCRCs.Data = sd->Data; + RINOK(SkipBitUi32s(sd, numSubDigests)); + ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data; + } + else + { + RINOK(SkipData(sd)); + } + RINOK(ReadID(sd, &type)); + } +} + +static SRes SzReadStreamsInfo(CSzAr *p, + CSzData *sd, + UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, + UInt64 *dataOffset, + CSubStreamInfo *ssi, + ISzAllocPtr alloc) +{ + UInt64 type; + + SzData_Clear(&ssi->sdSizes); + SzData_Clear(&ssi->sdCRCs); + SzData_Clear(&ssi->sdNumSubStreams); + + *dataOffset = 0; + RINOK(ReadID(sd, &type)); + if (type == k7zIdPackInfo) + { + RINOK(ReadNumber(sd, dataOffset)); + RINOK(ReadPackInfo(p, sd, alloc)); + RINOK(ReadID(sd, &type)); + } + if (type == k7zIdUnpackInfo) + { + RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)); + RINOK(ReadID(sd, &type)); + } + if (type == k7zIdSubStreamsInfo) + { + RINOK(ReadSubStreamsInfo(p, sd, ssi)); + RINOK(ReadID(sd, &type)); + } + else + { + ssi->NumTotalSubStreams = p->NumFolders; + // ssi->NumSubDigests = 0; + } + + return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED); +} + +static SRes SzReadAndDecodePackedStreams( + ILookInStream *inStream, + CSzData *sd, + CBuf *tempBufs, + UInt32 numFoldersMax, + UInt64 baseOffset, + CSzAr *p, + ISzAllocPtr allocTemp) +{ + UInt64 dataStartPos; + UInt32 fo; + CSubStreamInfo ssi; + + RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)); + + dataStartPos += baseOffset; + if (p->NumFolders == 0) + return SZ_ERROR_ARCHIVE; + + for (fo = 0; fo < p->NumFolders; fo++) + Buf_Init(tempBufs + fo); + + for (fo = 0; fo < p->NumFolders; fo++) + { + CBuf *tempBuf = tempBufs + fo; + UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); + if ((size_t)unpackSize != unpackSize) + return SZ_ERROR_MEM; + if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) + return SZ_ERROR_MEM; + } + + for (fo = 0; fo < p->NumFolders; fo++) + { + const CBuf *tempBuf = tempBufs + fo; + RINOK(LookInStream_SeekTo(inStream, dataStartPos)); + RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)); + } + + return SZ_OK; +} + +static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets) +{ + size_t pos = 0; + *offsets++ = 0; + if (numFiles == 0) + return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE; + if (size < 2) + return SZ_ERROR_ARCHIVE; + if (data[size - 2] != 0 || data[size - 1] != 0) + return SZ_ERROR_ARCHIVE; + do + { + const Byte *p; + if (pos == size) + return SZ_ERROR_ARCHIVE; + for (p = data + pos; + #ifdef _WIN32 + *(const UInt16 *)p != 0 + #else + p[0] != 0 || p[1] != 0 + #endif + ; p += 2); + pos = p - data + 2; + *offsets++ = (pos >> 1); + } + while (--numFiles); + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, + CSzData *sd2, + const CBuf *tempBufs, UInt32 numTempBufs, + ISzAllocPtr alloc) +{ + CSzData sd; + UInt32 i; + CNtfsFileTime *vals; + Byte *defs; + Byte external; + + RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)); + + SZ_READ_BYTE_SD(sd2, external); + if (external == 0) + sd = *sd2; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd2, &index)); + if (index >= numTempBufs) + return SZ_ERROR_ARCHIVE; + sd.Data = tempBufs[index].data; + sd.Size = tempBufs[index].size; + } + + MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc); + vals = p->Vals; + defs = p->Defs; + for (i = 0; i < num; i++) + if (SzBitArray_Check(defs, i)) + { + if (sd.Size < 8) + return SZ_ERROR_ARCHIVE; + vals[i].Low = GetUi32(sd.Data); + vals[i].High = GetUi32(sd.Data + 4); + SKIP_DATA2(sd, 8); + } + else + vals[i].High = vals[i].Low = 0; + + if (external == 0) + *sd2 = sd; + + return SZ_OK; +} + + +#define NUM_ADDITIONAL_STREAMS_MAX 8 + + +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ + CSzData *sd, + ILookInStream *inStream, + CBuf *tempBufs, UInt32 *numTempBufs, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp + ) +{ + CSubStreamInfo ssi; + +{ + UInt64 type; + + SzData_Clear(&ssi.sdSizes); + SzData_Clear(&ssi.sdCRCs); + SzData_Clear(&ssi.sdNumSubStreams); + + ssi.NumSubDigests = 0; + ssi.NumTotalSubStreams = 0; + + RINOK(ReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + for (;;) + { + UInt64 type2; + RINOK(ReadID(sd, &type2)); + if (type2 == k7zIdEnd) + break; + RINOK(SkipData(sd)); + } + RINOK(ReadID(sd, &type)); + } + + if (type == k7zIdAdditionalStreamsInfo) + { + CSzAr tempAr; + SRes res; + + SzAr_Init(&tempAr); + res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX, + p->startPosAfterHeader, &tempAr, allocTemp); + *numTempBufs = tempAr.NumFolders; + SzAr_Free(&tempAr, allocTemp); + + if (res != SZ_OK) + return res; + RINOK(ReadID(sd, &type)); + } + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, + &p->dataPos, &ssi, allocMain)); + p->dataPos += p->startPosAfterHeader; + RINOK(ReadID(sd, &type)); + } + + if (type == k7zIdEnd) + { + return SZ_OK; + } + + if (type != k7zIdFilesInfo) + return SZ_ERROR_ARCHIVE; +} + +{ + UInt32 numFiles = 0; + UInt32 numEmptyStreams = 0; + const Byte *emptyStreams = NULL; + const Byte *emptyFiles = NULL; + + RINOK(SzReadNumber32(sd, &numFiles)); + p->NumFiles = numFiles; + + for (;;) + { + UInt64 type; + UInt64 size; + RINOK(ReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(ReadNumber(sd, &size)); + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + + if (type >= ((UInt32)1 << 8)) + { + SKIP_DATA(sd, size); + } + else switch ((unsigned)type) + { + case k7zIdName: + { + size_t namesSize; + const Byte *namesData; + Byte external; + + SZ_READ_BYTE(external); + if (external == 0) + { + namesSize = (size_t)size - 1; + namesData = sd->Data; + } + else + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)); + if (index >= *numTempBufs) + return SZ_ERROR_ARCHIVE; + namesData = (tempBufs)[index].data; + namesSize = (tempBufs)[index].size; + } + + if ((namesSize & 1) != 0) + return SZ_ERROR_ARCHIVE; + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); + MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain); + RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) + if (external == 0) + { + SKIP_DATA(sd, namesSize); + } + break; + } + case k7zIdEmptyStream: + { + RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); + numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); + emptyFiles = NULL; + break; + } + case k7zIdEmptyFile: + { + RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)); + break; + } + case k7zIdWinAttrib: + { + Byte external; + CSzData sdSwitch; + CSzData *sdPtr; + SzBitUi32s_Free(&p->Attribs, allocMain); + RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)); + + SZ_READ_BYTE(external); + if (external == 0) + sdPtr = sd; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)); + if (index >= *numTempBufs) + return SZ_ERROR_ARCHIVE; + sdSwitch.Data = (tempBufs)[index].data; + sdSwitch.Size = (tempBufs)[index].size; + sdPtr = &sdSwitch; + } + RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)); + break; + } + /* + case k7zParent: + { + SzBitUi32s_Free(&p->Parents, allocMain); + RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain)); + RINOK(SzReadSwitch(sd)); + RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain)); + break; + } + */ + case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; + case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; + default: + { + SKIP_DATA(sd, size); + } + } + } + + if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams) + return SZ_ERROR_ARCHIVE; + + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SkipData(sd)); + } + + { + UInt32 i; + UInt32 emptyFileIndex = 0; + UInt32 folderIndex = 0; + UInt32 remSubStreams = 0; + UInt32 numSubStreams = 0; + UInt64 unpackPos = 0; + const Byte *digestsDefs = NULL; + const Byte *digestsVals = NULL; + UInt32 digestsValsIndex = 0; + UInt32 digestIndex; + Byte allDigestsDefined = 0; + Byte isDirMask = 0; + Byte crcMask = 0; + Byte mask = 0x80; + + MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain); + MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain); + MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain); + MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain); + + RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)); + + if (ssi.sdCRCs.Size != 0) + { + SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined); + if (allDigestsDefined) + digestsVals = ssi.sdCRCs.Data; + else + { + size_t numBytes = (ssi.NumSubDigests + 7) >> 3; + digestsDefs = ssi.sdCRCs.Data; + digestsVals = digestsDefs + numBytes; + } + } + + digestIndex = 0; + + for (i = 0; i < numFiles; i++, mask >>= 1) + { + if (mask == 0) + { + UInt32 byteIndex = (i - 1) >> 3; + p->IsDirs[byteIndex] = isDirMask; + p->CRCs.Defs[byteIndex] = crcMask; + isDirMask = 0; + crcMask = 0; + mask = 0x80; + } + + p->UnpackPositions[i] = unpackPos; + p->CRCs.Vals[i] = 0; + + if (emptyStreams && SzBitArray_Check(emptyStreams, i)) + { + if (emptyFiles) + { + if (!SzBitArray_Check(emptyFiles, emptyFileIndex)) + isDirMask |= mask; + emptyFileIndex++; + } + else + isDirMask |= mask; + if (remSubStreams == 0) + { + p->FileToFolder[i] = (UInt32)-1; + continue; + } + } + + if (remSubStreams == 0) + { + for (;;) + { + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderToFile[folderIndex] = i; + numSubStreams = 1; + if (ssi.sdNumSubStreams.Data) + { + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + } + remSubStreams = numSubStreams; + if (numSubStreams != 0) + break; + { + UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + unpackPos += folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + } + + folderIndex++; + } + } + + p->FileToFolder[i] = folderIndex; + + if (emptyStreams && SzBitArray_Check(emptyStreams, i)) + continue; + + if (--remSubStreams == 0) + { + UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; + if (folderUnpackSize < unpackPos - startFolderUnpackPos) + return SZ_ERROR_ARCHIVE; + unpackPos = startFolderUnpackPos + folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + + if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i)) + { + p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; + crcMask |= mask; + } + else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) + { + p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); + digestsValsIndex++; + crcMask |= mask; + } + + folderIndex++; + } + else + { + UInt64 v; + RINOK(ReadNumber(&ssi.sdSizes, &v)); + unpackPos += v; + if (unpackPos < v) + return SZ_ERROR_ARCHIVE; + if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) + { + p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); + digestsValsIndex++; + crcMask |= mask; + } + } + } + + if (mask != 0x80) + { + UInt32 byteIndex = (i - 1) >> 3; + p->IsDirs[byteIndex] = isDirMask; + p->CRCs.Defs[byteIndex] = crcMask; + } + + p->UnpackPositions[i] = unpackPos; + + if (remSubStreams != 0) + return SZ_ERROR_ARCHIVE; + + for (;;) + { + p->FolderToFile[folderIndex] = i; + if (folderIndex >= p->db.NumFolders) + break; + if (!ssi.sdNumSubStreams.Data) + return SZ_ERROR_ARCHIVE; + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + if (numSubStreams != 0) + return SZ_ERROR_ARCHIVE; + /* + { + UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + unpackPos += folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + } + */ + folderIndex++; + } + + if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0) + return SZ_ERROR_ARCHIVE; + } +} + return SZ_OK; +} + + +static SRes SzReadHeader( + CSzArEx *p, + CSzData *sd, + ILookInStream *inStream, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + UInt32 i; + UInt32 numTempBufs = 0; + SRes res; + CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX]; + + for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) + Buf_Init(tempBufs + i); + + res = SzReadHeader2(p, sd, inStream, + tempBufs, &numTempBufs, + allocMain, allocTemp); + + for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) + Buf_Free(tempBufs + i, allocTemp); + + RINOK(res); + + if (sd->Size != 0) + return SZ_ERROR_FAIL; + + return res; +} + +static SRes SzArEx_Open2( + CSzArEx *p, + ILookInStream *inStream, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + Byte header[k7zStartHeaderSize]; + Int64 startArcPos; + UInt64 nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; + UInt32 nextHeaderCRC; + CBuf buf; + SRes res; + + startArcPos = 0; + RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + + if (!TestSignatureCandidate(header)) + return SZ_ERROR_NO_ARCHIVE; + if (header[6] != k7zMajorVersion) + return SZ_ERROR_UNSUPPORTED; + + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); + + p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; + + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) + return SZ_ERROR_CRC; + + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) + return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + Int64 pos = 0; + RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)); + if ((UInt64)pos < startArcPos + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } + + RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); + + if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) + return SZ_ERROR_MEM; + + res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT); + + if (res == SZ_OK) + { + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC) + { + CSzData sd; + UInt64 type; + sd.Data = buf.data; + sd.Size = buf.size; + + res = ReadID(&sd, &type); + + if (res == SZ_OK && type == k7zIdEncodedHeader) + { + CSzAr tempAr; + CBuf tempBuf; + Buf_Init(&tempBuf); + + SzAr_Init(&tempAr); + res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp); + SzAr_Free(&tempAr, allocTemp); + + if (res != SZ_OK) + { + Buf_Free(&tempBuf, allocTemp); + } + else + { + Buf_Free(&buf, allocTemp); + buf.data = tempBuf.data; + buf.size = tempBuf.size; + sd.Data = buf.data; + sd.Size = buf.size; + res = ReadID(&sd, &type); + } + } + + if (res == SZ_OK) + { + if (type == k7zIdHeader) + { + /* + CSzData sd2; + unsigned ttt; + for (ttt = 0; ttt < 40000; ttt++) + { + SzArEx_Free(p, allocMain); + sd2 = sd; + res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp); + if (res != SZ_OK) + break; + } + */ + res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp); + } + else + res = SZ_ERROR_UNSUPPORTED; + } + } + } + + Buf_Free(&buf, allocTemp); + return res; +} + + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, + ISzAllocPtr allocMain, ISzAllocPtr allocTemp) +{ + SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + if (res != SZ_OK) + SzArEx_Free(p, allocMain); + return res; +} + + +SRes SzArEx_Extract( + const CSzArEx *p, + ILookInStream *inStream, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **tempBuf, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + UInt32 folderIndex = p->FileToFolder[fileIndex]; + SRes res = SZ_OK; + + *offset = 0; + *outSizeProcessed = 0; + + if (folderIndex == (UInt32)-1) + { + ISzAlloc_Free(allocMain, *tempBuf); + *blockIndex = folderIndex; + *tempBuf = NULL; + *outBufferSize = 0; + return SZ_OK; + } + + if (*tempBuf == NULL || *blockIndex != folderIndex) + { + UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + /* + UInt64 unpackSizeSpec = + p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] - + p->UnpackPositions[p->FolderToFile[folderIndex]]; + */ + size_t unpackSize = (size_t)unpackSizeSpec; + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + ISzAlloc_Free(allocMain, *tempBuf); + *tempBuf = NULL; + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize); + if (*tempBuf == NULL) + res = SZ_ERROR_MEM; + } + + if (res == SZ_OK) + { + res = SzAr_DecodeFolder(&p->db, folderIndex, + inStream, p->dataPos, *tempBuf, unpackSize, allocTemp); + } + } + } + + if (res == SZ_OK) + { + UInt64 unpackPos = p->UnpackPositions[fileIndex]; + *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); + *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos); + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + if (SzBitWithVals_Check(&p->CRCs, fileIndex)) + if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex]) + res = SZ_ERROR_CRC; + } + + return res; +} + + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + size_t offs = p->FileNameOffsets[fileIndex]; + size_t len = p->FileNameOffsets[fileIndex + 1] - offs; + if (dest != 0) + { + size_t i; + const Byte *src = p->FileNames + offs * 2; + for (i = 0; i < len; i++) + dest[i] = GetUi16(src + i * 2); + } + return len; +} + +/* +size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex) +{ + size_t len; + if (!p->FileNameOffsets) + return 1; + len = 0; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + if SzBitWithVals_Check(&p->Parents, fileIndex) + parent = p->Parents.Vals[fileIndex]; + if (parent == (UInt32)(Int32)-1) + return len; + fileIndex = parent; + } +} + +UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + BoolInt needSlash; + if (!p->FileNameOffsets) + { + *(--dest) = 0; + return dest; + } + needSlash = False; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen); + if (needSlash) + *(dest - 1) = '/'; + needSlash = True; + dest -= curLen; + + if SzBitWithVals_Check(&p->Parents, fileIndex) + parent = p->Parents.Vals[fileIndex]; + if (parent == (UInt32)(Int32)-1) + return dest; + fileIndex = parent; + } +} +*/ diff --git a/components/ota/common/lzma/3rdparty/7zBuf.c b/components/ota/common/lzma/3rdparty/7zBuf.c new file mode 100644 index 00000000..8865c32a --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zBuf.c @@ -0,0 +1,36 @@ +/* 7zBuf.c -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zBuf.h" + +void Buf_Init(CBuf *p) +{ + p->data = 0; + p->size = 0; +} + +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc) +{ + p->size = 0; + if (size == 0) + { + p->data = 0; + return 1; + } + p->data = (Byte *)ISzAlloc_Alloc(alloc, size); + if (p->data) + { + p->size = size; + return 1; + } + return 0; +} + +void Buf_Free(CBuf *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->data); + p->data = 0; + p->size = 0; +} diff --git a/components/ota/common/lzma/3rdparty/7zBuf.h b/components/ota/common/lzma/3rdparty/7zBuf.h new file mode 100644 index 00000000..81d1b5b6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zBuf.h @@ -0,0 +1,35 @@ +/* 7zBuf.h -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#ifndef __7Z_BUF_H +#define __7Z_BUF_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef struct +{ + Byte *data; + size_t size; +} CBuf; + +void Buf_Init(CBuf *p); +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc); +void Buf_Free(CBuf *p, ISzAllocPtr alloc); + +typedef struct +{ + Byte *data; + size_t size; + size_t pos; +} CDynBuf; + +void DynBuf_Construct(CDynBuf *p); +void DynBuf_SeekToBeg(CDynBuf *p); +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc); +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zBuf2.c b/components/ota/common/lzma/3rdparty/7zBuf2.c new file mode 100644 index 00000000..20834741 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zBuf2.c @@ -0,0 +1,52 @@ +/* 7zBuf2.c -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zBuf.h" + +void DynBuf_Construct(CDynBuf *p) +{ + p->data = 0; + p->size = 0; + p->pos = 0; +} + +void DynBuf_SeekToBeg(CDynBuf *p) +{ + p->pos = 0; +} + +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + if (size > p->size - p->pos) + { + size_t newSize = p->pos + size; + Byte *data; + newSize += newSize / 4; + data = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!data) + return 0; + p->size = newSize; + if (p->pos != 0) + memcpy(data, p->data, p->pos); + ISzAlloc_Free(alloc, p->data); + p->data = data; + } + if (size != 0) + { + memcpy(p->data + p->pos, buf, size); + p->pos += size; + } + return 1; +} + +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->data); + p->data = 0; + p->size = 0; + p->pos = 0; +} diff --git a/components/ota/common/lzma/3rdparty/7zCrc.c b/components/ota/common/lzma/3rdparty/7zCrc.c new file mode 100644 index 00000000..b4d84f02 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zCrc.c @@ -0,0 +1,128 @@ +/* 7zCrc.c -- CRC32 init +2017-06-06 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zCrc.h" +#include "CpuArch.h" + +#define kCrcPoly 0xEDB88320 + +#ifdef MY_CPU_LE + #define CRC_NUM_TABLES 8 +#else + #define CRC_NUM_TABLES 9 + + #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + + UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif + +#ifndef MY_CPU_BE + UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif + +typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); + +CRC_FUNC g_CrcUpdateT4; +CRC_FUNC g_CrcUpdateT8; +CRC_FUNC g_CrcUpdate; + +UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) +{ + return g_CrcUpdate(v, data, size, g_CrcTable); +} + +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) +{ + return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; +} + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + const Byte *pEnd = p + size; + for (; p != pEnd; p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +void MY_FAST_CALL CrcGenerateTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + g_CrcTable[i] = r; + } + for (i = 256; i < 256 * CRC_NUM_TABLES; i++) + { + UInt32 r = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); + } + + #if CRC_NUM_TABLES < 4 + + g_CrcUpdate = CrcUpdateT1; + + #else + + #ifdef MY_CPU_LE + + g_CrcUpdateT4 = CrcUpdateT4; + g_CrcUpdate = CrcUpdateT4; + + #if CRC_NUM_TABLES >= 8 + g_CrcUpdateT8 = CrcUpdateT8; + + #ifdef MY_CPU_X86_OR_AMD64 + if (!CPU_Is_InOrder()) + #endif + g_CrcUpdate = CrcUpdateT8; + #endif + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 0x01020304; + const Byte *p = (const Byte *)&k; + if (p[0] == 4 && p[1] == 3) + { + g_CrcUpdateT4 = CrcUpdateT4; + g_CrcUpdate = CrcUpdateT4; + #if CRC_NUM_TABLES >= 8 + g_CrcUpdateT8 = CrcUpdateT8; + g_CrcUpdate = CrcUpdateT8; + #endif + } + else if (p[0] != 1 || p[1] != 2) + g_CrcUpdate = CrcUpdateT1; + else + #endif + { + for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) + { + UInt32 x = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = CRC_UINT32_SWAP(x); + } + g_CrcUpdateT4 = CrcUpdateT1_BeT4; + g_CrcUpdate = CrcUpdateT1_BeT4; + #if CRC_NUM_TABLES >= 8 + g_CrcUpdateT8 = CrcUpdateT1_BeT8; + g_CrcUpdate = CrcUpdateT1_BeT8; + #endif + } + } + #endif + + #endif +} diff --git a/components/ota/common/lzma/3rdparty/7zCrc.h b/components/ota/common/lzma/3rdparty/7zCrc.h new file mode 100644 index 00000000..8fd57958 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zCrc.h @@ -0,0 +1,25 @@ +/* 7zCrc.h -- CRC32 calculation +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +extern UInt32 g_CrcTable[]; + +/* Call CrcGenerateTable one time before other CRC functions */ +void MY_FAST_CALL CrcGenerateTable(void); + +#define CRC_INIT_VAL 0xFFFFFFFF +#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zCrcOpt.c b/components/ota/common/lzma/3rdparty/7zCrcOpt.c new file mode 100644 index 00000000..73beba29 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zCrcOpt.c @@ -0,0 +1,115 @@ +/* 7zCrcOpt.c -- CRC32 calculation +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#ifndef MY_CPU_BE + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + (table + 0x300)[((v ) & 0xFF)] + ^ (table + 0x200)[((v >> 8) & 0xFF)] + ^ (table + 0x100)[((v >> 16) & 0xFF)] + ^ (table + 0x000)[((v >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 8; size -= 8, p += 8) + { + UInt32 d; + v ^= *(const UInt32 *)p; + v = + (table + 0x700)[((v ) & 0xFF)] + ^ (table + 0x600)[((v >> 8) & 0xFF)] + ^ (table + 0x500)[((v >> 16) & 0xFF)] + ^ (table + 0x400)[((v >> 24))]; + d = *((const UInt32 *)p + 1); + v ^= + (table + 0x300)[((d ) & 0xFF)] + ^ (table + 0x200)[((d >> 8) & 0xFF)] + ^ (table + 0x100)[((d >> 16) & 0xFF)] + ^ (table + 0x000)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif + + +#ifndef MY_CPU_LE + +#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + +#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8)) + +UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + table += 0x100; + v = CRC_UINT32_SWAP(v); + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + (table + 0x000)[((v ) & 0xFF)] + ^ (table + 0x100)[((v >> 8) & 0xFF)] + ^ (table + 0x200)[((v >> 16) & 0xFF)] + ^ (table + 0x300)[((v >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + return CRC_UINT32_SWAP(v); +} + +UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + table += 0x100; + v = CRC_UINT32_SWAP(v); + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + for (; size >= 8; size -= 8, p += 8) + { + UInt32 d; + v ^= *(const UInt32 *)p; + v = + (table + 0x400)[((v ) & 0xFF)] + ^ (table + 0x500)[((v >> 8) & 0xFF)] + ^ (table + 0x600)[((v >> 16) & 0xFF)] + ^ (table + 0x700)[((v >> 24))]; + d = *((const UInt32 *)p + 1); + v ^= + (table + 0x000)[((d ) & 0xFF)] + ^ (table + 0x100)[((d >> 8) & 0xFF)] + ^ (table + 0x200)[((d >> 16) & 0xFF)] + ^ (table + 0x300)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + return CRC_UINT32_SWAP(v); +} + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zDec.c b/components/ota/common/lzma/3rdparty/7zDec.c new file mode 100644 index 00000000..7c463521 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zDec.c @@ -0,0 +1,591 @@ +/* 7zDec.c -- Decoding from 7z folder +2019-02-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define _7ZIP_PPMD_SUPPPORT */ + +#include "7z.h" +#include "7zCrc.h" + +#include "Bcj2.h" +#include "Bra.h" +#include "CpuArch.h" +#include "Delta.h" +#include "LzmaDec.h" +#include "Lzma2Dec.h" +#ifdef _7ZIP_PPMD_SUPPPORT +#include "Ppmd7.h" +#endif + +#define k_Copy 0 +#define k_Delta 3 +#define k_LZMA2 0x21 +#define k_LZMA 0x30101 +#define k_BCJ 0x3030103 +#define k_BCJ2 0x303011B +#define k_PPC 0x3030205 +#define k_IA64 0x3030401 +#define k_ARM 0x3030501 +#define k_ARMT 0x3030701 +#define k_SPARC 0x3030805 + + +#ifdef _7ZIP_PPMD_SUPPPORT + +#define k_PPMD 0x30401 + +typedef struct +{ + IByteIn vt; + const Byte *cur; + const Byte *end; + const Byte *begin; + UInt64 processed; + BoolInt extra; + SRes res; + const ILookInStream *inStream; +} CByteInToLook; + +static Byte ReadByte(const IByteIn *pp) +{ + CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); + if (p->cur != p->end) + return *p->cur++; + if (p->res == SZ_OK) + { + size_t size = p->cur - p->begin; + p->processed += size; + p->res = ILookInStream_Skip(p->inStream, size); + size = (1 << 25); + p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size); + p->cur = p->begin; + p->end = p->begin + size; + if (size != 0) + return *p->cur++;; + } + p->extra = True; + return 0; +} + +static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CPpmd7 ppmd; + CByteInToLook s; + SRes res = SZ_OK; + + s.vt.Read = ReadByte; + s.inStream = inStream; + s.begin = s.end = s.cur = NULL; + s.extra = False; + s.res = SZ_OK; + s.processed = 0; + + if (propsSize != 5) + return SZ_ERROR_UNSUPPORTED; + + { + unsigned order = props[0]; + UInt32 memSize = GetUi32(props + 1); + if (order < PPMD7_MIN_ORDER || + order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) + return SZ_ERROR_UNSUPPORTED; + Ppmd7_Construct(&ppmd); + if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) + return SZ_ERROR_MEM; + Ppmd7_Init(&ppmd, order); + } + { + CPpmd7z_RangeDec rc; + Ppmd7z_RangeDec_CreateVTable(&rc); + rc.Stream = &s.vt; + if (!Ppmd7z_RangeDec_Init(&rc)) + res = SZ_ERROR_DATA; + else if (s.extra) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else + { + SizeT i; + for (i = 0; i < outSize; i++) + { + int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt); + if (s.extra || sym < 0) + break; + outBuffer[i] = (Byte)sym; + } + if (i != outSize) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) + res = SZ_ERROR_DATA; + } + } + Ppmd7_Free(&ppmd, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + const void *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = ILookInStream_Look(inStream, &inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (outSize != state.dicPos || inSize != 0) + res = SZ_ERROR_DATA; + break; + } + + if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + break; + + if (inProcessed == 0 && dicPos == state.dicPos) + { + res = SZ_ERROR_DATA; + break; + } + + res = ILookInStream_Skip(inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + + +#ifndef _7Z_NO_METHOD_LZMA2 + +static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CLzma2Dec state; + SRes res = SZ_OK; + + Lzma2Dec_Construct(&state); + if (propsSize != 1) + return SZ_ERROR_DATA; + RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); + state.decoder.dic = outBuffer; + state.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&state); + + for (;;) + { + const void *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = ILookInStream_Look(inStream, &inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; + ELzmaStatus status; + res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (outSize != state.decoder.dicPos || inSize != 0) + res = SZ_ERROR_DATA; + break; + } + + if (inProcessed == 0 && dicPos == state.decoder.dicPos) + { + res = SZ_ERROR_DATA; + break; + } + + res = ILookInStream_Skip(inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + Lzma2Dec_FreeProbs(&state, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +{ + while (inSize > 0) + { + const void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(ILookInStream_Skip(inStream, curSize)); + } + return SZ_OK; +} + +static BoolInt IS_MAIN_METHOD(UInt32 m) +{ + switch (m) + { + case k_Copy: + case k_LZMA: + #ifndef _7Z_NO_METHOD_LZMA2 + case k_LZMA2: + #endif + #ifdef _7ZIP_PPMD_SUPPPORT + case k_PPMD: + #endif + return True; + } + return False; +} + +static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c) +{ + return + c->NumStreams == 1 + /* && c->MethodID <= (UInt32)0xFFFFFFFF */ + && IS_MAIN_METHOD((UInt32)c->MethodID); +} + +#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4) + +static SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (!IS_SUPPORTED_CODER(&f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + + + #ifndef _7Z_NO_METHODS_FILTERS + + if (f->NumCoders == 2) + { + const CSzCoderInfo *c = &f->Coders[1]; + if ( + /* c->MethodID > (UInt32)0xFFFFFFFF || */ + c->NumStreams != 1 + || f->NumPackStreams != 1 + || f->PackStreams[0] != 0 + || f->NumBonds != 1 + || f->Bonds[0].InIndex != 1 + || f->Bonds[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + switch ((UInt32)c->MethodID) + { + case k_Delta: + case k_BCJ: + case k_PPC: + case k_IA64: + case k_SPARC: + case k_ARM: + case k_ARMT: + break; + default: + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; + } + + #endif + + + if (f->NumCoders == 4) + { + if (!IS_SUPPORTED_CODER(&f->Coders[1]) + || !IS_SUPPORTED_CODER(&f->Coders[2]) + || !IS_BCJ2(&f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 + || f->PackStreams[0] != 2 + || f->PackStreams[1] != 6 + || f->PackStreams[2] != 1 + || f->PackStreams[3] != 0 + || f->NumBonds != 3 + || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0 + || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1 + || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + + return SZ_ERROR_UNSUPPORTED; +} + +#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; + +static SRes SzFolder_Decode2(const CSzFolder *folder, + const Byte *propsData, + const UInt64 *unpackSizes, + const UInt64 *packPositions, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, + Byte *tempBuf[]) +{ + UInt32 ci; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; + Byte *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)); + + for (ci = 0; ci < folder->NumCoders; ci++) + { + const CSzCoderInfo *coder = &folder->Coders[ci]; + + if (IS_MAIN_METHOD((UInt32)coder->MethodID)) + { + UInt32 si = 0; + UInt64 offset; + UInt64 inSize; + Byte *outBufCur = outBuffer; + SizeT outSizeCur = outSize; + if (folder->NumCoders == 4) + { + UInt32 indices[] = { 3, 2, 0 }; + UInt64 unpackSize = unpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + Byte *temp; + outSizeCur = (SizeT)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur); + if (!temp && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (SizeT)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = packPositions[si]; + inSize = packPositions[(size_t)si + 1] - offset; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + } + else if (coder->MethodID == k_LZMA) + { + RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + #ifndef _7Z_NO_METHOD_LZMA2 + else if (coder->MethodID == k_LZMA2) + { + RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + #endif + #ifdef _7ZIP_PPMD_SUPPPORT + else if (coder->MethodID == k_PPMD) + { + RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + #endif + else + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->MethodID == k_BCJ2) + { + UInt64 offset = packPositions[1]; + UInt64 s3Size = packPositions[2] - offset; + + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + + tempSizes[2] = (SizeT)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]); + if (!tempBuf[2] && tempSizes[2] != 0) + return SZ_ERROR_MEM; + + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])); + + if ((tempSizes[0] & 3) != 0 || + (tempSizes[1] & 3) != 0 || + tempSize3 + tempSizes[0] + tempSizes[1] != outSize) + return SZ_ERROR_DATA; + + { + CBcj2Dec p; + + p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3; + p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0]; + p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1]; + p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2]; + + p.dest = outBuffer; + p.destLim = outBuffer + outSize; + + Bcj2Dec_Init(&p); + RINOK(Bcj2Dec_Decode(&p)); + + { + unsigned i; + for (i = 0; i < 4; i++) + if (p.bufs[i] != p.lims[i]) + return SZ_ERROR_DATA; + + if (!Bcj2Dec_IsFinished(&p)) + return SZ_ERROR_DATA; + + if (p.dest != p.destLim + || p.state != BCJ2_STREAM_MAIN) + return SZ_ERROR_DATA; + } + } + } + #ifndef _7Z_NO_METHODS_FILTERS + else if (ci == 1) + { + if (coder->MethodID == k_Delta) + { + if (coder->PropsSize != 1) + return SZ_ERROR_UNSUPPORTED; + { + Byte state[DELTA_STATE_SIZE]; + Delta_Init(state); + Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); + } + } + else + { + if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + switch (coder->MethodID) + { + case k_BCJ: + { + UInt32 state; + x86_Convert_Init(state); + x86_Convert(outBuffer, outSize, 0, &state, 0); + break; + } + CASE_BRA_CONV(PPC) + CASE_BRA_CONV(IA64) + CASE_BRA_CONV(SPARC) + CASE_BRA_CONV(ARM) + CASE_BRA_CONV(ARMT) + default: + return SZ_ERROR_UNSUPPORTED; + } + } + } + #endif + else + return SZ_ERROR_UNSUPPORTED; + } + + return SZ_OK; +} + + +SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, size_t outSize, + ISzAllocPtr allocMain) +{ + SRes res; + CSzFolder folder; + CSzData sd; + + const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; + sd.Data = data; + sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex]; + + res = SzGetNextFolderItem(&folder, &sd); + + if (res != SZ_OK) + return res; + + if (sd.Size != 0 + || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex] + || outSize != SzAr_GetFolderUnpackSize(p, folderIndex)) + return SZ_ERROR_FAIL; + { + unsigned i; + Byte *tempBuf[3] = { 0, 0, 0}; + + res = SzFolder_Decode2(&folder, data, + &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]], + p->PackPositions + p->FoStartPackStreamIndex[folderIndex], + inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); + + for (i = 0; i < 3; i++) + ISzAlloc_Free(allocMain, tempBuf[i]); + + if (res == SZ_OK) + if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex)) + if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex]) + res = SZ_ERROR_CRC; + + return res; + } +} diff --git a/components/ota/common/lzma/3rdparty/7zFile.c b/components/ota/common/lzma/3rdparty/7zFile.c new file mode 100644 index 00000000..8992fb1c --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zFile.c @@ -0,0 +1,286 @@ +/* 7zFile.c -- File IO +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + +#ifndef UNDER_CE +#include +#endif + +#else + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" +*/ + +#define kChunkSizeMax (1 << 22) + +#endif + +void File_Construct(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; + #else + p->file = NULL; + #endif +} + +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ + #ifdef USE_WINDOWS_FILE + p->handle = CreateFileA(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); + #else + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : + #ifdef UNDER_CE + 2; /* ENOENT */ + #else + errno; + #endif + #endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } +WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } +#endif + +#ifdef USE_WINDOWS_FILE +static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) +{ + p->handle = CreateFileW(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +} +WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } +#endif + +WRes File_Close(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } + #else + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + return res; + p->file = NULL; + } + #endif + return 0; +} + +WRes File_Read(CSzFile *p, void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + + #else + + *size = fread(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + + #endif +} + +WRes File_Write(CSzFile *p, const void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + + #else + + *size = fwrite(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + + #endif +} + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) +{ + #ifdef USE_WINDOWS_FILE + + LARGE_INTEGER value; + DWORD moveMethod; + value.LowPart = (DWORD)*pos; + value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ + switch (origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((Int64)value.HighPart << 32) | value.LowPart; + return 0; + + #else + + int moveMethod; + int res; + switch (origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return 1; + } + res = fseek(p->file, (long)*pos, moveMethod); + *pos = ftell(p->file); + return res; + + #endif +} + +WRes File_GetLength(CSzFile *p, UInt64 *length) +{ + #ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((UInt64)sizeHigh) << 32) + sizeLow; + return 0; + + #else + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + + #endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size) +{ + CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt); + return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->vt.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size) +{ + CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); + return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin) +{ + CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); + return File_Seek(&p->file, pos, origin); +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->vt.Read = FileInStream_Read; + p->vt.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size) +{ + CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt); + File_Write(&p->file, data, &size); + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->vt.Write = FileOutStream_Write; +} diff --git a/components/ota/common/lzma/3rdparty/7zFile.h b/components/ota/common/lzma/3rdparty/7zFile.h new file mode 100644 index 00000000..0e792538 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zFile.h @@ -0,0 +1,83 @@ +/* 7zFile.h -- File IO +2017-04-03 : Igor Pavlov : Public domain */ + +#ifndef __7Z_FILE_H +#define __7Z_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +#endif + +#ifdef USE_WINDOWS_FILE +#include +#else +#include +#endif + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #else + FILE *file; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +#endif +#ifdef USE_WINDOWS_FILE +WRes InFile_OpenW(CSzFile *p, const WCHAR *name); +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); +#endif +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, UInt64 *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + CSzFile file; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream vt; + CSzFile file; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream vt; + CSzFile file; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zStream.c b/components/ota/common/lzma/3rdparty/7zStream.c new file mode 100644 index 00000000..6b5aa162 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zStream.c @@ -0,0 +1,176 @@ +/* 7zStream.c -- 7z Stream functions +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zTypes.h" + +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(ISeqInStream_Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size) +{ + return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf) +{ + size_t processed = 1; + RINOK(ISeqInStream_Read(stream, buf, &processed)); + return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; +} + + + +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) +{ + Int64 t = offset; + return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); +} + +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) +{ + const void *lookBuf; + if (*size == 0) + return SZ_OK; + RINOK(ILookInStream_Look(stream, &lookBuf, size)); + memcpy(buf, lookBuf, *size); + return ILookInStream_Skip(stream, *size); +} + +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(ILookInStream_Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) +{ + return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + + + +#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); + +static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + GET_LookToRead2 + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size != 0) + { + p->pos = 0; + p->size = 0; + size2 = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, &size2); + p->size = size2; + } + if (*size > size2) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + GET_LookToRead2 + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size != 0) + { + p->pos = 0; + p->size = 0; + if (*size > p->bufSize) + *size = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, size); + size2 = p->size = *size; + } + if (*size > size2) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) +{ + GET_LookToRead2 + p->pos += offset; + return SZ_OK; +} + +static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) +{ + GET_LookToRead2 + size_t rem = p->size - p->pos; + if (rem == 0) + return ISeekInStream_Read(p->realStream, buf, size); + if (rem > *size) + rem = *size; + memcpy(buf, p->buf + p->pos, rem); + p->pos += rem; + *size = rem; + return SZ_OK; +} + +static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) +{ + GET_LookToRead2 + p->pos = p->size = 0; + return ISeekInStream_Seek(p->realStream, pos, origin); +} + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) +{ + p->vt.Look = lookahead ? + LookToRead2_Look_Lookahead : + LookToRead2_Look_Exact; + p->vt.Skip = LookToRead2_Skip; + p->vt.Read = LookToRead2_Read; + p->vt.Seek = LookToRead2_Seek; +} + + + +static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) +{ + CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); + return LookInStream_LookRead(p->realStream, buf, size); +} + +void SecToLook_CreateVTable(CSecToLook *p) +{ + p->vt.Read = SecToLook_Read; +} + +static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) +{ + CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); + return ILookInStream_Read(p->realStream, buf, size); +} + +void SecToRead_CreateVTable(CSecToRead *p) +{ + p->vt.Read = SecToRead_Read; +} diff --git a/components/ota/common/lzma/3rdparty/7zTypes.h b/components/ota/common/lzma/3rdparty/7zTypes.h new file mode 100644 index 00000000..65b3af63 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zTypes.h @@ -0,0 +1,375 @@ +/* 7zTypes.h -- Basic types +2018-08-04 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#ifdef _WIN32 +/* #include */ +#endif + +#include + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + + +#ifdef _WIN32 + +/* typedef DWORD WRes; */ +typedef unsigned WRes; +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) + +#else + +typedef int WRes; +#define MY__FACILITY_WIN32 7 +#define MY__FACILITY__WRes MY__FACILITY_WIN32 +#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000))) + +#endif + + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef _LZMA_UINT32_IS_ULONG +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +#ifdef _SZ_NO_INT_64 + +/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. + NOTES: Some code will work incorrectly in that case! */ + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#define UINT64_CONST(n) n +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#define UINT64_CONST(n) n ## ULL +#endif + +#endif + +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +typedef size_t SizeT; +#endif + +typedef int BoolInt; +/* typedef BoolInt Bool; */ +#define True 1 +#define False 0 + + +#ifdef _WIN32 +#define MY_STD_CALL __stdcall +#else +#define MY_STD_CALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_FORCE_INLINE __forceinline + +#define MY_CDECL __cdecl +#define MY_FAST_CALL __fastcall + +#else + +#define MY_NO_INLINE +#define MY_FORCE_INLINE +#define MY_CDECL +#define MY_FAST_CALL + +/* inline keyword : for C++ / C99 */ + +/* GCC, clang: */ +/* +#if defined (__GNUC__) && (__GNUC__ >= 4) +#define MY_FORCE_INLINE __attribute__((always_inline)) +#define MY_NO_INLINE __attribute__((noinline)) +#endif +*/ + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct IByteIn IByteIn; +struct IByteIn +{ + Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */ +}; +#define IByteIn_Read(p) (p)->Read(p) + + +typedef struct IByteOut IByteOut; +struct IByteOut +{ + void (*Write)(const IByteOut *p, Byte b); +}; +#define IByteOut_Write(p, b) (p)->Write(p, b) + + +typedef struct ISeqInStream ISeqInStream; +struct ISeqInStream +{ + SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +}; +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) + +/* it can return SZ_ERROR_INPUT_EOF */ +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf); + + +typedef struct ISeqOutStream ISeqOutStream; +struct ISeqOutStream +{ + size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +}; +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) + +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + + +typedef struct ISeekInStream ISeekInStream; +struct ISeekInStream +{ + SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin); +}; +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +typedef struct ILookInStream ILookInStream; +struct ILookInStream +{ + SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(const ILookInStream *p, size_t offset); + /* offset must be <= output(*size) of Look */ + + SRes (*Read)(const ILookInStream *p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin); +}; + +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size); + + + +typedef struct +{ + ILookInStream vt; + const ISeekInStream *realStream; + + size_t pos; + size_t size; /* it's data size */ + + /* the following variables must be set outside */ + Byte *buf; + size_t bufSize; +} CLookToRead2; + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); + +#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; } + + +typedef struct +{ + ISeqInStream vt; + const ILookInStream *realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + + + +typedef struct +{ + ISeqInStream vt; + const ILookInStream *realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + + +typedef struct ICompressProgress ICompressProgress; + +struct ICompressProgress +{ + SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +}; +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) + + + +typedef struct ISzAlloc ISzAlloc; +typedef const ISzAlloc * ISzAllocPtr; + +struct ISzAlloc +{ + void *(*Alloc)(ISzAllocPtr p, size_t size); + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ +}; + +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) +#define ISzAlloc_Free(p, a) (p)->Free(p, a) + +/* deprecated */ +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) + + + + + +#ifndef MY_offsetof + #ifdef offsetof + #define MY_offsetof(type, m) offsetof(type, m) + /* + #define MY_offsetof(type, m) FIELD_OFFSET(type, m) + */ + #else + #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m)) + #endif +#endif + + + +#ifndef MY_container_of + +/* +#define MY_container_of(ptr, type, m) container_of(ptr, type, m) +#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +*/ + +/* + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" + GCC 3.4.4 : classes with constructor + GCC 4.8.1 : classes with non-public variable members" +*/ + +#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m))) + + +#endif + +#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr)) + +/* +#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +*/ +#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m) + +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +/* +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m) +*/ + + + +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/7zVersion.h b/components/ota/common/lzma/3rdparty/7zVersion.h new file mode 100644 index 00000000..c176823a --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zVersion.h @@ -0,0 +1,27 @@ +#define MY_VER_MAJOR 19 +#define MY_VER_MINOR 00 +#define MY_VER_BUILD 0 +#define MY_VERSION_NUMBERS "19.00" +#define MY_VERSION MY_VERSION_NUMBERS + +#ifdef MY_CPU_NAME + #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")" +#else + #define MY_VERSION_CPU MY_VERSION +#endif + +#define MY_DATE "2019-02-21" +#undef MY_COPYRIGHT +#undef MY_VERSION_COPYRIGHT_DATE +#define MY_AUTHOR_NAME "Igor Pavlov" +#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov" + +#ifdef USE_COPYRIGHT_CR + #define MY_COPYRIGHT MY_COPYRIGHT_CR +#else + #define MY_COPYRIGHT MY_COPYRIGHT_PD +#endif + +#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE diff --git a/components/ota/common/lzma/3rdparty/7zVersion.rc b/components/ota/common/lzma/3rdparty/7zVersion.rc new file mode 100644 index 00000000..e520995d --- /dev/null +++ b/components/ota/common/lzma/3rdparty/7zVersion.rc @@ -0,0 +1,55 @@ +#define MY_VS_FFI_FILEFLAGSMASK 0x0000003FL +#define MY_VOS_NT_WINDOWS32 0x00040004L +#define MY_VOS_CE_WINDOWS32 0x00050004L + +#define MY_VFT_APP 0x00000001L +#define MY_VFT_DLL 0x00000002L + +// #include + +#ifndef MY_VERSION +#include "7zVersion.h" +#endif + +#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0 + +#ifdef DEBUG +#define DBG_FL VS_FF_DEBUG +#else +#define DBG_FL 0 +#endif + +#define MY_VERSION_INFO(fileType, descr, intName, origName) \ +LANGUAGE 9, 1 \ +1 VERSIONINFO \ + FILEVERSION MY_VER \ + PRODUCTVERSION MY_VER \ + FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \ + FILEFLAGS DBG_FL \ + FILEOS MY_VOS_NT_WINDOWS32 \ + FILETYPE fileType \ + FILESUBTYPE 0x0L \ +BEGIN \ + BLOCK "StringFileInfo" \ + BEGIN \ + BLOCK "040904b0" \ + BEGIN \ + VALUE "CompanyName", "Igor Pavlov" \ + VALUE "FileDescription", descr \ + VALUE "FileVersion", MY_VERSION \ + VALUE "InternalName", intName \ + VALUE "LegalCopyright", MY_COPYRIGHT \ + VALUE "OriginalFilename", origName \ + VALUE "ProductName", "7-Zip" \ + VALUE "ProductVersion", MY_VERSION \ + END \ + END \ + BLOCK "VarFileInfo" \ + BEGIN \ + VALUE "Translation", 0x409, 1200 \ + END \ +END + +#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe") + +#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll") diff --git a/components/ota/common/lzma/3rdparty/Aes.c b/components/ota/common/lzma/3rdparty/Aes.c new file mode 100644 index 00000000..1cdd0e78 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Aes.c @@ -0,0 +1,306 @@ +/* Aes.c -- AES encryption / decryption +2017-01-24 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Aes.h" +#include "CpuArch.h" + +static UInt32 T[256 * 4]; +static const Byte Sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); + +void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); + +AES_CODE_FUNC g_AesCbc_Encode; +AES_CODE_FUNC g_AesCbc_Decode; +AES_CODE_FUNC g_AesCtr_Code; + +static UInt32 D[256 * 4]; +static Byte InvS[256]; + +static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) + +#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) + +#define gb0(x) ( (x) & 0xFF) +#define gb1(x) (((x) >> ( 8)) & 0xFF) +#define gb2(x) (((x) >> (16)) & 0xFF) +#define gb3(x) (((x) >> (24))) + +#define gb(n, x) gb ## n(x) + +#define TT(x) (T + (x << 8)) +#define DD(x) (D + (x << 8)) + + +void AesGenTables(void) +{ + unsigned i; + for (i = 0; i < 256; i++) + InvS[Sbox[i]] = (Byte)i; + + for (i = 0; i < 256; i++) + { + { + UInt32 a1 = Sbox[i]; + UInt32 a2 = xtime(a1); + UInt32 a3 = a2 ^ a1; + TT(0)[i] = Ui32(a2, a1, a1, a3); + TT(1)[i] = Ui32(a3, a2, a1, a1); + TT(2)[i] = Ui32(a1, a3, a2, a1); + TT(3)[i] = Ui32(a1, a1, a3, a2); + } + { + UInt32 a1 = InvS[i]; + UInt32 a2 = xtime(a1); + UInt32 a4 = xtime(a2); + UInt32 a8 = xtime(a4); + UInt32 a9 = a8 ^ a1; + UInt32 aB = a8 ^ a2 ^ a1; + UInt32 aD = a8 ^ a4 ^ a1; + UInt32 aE = a8 ^ a4 ^ a2; + DD(0)[i] = Ui32(aE, a9, aD, aB); + DD(1)[i] = Ui32(aB, aE, a9, aD); + DD(2)[i] = Ui32(aD, aB, aE, a9); + DD(3)[i] = Ui32(a9, aD, aB, aE); + } + } + + g_AesCbc_Encode = AesCbc_Encode; + g_AesCbc_Decode = AesCbc_Decode; + g_AesCtr_Code = AesCtr_Code; + + #ifdef MY_CPU_X86_OR_AMD64 + if (CPU_Is_Aes_Supported()) + { + g_AesCbc_Encode = AesCbc_Encode_Intel; + g_AesCbc_Decode = AesCbc_Decode_Intel; + g_AesCtr_Code = AesCtr_Code_Intel; + } + #endif +} + + +#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])] + +#define HT4(m, i, s, p) m[i] = \ + HT(i, 0, s) ^ \ + HT(i, 1, s) ^ \ + HT(i, 2, s) ^ \ + HT(i, 3, s) ^ w[p + i] + +#define HT16(m, s, p) \ + HT4(m, 0, s, p); \ + HT4(m, 1, s, p); \ + HT4(m, 2, s, p); \ + HT4(m, 3, s, p); \ + +#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])] +#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; + + +#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])] + +#define HD4(m, i, s, p) m[i] = \ + HD(i, 0, s) ^ \ + HD(i, 1, s) ^ \ + HD(i, 2, s) ^ \ + HD(i, 3, s) ^ w[p + i]; + +#define HD16(m, s, p) \ + HD4(m, 0, s, p); \ + HD4(m, 1, s, p); \ + HD4(m, 2, s, p); \ + HD4(m, 3, s, p); \ + +#define FD(i, x) InvS[gb(x, m[(i - x) & 3])] +#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; + +void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, wSize; + wSize = keySize + 28; + keySize /= 4; + w[0] = ((UInt32)keySize / 2) + 3; + w += 4; + + for (i = 0; i < keySize; i++, key += 4) + w[i] = GetUi32(key); + + for (; i < wSize; i++) + { + UInt32 t = w[(size_t)i - 1]; + unsigned rem = i % keySize; + if (rem == 0) + t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); + else if (keySize > 6 && rem == 4) + t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); + w[i] = w[i - keySize] ^ t; + } +} + +void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, num; + Aes_SetKey_Enc(w, key, keySize); + num = keySize + 20; + w += 8; + for (i = 0; i < num; i++) + { + UInt32 r = w[i]; + w[i] = + DD(0)[Sbox[gb0(r)]] ^ + DD(1)[Sbox[gb1(r)]] ^ + DD(2)[Sbox[gb2(r)]] ^ + DD(3)[Sbox[gb3(r)]]; + } +} + +/* Aes_Encode and Aes_Decode functions work with little-endian words. + src and dest are pointers to 4 UInt32 words. + src and dest can point to same block */ + +static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + w += 4; + for (;;) + { + HT16(m, s, 0); + if (--numRounds2 == 0) + break; + HT16(s, m, 4); + w += 8; + } + w += 4; + FT4(0); FT4(1); FT4(2); FT4(3); +} + +static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4 + numRounds2 * 8; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + for (;;) + { + w -= 8; + HD16(m, s, 4); + if (--numRounds2 == 0) + break; + HD16(s, m, 0); + } + FD4(0); FD4(1); FD4(2); FD4(3); +} + +void AesCbc_Init(UInt32 *p, const Byte *iv) +{ + unsigned i; + for (i = 0; i < 4; i++) + p[i] = GetUi32(iv + i * 4); +} + +void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + p[0] ^= GetUi32(data); + p[1] ^= GetUi32(data + 4); + p[2] ^= GetUi32(data + 8); + p[3] ^= GetUi32(data + 12); + + Aes_Encode(p + 4, p, p); + + SetUi32(data, p[0]); + SetUi32(data + 4, p[1]); + SetUi32(data + 8, p[2]); + SetUi32(data + 12, p[3]); + } +} + +void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) +{ + UInt32 in[4], out[4]; + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + in[0] = GetUi32(data); + in[1] = GetUi32(data + 4); + in[2] = GetUi32(data + 8); + in[3] = GetUi32(data + 12); + + Aes_Decode(p + 4, out, in); + + SetUi32(data, p[0] ^ out[0]); + SetUi32(data + 4, p[1] ^ out[1]); + SetUi32(data + 8, p[2] ^ out[2]); + SetUi32(data + 12, p[3] ^ out[3]); + + p[0] = in[0]; + p[1] = in[1]; + p[2] = in[2]; + p[3] = in[3]; + } +} + +void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--) + { + UInt32 temp[4]; + unsigned i; + + if (++p[0] == 0) + p[1]++; + + Aes_Encode(p + 4, temp, p); + + for (i = 0; i < 4; i++, data += 4) + { + UInt32 t = temp[i]; + + #ifdef MY_CPU_LE_UNALIGN + *((UInt32 *)data) ^= t; + #else + data[0] ^= (t & 0xFF); + data[1] ^= ((t >> 8) & 0xFF); + data[2] ^= ((t >> 16) & 0xFF); + data[3] ^= ((t >> 24)); + #endif + } + } +} diff --git a/components/ota/common/lzma/3rdparty/Aes.h b/components/ota/common/lzma/3rdparty/Aes.h new file mode 100644 index 00000000..64979b5b --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Aes.h @@ -0,0 +1,38 @@ +/* Aes.h -- AES encryption / decryption +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __AES_H +#define __AES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define AES_BLOCK_SIZE 16 + +/* Call AesGenTables one time before other AES functions */ +void AesGenTables(void); + +/* UInt32 pointers must be 16-byte aligned */ + +/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ +#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) + +/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ +/* keySize = 16 or 24 or 32 (bytes) */ +typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); +void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); +void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); + +/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ +void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ +/* data - 16-byte aligned pointer to data */ +/* numBlocks - the number of 16-byte blocks in data array */ +typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); +extern AES_CODE_FUNC g_AesCbc_Encode; +extern AES_CODE_FUNC g_AesCbc_Decode; +extern AES_CODE_FUNC g_AesCtr_Code; + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/AesOpt.c b/components/ota/common/lzma/3rdparty/AesOpt.c new file mode 100644 index 00000000..9571c467 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/AesOpt.c @@ -0,0 +1,184 @@ +/* AesOpt.c -- Intel's AES +2017-06-08 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 +#if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) +#define USE_INTEL_AES +#endif +#endif + +#ifdef USE_INTEL_AES + +#include + +void MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks) +{ + __m128i m = *p; + for (; numBlocks != 0; numBlocks--, data++) + { + UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; + const __m128i *w = p + 3; + m = _mm_xor_si128(m, *data); + m = _mm_xor_si128(m, p[2]); + do + { + m = _mm_aesenc_si128(m, w[0]); + m = _mm_aesenc_si128(m, w[1]); + w += 2; + } + while (--numRounds2 != 0); + m = _mm_aesenc_si128(m, w[0]); + m = _mm_aesenclast_si128(m, w[1]); + *data = m; + } + *p = m; +} + +#define NUM_WAYS 3 + +#define AES_OP_W(op, n) { \ + const __m128i t = w[n]; \ + m0 = op(m0, t); \ + m1 = op(m1, t); \ + m2 = op(m2, t); \ + } + +#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n) +#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n) +#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n) +#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n) + +void MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks) +{ + __m128i iv = *p; + for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) + { + UInt32 numRounds2 = *(const UInt32 *)(p + 1); + const __m128i *w = p + numRounds2 * 2; + __m128i m0, m1, m2; + { + const __m128i t = w[2]; + m0 = _mm_xor_si128(t, data[0]); + m1 = _mm_xor_si128(t, data[1]); + m2 = _mm_xor_si128(t, data[2]); + } + numRounds2--; + do + { + AES_DEC(1) + AES_DEC(0) + w -= 2; + } + while (--numRounds2 != 0); + AES_DEC(1) + AES_DEC_LAST(0) + + { + __m128i t; + t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t; + t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t; + t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t; + } + } + for (; numBlocks != 0; numBlocks--, data++) + { + UInt32 numRounds2 = *(const UInt32 *)(p + 1); + const __m128i *w = p + numRounds2 * 2; + __m128i m = _mm_xor_si128(w[2], *data); + numRounds2--; + do + { + m = _mm_aesdec_si128(m, w[1]); + m = _mm_aesdec_si128(m, w[0]); + w -= 2; + } + while (--numRounds2 != 0); + m = _mm_aesdec_si128(m, w[1]); + m = _mm_aesdeclast_si128(m, w[0]); + + m = _mm_xor_si128(m, iv); + iv = *data; + *data = m; + } + *p = iv; +} + +void MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks) +{ + __m128i ctr = *p; + __m128i one; + one.m128i_u64[0] = 1; + one.m128i_u64[1] = 0; + for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) + { + UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; + const __m128i *w = p; + __m128i m0, m1, m2; + { + const __m128i t = w[2]; + ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t); + ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t); + ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t); + } + w += 3; + do + { + AES_ENC(0) + AES_ENC(1) + w += 2; + } + while (--numRounds2 != 0); + AES_ENC(0) + AES_ENC_LAST(1) + data[0] = _mm_xor_si128(data[0], m0); + data[1] = _mm_xor_si128(data[1], m1); + data[2] = _mm_xor_si128(data[2], m2); + } + for (; numBlocks != 0; numBlocks--, data++) + { + UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; + const __m128i *w = p; + __m128i m; + ctr = _mm_add_epi64(ctr, one); + m = _mm_xor_si128(ctr, p[2]); + w += 3; + do + { + m = _mm_aesenc_si128(m, w[0]); + m = _mm_aesenc_si128(m, w[1]); + w += 2; + } + while (--numRounds2 != 0); + m = _mm_aesenc_si128(m, w[0]); + m = _mm_aesenclast_si128(m, w[1]); + *data = _mm_xor_si128(*data, m); + } + *p = ctr; +} + +#else + +void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); +void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); + +void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks) +{ + AesCbc_Encode(p, data, numBlocks); +} + +void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks) +{ + AesCbc_Decode(p, data, numBlocks); +} + +void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks) +{ + AesCtr_Code(p, data, numBlocks); +} + +#endif diff --git a/components/ota/common/lzma/3rdparty/Alloc.c b/components/ota/common/lzma/3rdparty/Alloc.c new file mode 100644 index 00000000..bcede4b8 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Alloc.c @@ -0,0 +1,455 @@ +/* Alloc.c -- Memory allocation functions +2018-04-27 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#ifdef _WIN32 +#include +#endif +#include + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ + +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG + +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; + + +#define CONVERT_INT_TO_STR(charType, tempSize) \ + unsigned char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = temp[i]; } \ + *s = 0; + +static void ConvertUInt64ToString(UInt64 val, char *s) +{ + CONVERT_INT_TO_STR(char, 24); +} + +#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) + +static void ConvertUInt64ToHex(UInt64 val, char *s) +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; + do + { + unsigned t = (unsigned)(val & 0xF); + val >>= 4; + s[--i] = GET_HEX_CHAR(t); + } + while (i); +} + +#define DEBUG_OUT_STREAM stderr + +static void Print(const char *s) +{ + fputs(s, DEBUG_OUT_STREAM); +} + +static void PrintAligned(const char *s, size_t align) +{ + size_t len = strlen(s); + for(;;) + { + fputc(' ', DEBUG_OUT_STREAM); + if (len >= align) + break; + ++len; + } + Print(s); +} + +static void PrintLn() +{ + Print("\n"); +} + +static void PrintHex(UInt64 v, size_t align) +{ + char s[32]; + ConvertUInt64ToHex(v, s); + PrintAligned(s, align); +} + +static void PrintDec(UInt64 v, size_t align) +{ + char s[32]; + ConvertUInt64ToString(v, s); + PrintAligned(s, align); +} + +static void PrintAddr(void *p) +{ + PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12); +} + + +#define PRINT_ALLOC(name, cnt, size, ptr) \ + Print(name " "); \ + PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); + +#define PRINT_FREE(name, cnt, ptr) if (ptr) { \ + Print(name " "); \ + PrintDec(--cnt, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#else + +#define PRINT_ALLOC(name, cnt, size, ptr) +#define PRINT_FREE(name, cnt, ptr) +#define Print(s) +#define PrintLn() +#define PrintHex(v, align) +#define PrintDec(v, align) +#define PrintAddr(p) + +#endif + + + +void *MyAlloc(size_t size) +{ + if (size == 0) + return NULL; + #ifdef _SZ_ALLOC_DEBUG + { + void *p = malloc(size); + PRINT_ALLOC("Alloc ", g_allocCount, size, p); + return p; + } + #else + return malloc(size); + #endif +} + +void MyFree(void *address) +{ + PRINT_FREE("Free ", g_allocCount, address); + + free(address); +} + +#ifdef _WIN32 + +void *MidAlloc(size_t size) +{ + if (size == 0) + return NULL; + + PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL); + + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); +} + +void MidFree(void *address) +{ + PRINT_FREE("Free-Mid", g_allocCountMid, address); + + if (!address) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#ifndef MEM_LARGE_PAGES +#undef _7ZIP_LARGE_PAGES +#endif + +#ifdef _7ZIP_LARGE_PAGES +SIZE_T g_LargePageSize = 0; +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); +#endif + +void SetLargePageSize() +{ + #ifdef _7ZIP_LARGE_PAGES + SIZE_T size; + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (!largePageMinimum) + return; + size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return; + g_LargePageSize = size; + #endif +} + + +void *BigAlloc(size_t size) +{ + if (size == 0) + return NULL; + + PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL); + + #ifdef _7ZIP_LARGE_PAGES + { + SIZE_T ps = g_LargePageSize; + if (ps != 0 && ps <= (1 << 30) && size > (ps / 2)) + { + size_t size2; + ps--; + size2 = (size + ps) & ~ps; + if (size2 >= size) + { + void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (res) + return res; + } + } + } + #endif + + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) +{ + PRINT_FREE("Free-Big", g_allocCountBig, address); + + if (!address) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#endif + + +static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); } +static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); } +const ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); } +static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); } +const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree }; + +static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); } +static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); } +const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; + + +/* + uintptr_t : C99 (optional) + : unsupported in VS6 +*/ + +#ifdef _WIN32 + typedef UINT_PTR UIntPtr; +#else + /* + typedef uintptr_t UIntPtr; + */ + typedef ptrdiff_t UIntPtr; +#endif + + +#define ADJUST_ALLOC_SIZE 0 +/* +#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1) +*/ +/* + Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if + MyAlloc() can return address that is NOT multiple of sizeof(void *). +*/ + + +/* +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1)))) +*/ +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1)))) + +#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align) + + +#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32) + #define USE_posix_memalign +#endif + +/* + This posix_memalign() is for test purposes only. + We also need special Free() function instead of free(), + if this posix_memalign() is used. +*/ + +/* +static int posix_memalign(void **ptr, size_t align, size_t size) +{ + size_t newSize = size + align; + void *p; + void *pAligned; + *ptr = NULL; + if (newSize < size) + return 12; // ENOMEM + p = MyAlloc(newSize); + if (!p) + return 12; // ENOMEM + pAligned = MY_ALIGN_PTR_UP_PLUS(p, align); + ((void **)pAligned)[-1] = p; + *ptr = pAligned; + return 0; +} +*/ + +/* + ALLOC_ALIGN_SIZE >= sizeof(void *) + ALLOC_ALIGN_SIZE >= cache_line_size +*/ + +#define ALLOC_ALIGN_SIZE ((size_t)1 << 7) + +static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) +{ + #ifndef USE_posix_memalign + + void *p; + void *pAligned; + size_t newSize; + UNUSED_VAR(pp); + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + + newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + p = MyAlloc(newSize); + + if (!p) + return NULL; + pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE); + + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(p); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + ((void **)pAligned)[-1] = p; + + return pAligned; + + #else + + void *p; + UNUSED_VAR(pp); + if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size)) + return NULL; + + Print(" posix_memalign="); PrintAddr(p); + PrintLn(); + + return p; + + #endif +} + + +static void SzAlignedFree(ISzAllocPtr pp, void *address) +{ + UNUSED_VAR(pp); + #ifndef USE_posix_memalign + if (address) + MyFree(((void **)address)[-1]); + #else + free(address); + #endif +} + + +const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree }; + + + +#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) + +/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */ +#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] +/* +#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1] +*/ + +static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size) +{ + CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); + void *adr; + void *pAligned; + size_t newSize; + size_t extra; + size_t alignSize = (size_t)1 << p->numAlignBits; + + if (alignSize < sizeof(void *)) + alignSize = sizeof(void *); + + if (p->offset >= alignSize) + return NULL; + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + extra = p->offset & (sizeof(void *) - 1); + newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + adr = ISzAlloc_Alloc(p->baseAlloc, newSize); + + if (!adr) + return NULL; + + pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr + + alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset; + + PrintLn(); + Print("- Aligned: "); + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(adr); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + REAL_BLOCK_PTR_VAR(pAligned) = adr; + + return pAligned; +} + + +static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address) +{ + if (address) + { + CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); + PrintLn(); + Print("- Aligned Free: "); + PrintLn(); + ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address)); + } +} + + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p) +{ + p->vt.Alloc = AlignOffsetAlloc_Alloc; + p->vt.Free = AlignOffsetAlloc_Free; +} diff --git a/components/ota/common/lzma/3rdparty/Alloc.h b/components/ota/common/lzma/3rdparty/Alloc.h new file mode 100644 index 00000000..64823764 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Alloc.h @@ -0,0 +1,51 @@ +/* Alloc.h -- Memory allocation functions +2018-02-19 : Igor Pavlov : Public domain */ + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void *MyAlloc(size_t size); +void MyFree(void *address); + +#ifdef _WIN32 + +void SetLargePageSize(); + +void *MidAlloc(size_t size); +void MidFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +extern const ISzAlloc g_Alloc; +extern const ISzAlloc g_BigAlloc; +extern const ISzAlloc g_MidAlloc; +extern const ISzAlloc g_AlignedAlloc; + + +typedef struct +{ + ISzAlloc vt; + ISzAllocPtr baseAlloc; + unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */ + size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */ +} CAlignOffsetAlloc; + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p); + + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Bcj2.c b/components/ota/common/lzma/3rdparty/Bcj2.c new file mode 100644 index 00000000..9a0046a6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bcj2.c @@ -0,0 +1,257 @@ +/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) +2018-04-28 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bcj2.h" +#include "CpuArch.h" + +#define CProb UInt16 + +#define kTopValue ((UInt32)1 << 24) +#define kNumModelBits 11 +#define kBitModelTotal (1 << kNumModelBits) +#define kNumMoveBits 5 + +#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) +#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); + +void Bcj2Dec_Init(CBcj2Dec *p) +{ + unsigned i; + + p->state = BCJ2_DEC_STATE_OK; + p->ip = 0; + p->temp[3] = 0; + p->range = 0; + p->code = 0; + for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) + p->probs[i] = kBitModelTotal >> 1; +} + +SRes Bcj2Dec_Decode(CBcj2Dec *p) +{ + if (p->range <= 5) + { + p->state = BCJ2_DEC_STATE_OK; + for (; p->range != 5; p->range++) + { + if (p->range == 1 && p->code != 0) + return SZ_ERROR_DATA; + + if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + return SZ_OK; + } + + p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + } + + if (p->code == 0xFFFFFFFF) + return SZ_ERROR_DATA; + + p->range = 0xFFFFFFFF; + } + else if (p->state >= BCJ2_DEC_STATE_ORIG_0) + { + while (p->state <= BCJ2_DEC_STATE_ORIG_3) + { + Byte *dest = p->dest; + if (dest == p->destLim) + return SZ_OK; + *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; + p->state++; + p->dest = dest + 1; + } + } + + /* + if (BCJ2_IS_32BIT_STREAM(p->state)) + { + const Byte *cur = p->bufs[p->state]; + if (cur == p->lims[p->state]) + return SZ_OK; + p->bufs[p->state] = cur + 4; + + { + UInt32 val; + Byte *dest; + SizeT rem; + + p->ip += 4; + val = GetBe32(cur) - p->ip; + dest = p->dest; + rem = p->destLim - dest; + if (rem < 4) + { + SizeT i; + SetUi32(p->temp, val); + for (i = 0; i < rem; i++) + dest[i] = p->temp[i]; + p->dest = dest + rem; + p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; + return SZ_OK; + } + SetUi32(dest, val); + p->temp[3] = (Byte)(val >> 24); + p->dest = dest + 4; + p->state = BCJ2_DEC_STATE_OK; + } + } + */ + + for (;;) + { + if (BCJ2_IS_32BIT_STREAM(p->state)) + p->state = BCJ2_DEC_STATE_OK; + else + { + if (p->range < kTopValue) + { + if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + return SZ_OK; + } + p->range <<= 8; + p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + } + + { + const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; + const Byte *srcLim; + Byte *dest; + SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; + + if (num == 0) + { + p->state = BCJ2_STREAM_MAIN; + return SZ_OK; + } + + dest = p->dest; + if (num > (SizeT)(p->destLim - dest)) + { + num = p->destLim - dest; + if (num == 0) + { + p->state = BCJ2_DEC_STATE_ORIG; + return SZ_OK; + } + } + + srcLim = src + num; + + if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) + *dest = src[0]; + else for (;;) + { + Byte b = *src; + *dest = b; + if (b != 0x0F) + { + if ((b & 0xFE) == 0xE8) + break; + dest++; + if (++src != srcLim) + continue; + break; + } + dest++; + if (++src == srcLim) + break; + if ((*src & 0xF0) != 0x80) + continue; + *dest = *src; + break; + } + + num = src - p->bufs[BCJ2_STREAM_MAIN]; + + if (src == srcLim) + { + p->temp[3] = src[-1]; + p->bufs[BCJ2_STREAM_MAIN] = src; + p->ip += (UInt32)num; + p->dest += num; + p->state = + p->bufs[BCJ2_STREAM_MAIN] == + p->lims[BCJ2_STREAM_MAIN] ? + (unsigned)BCJ2_STREAM_MAIN : + (unsigned)BCJ2_DEC_STATE_ORIG; + return SZ_OK; + } + + { + UInt32 bound, ttt; + CProb *prob; + Byte b = src[0]; + Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); + + p->temp[3] = b; + p->bufs[BCJ2_STREAM_MAIN] = src + 1; + num++; + p->ip += (UInt32)num; + p->dest += num; + + prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); + + _IF_BIT_0 + { + _UPDATE_0 + continue; + } + _UPDATE_1 + + } + } + } + + { + UInt32 val; + unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + const Byte *cur = p->bufs[cj]; + Byte *dest; + SizeT rem; + + if (cur == p->lims[cj]) + { + p->state = cj; + break; + } + + val = GetBe32(cur); + p->bufs[cj] = cur + 4; + + p->ip += 4; + val -= p->ip; + dest = p->dest; + rem = p->destLim - dest; + + if (rem < 4) + { + p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; + p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; + p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; + p->temp[3] = (Byte)val; + p->dest = dest + rem; + p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; + break; + } + + SetUi32(dest, val); + p->temp[3] = (Byte)(val >> 24); + p->dest = dest + 4; + } + } + + if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) + { + p->range <<= 8; + p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + } + + return SZ_OK; +} diff --git a/components/ota/common/lzma/3rdparty/Bcj2.h b/components/ota/common/lzma/3rdparty/Bcj2.h new file mode 100644 index 00000000..8824080a --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bcj2.h @@ -0,0 +1,146 @@ +/* Bcj2.h -- BCJ2 Converter for x86 code +2014-11-10 : Igor Pavlov : Public domain */ + +#ifndef __BCJ2_H +#define __BCJ2_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define BCJ2_NUM_STREAMS 4 + +enum +{ + BCJ2_STREAM_MAIN, + BCJ2_STREAM_CALL, + BCJ2_STREAM_JUMP, + BCJ2_STREAM_RC +}; + +enum +{ + BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, + BCJ2_DEC_STATE_ORIG_1, + BCJ2_DEC_STATE_ORIG_2, + BCJ2_DEC_STATE_ORIG_3, + + BCJ2_DEC_STATE_ORIG, + BCJ2_DEC_STATE_OK +}; + +enum +{ + BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, + BCJ2_ENC_STATE_OK +}; + + +#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) + +/* +CBcj2Dec / CBcj2Enc +bufs sizes: + BUF_SIZE(n) = lims[n] - bufs[n] +bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: + (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 + (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 +*/ + +/* +CBcj2Dec: +dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: + bufs[BCJ2_STREAM_MAIN] >= dest && + bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + + BUF_SIZE(BCJ2_STREAM_CALL) + + BUF_SIZE(BCJ2_STREAM_JUMP) + tempReserv = 0 : for first call of Bcj2Dec_Decode + tempReserv = 4 : for any other calls of Bcj2Dec_Decode + overlap with offset = 1 is not allowed +*/ + +typedef struct +{ + const Byte *bufs[BCJ2_NUM_STREAMS]; + const Byte *lims[BCJ2_NUM_STREAMS]; + Byte *dest; + const Byte *destLim; + + unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ + + UInt32 ip; + Byte temp[4]; + UInt32 range; + UInt32 code; + UInt16 probs[2 + 256]; +} CBcj2Dec; + +void Bcj2Dec_Init(CBcj2Dec *p); + +/* Returns: SZ_OK or SZ_ERROR_DATA */ +SRes Bcj2Dec_Decode(CBcj2Dec *p); + +#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) + + + +typedef enum +{ + BCJ2_ENC_FINISH_MODE_CONTINUE, + BCJ2_ENC_FINISH_MODE_END_BLOCK, + BCJ2_ENC_FINISH_MODE_END_STREAM +} EBcj2Enc_FinishMode; + +typedef struct +{ + Byte *bufs[BCJ2_NUM_STREAMS]; + const Byte *lims[BCJ2_NUM_STREAMS]; + const Byte *src; + const Byte *srcLim; + + unsigned state; + EBcj2Enc_FinishMode finishMode; + + Byte prevByte; + + Byte cache; + UInt32 range; + UInt64 low; + UInt64 cacheSize; + + UInt32 ip; + + /* 32-bit ralative offset in JUMP/CALL commands is + - (mod 4 GB) in 32-bit mode + - signed Int32 in 64-bit mode + We use (mod 4 GB) check for fileSize. + Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ + UInt32 fileIp; + UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ + UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ + + UInt32 tempTarget; + unsigned tempPos; + Byte temp[4 * 2]; + + unsigned flushPos; + + UInt16 probs[2 + 256]; +} CBcj2Enc; + +void Bcj2Enc_Init(CBcj2Enc *p); +void Bcj2Enc_Encode(CBcj2Enc *p); + +#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) +#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) + + +#define BCJ2_RELAT_LIMIT_NUM_BITS 26 +#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) + +/* limit for CBcj2Enc::fileSize variable */ +#define BCJ2_FileSize_MAX ((UInt32)1 << 31) + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Bcj2Enc.c b/components/ota/common/lzma/3rdparty/Bcj2Enc.c new file mode 100644 index 00000000..bfbeb8e4 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bcj2Enc.c @@ -0,0 +1,311 @@ +/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code) +2019-02-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +/* #define SHOW_STAT */ + +#ifdef SHOW_STAT +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#include + +#include "Bcj2.h" +#include "CpuArch.h" + +#define CProb UInt16 + +#define kTopValue ((UInt32)1 << 24) +#define kNumModelBits 11 +#define kBitModelTotal (1 << kNumModelBits) +#define kNumMoveBits 5 + +void Bcj2Enc_Init(CBcj2Enc *p) +{ + unsigned i; + + p->state = BCJ2_ENC_STATE_OK; + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + + p->prevByte = 0; + + p->cache = 0; + p->range = 0xFFFFFFFF; + p->low = 0; + p->cacheSize = 1; + + p->ip = 0; + + p->fileIp = 0; + p->fileSize = 0; + p->relatLimit = BCJ2_RELAT_LIMIT; + + p->tempPos = 0; + + p->flushPos = 0; + + for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) + p->probs[i] = kBitModelTotal >> 1; +} + +static BoolInt MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0) + { + Byte *buf = p->bufs[BCJ2_STREAM_RC]; + do + { + if (buf == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + p->bufs[BCJ2_STREAM_RC] = buf; + return True; + } + *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32)); + p->cache = 0xFF; + } + while (--p->cacheSize); + p->bufs[BCJ2_STREAM_RC] = buf; + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; + return False; +} + +static void Bcj2Enc_Encode_2(CBcj2Enc *p) +{ + if (BCJ2_IS_32BIT_STREAM(p->state)) + { + Byte *cur = p->bufs[p->state]; + if (cur == p->lims[p->state]) + return; + SetBe32(cur, p->tempTarget); + p->bufs[p->state] = cur + 4; + } + + p->state = BCJ2_ENC_STATE_ORIG; + + for (;;) + { + if (p->range < kTopValue) + { + if (RangeEnc_ShiftLow(p)) + return; + p->range <<= 8; + } + + { + { + const Byte *src = p->src; + const Byte *srcLim; + Byte *dest; + SizeT num = p->srcLim - src; + + if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + { + if (num <= 4) + return; + num -= 4; + } + else if (num == 0) + break; + + dest = p->bufs[BCJ2_STREAM_MAIN]; + if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest)) + { + num = p->lims[BCJ2_STREAM_MAIN] - dest; + if (num == 0) + { + p->state = BCJ2_STREAM_MAIN; + return; + } + } + + srcLim = src + num; + + if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80) + *dest = src[0]; + else for (;;) + { + Byte b = *src; + *dest = b; + if (b != 0x0F) + { + if ((b & 0xFE) == 0xE8) + break; + dest++; + if (++src != srcLim) + continue; + break; + } + dest++; + if (++src == srcLim) + break; + if ((*src & 0xF0) != 0x80) + continue; + *dest = *src; + break; + } + + num = src - p->src; + + if (src == srcLim) + { + p->prevByte = src[-1]; + p->bufs[BCJ2_STREAM_MAIN] = dest; + p->src = src; + p->ip += (UInt32)num; + continue; + } + + { + Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]); + BoolInt needConvert; + + p->bufs[BCJ2_STREAM_MAIN] = dest + 1; + p->ip += (UInt32)num + 1; + src++; + + needConvert = False; + + if ((SizeT)(p->srcLim - src) >= 4) + { + UInt32 relatVal = GetUi32(src); + if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize) + && ((relatVal + p->relatLimit) >> 1) < p->relatLimit) + needConvert = True; + } + + { + UInt32 bound; + unsigned ttt; + Byte b = src[-1]; + CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0)); + + ttt = *prob; + bound = (p->range >> kNumModelBits) * ttt; + + if (!needConvert) + { + p->range = bound; + *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + p->src = src; + p->prevByte = b; + continue; + } + + p->low += bound; + p->range -= bound; + *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); + + { + UInt32 relatVal = GetUi32(src); + UInt32 absVal; + p->ip += 4; + absVal = p->ip + relatVal; + p->prevByte = src[3]; + src += 4; + p->src = src; + { + unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + Byte *cur = p->bufs[cj]; + if (cur == p->lims[cj]) + { + p->state = cj; + p->tempTarget = absVal; + return; + } + SetBe32(cur, absVal); + p->bufs[cj] = cur + 4; + } + } + } + } + } + } + } + + if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + return; + + for (; p->flushPos < 5; p->flushPos++) + if (RangeEnc_ShiftLow(p)) + return; + p->state = BCJ2_ENC_STATE_OK; +} + + +void Bcj2Enc_Encode(CBcj2Enc *p) +{ + PRF(printf("\n")); + PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); + + if (p->tempPos != 0) + { + unsigned extra = 0; + + for (;;) + { + const Byte *src = p->src; + const Byte *srcLim = p->srcLim; + EBcj2Enc_FinishMode finishMode = p->finishMode; + + p->src = p->temp; + p->srcLim = p->temp + p->tempPos; + if (src != srcLim) + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + + PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); + + Bcj2Enc_Encode_2(p); + + { + unsigned num = (unsigned)(p->src - p->temp); + unsigned tempPos = p->tempPos - num; + unsigned i; + p->tempPos = tempPos; + for (i = 0; i < tempPos; i++) + p->temp[i] = p->temp[(size_t)i + num]; + + p->src = src; + p->srcLim = srcLim; + p->finishMode = finishMode; + + if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim) + return; + + if (extra >= tempPos) + { + p->src = src - tempPos; + p->tempPos = 0; + break; + } + + p->temp[tempPos] = src[0]; + p->tempPos = tempPos + 1; + p->src = src + 1; + extra++; + } + } + } + + PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); + + Bcj2Enc_Encode_2(p); + + if (p->state == BCJ2_ENC_STATE_ORIG) + { + const Byte *src = p->src; + unsigned rem = (unsigned)(p->srcLim - src); + unsigned i; + for (i = 0; i < rem; i++) + p->temp[i] = src[i]; + p->tempPos = rem; + p->src = src + rem; + } +} diff --git a/components/ota/common/lzma/3rdparty/Bra.c b/components/ota/common/lzma/3rdparty/Bra.c new file mode 100644 index 00000000..aed17e33 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bra.c @@ -0,0 +1,230 @@ +/* Bra.c -- Converters for RISC code +2017-04-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "Bra.h" + +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip += 4; + p = data; + lim = data + size; + + if (encoding) + + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + p += 4; + if (p[-1] == 0xEB) + break; + } + { + UInt32 v = GetUi32(p - 4); + v <<= 2; + v += ip + (UInt32)(p - data); + v >>= 2; + v &= 0x00FFFFFF; + v |= 0xEB000000; + SetUi32(p - 4, v); + } + } + + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + p += 4; + if (p[-1] == 0xEB) + break; + } + { + UInt32 v = GetUi32(p - 4); + v <<= 2; + v -= ip + (UInt32)(p - data); + v >>= 2; + v &= 0x00FFFFFF; + v |= 0xEB000000; + SetUi32(p - 4, v); + } + } +} + + +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + Byte *p; + const Byte *lim; + size &= ~(size_t)1; + p = data; + lim = data + size - 4; + + if (encoding) + + for (;;) + { + UInt32 b1; + for (;;) + { + UInt32 b3; + if (p > lim) + return p - data; + b1 = p[1]; + b3 = p[3]; + p += 2; + b1 ^= 8; + if ((b3 & b1) >= 0xF8) + break; + } + { + UInt32 v = + ((UInt32)b1 << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + + p += 2; + { + UInt32 cur = (ip + (UInt32)(p - data)) >> 1; + v += cur; + } + + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xF8 | (v >> 8)); + } + } + + for (;;) + { + UInt32 b1; + for (;;) + { + UInt32 b3; + if (p > lim) + return p - data; + b1 = p[1]; + b3 = p[3]; + p += 2; + b1 ^= 8; + if ((b3 & b1) >= 0xF8) + break; + } + { + UInt32 v = + ((UInt32)b1 << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + + p += 2; + { + UInt32 cur = (ip + (UInt32)(p - data)) >> 1; + v -= cur; + } + + /* + SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); + SetUi16(p - 2, (UInt16)(v | 0xF800)); + */ + + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xF8 | (v >> 8)); + } + } +} + + +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip -= 4; + p = data; + lim = data + size; + + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + p += 4; + /* if ((v & 0xFC000003) == 0x48000001) */ + if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) + break; + } + { + UInt32 v = GetBe32(p - 4); + if (encoding) + v += ip + (UInt32)(p - data); + else + v -= ip + (UInt32)(p - data); + v &= 0x03FFFFFF; + v |= 0x48000000; + SetBe32(p - 4, v); + } + } +} + + +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip -= 4; + p = data; + lim = data + size; + + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + /* + v = GetBe32(p); + p += 4; + m = v + ((UInt32)5 << 29); + m ^= (UInt32)7 << 29; + m += (UInt32)1 << 22; + if ((m & ((UInt32)0x1FF << 23)) == 0) + break; + */ + p += 4; + if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || + (p[-4] == 0x7F && (p[-3] >= 0xC0))) + break; + } + { + UInt32 v = GetBe32(p - 4); + v <<= 2; + if (encoding) + v += ip + (UInt32)(p - data); + else + v -= ip + (UInt32)(p - data); + + v &= 0x01FFFFFF; + v -= (UInt32)1 << 24; + v ^= 0xFF000000; + v >>= 2; + v |= 0x40000000; + SetBe32(p - 4, v); + } + } +} diff --git a/components/ota/common/lzma/3rdparty/Bra.h b/components/ota/common/lzma/3rdparty/Bra.h new file mode 100644 index 00000000..855e37a6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bra.h @@ -0,0 +1,64 @@ +/* Bra.h -- Branch converters for executables +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __BRA_H +#define __BRA_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* +These functions convert relative addresses to absolute addresses +in CALL instructions to increase the compression ratio. + + In: + data - data buffer + size - size of data + ip - current virtual Instruction Pinter (IP) value + state - state variable for x86 converter + encoding - 0 (for decoding), 1 (for encoding) + + Out: + state - state variable for x86 converter + + Returns: + The number of processed bytes. If you call these functions with multiple calls, + you must start next call with first byte after block of processed bytes. + + Type Endian Alignment LookAhead + + x86 little 1 4 + ARMT little 2 2 + ARM little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + size must be >= Alignment + LookAhead, if it's not last block. + If (size < Alignment + LookAhead), converter returns 0. + + Example: + + UInt32 ip = 0; + for () + { + ; size must be >= Alignment + LookAhead, if it's not last block + SizeT processed = Convert(data, size, ip, 1); + data += processed; + size -= processed; + ip += processed; + } +*/ + +#define x86_Convert_Init(state) { state = 0; } +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Bra86.c b/components/ota/common/lzma/3rdparty/Bra86.c new file mode 100644 index 00000000..93ed4d76 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Bra86.c @@ -0,0 +1,82 @@ +/* Bra86.c -- Converter for x86 code (BCJ) +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bra.h" + +#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) + +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +{ + SizeT pos = 0; + UInt32 mask = *state & 7; + if (size < 5) + return 0; + size -= 4; + ip += 5; + + for (;;) + { + Byte *p = data + pos; + const Byte *limit = data + size; + for (; p < limit; p++) + if ((*p & 0xFE) == 0xE8) + break; + + { + SizeT d = (SizeT)(p - data - pos); + pos = (SizeT)(p - data); + if (p >= limit) + { + *state = (d > 2 ? 0 : mask >> (unsigned)d); + return pos; + } + if (d > 2) + mask = 0; + else + { + mask >>= (unsigned)d; + if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) + { + mask = (mask >> 1) | 4; + pos++; + continue; + } + } + } + + if (Test86MSByte(p[4])) + { + UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); + UInt32 cur = ip + (UInt32)pos; + pos += 5; + if (encoding) + v += cur; + else + v -= cur; + if (mask != 0) + { + unsigned sh = (mask & 6) << 2; + if (Test86MSByte((Byte)(v >> sh))) + { + v ^= (((UInt32)0x100 << sh) - 1); + if (encoding) + v += cur; + else + v -= cur; + } + mask = 0; + } + p[1] = (Byte)v; + p[2] = (Byte)(v >> 8); + p[3] = (Byte)(v >> 16); + p[4] = (Byte)(0 - ((v >> 24) & 1)); + } + else + { + mask = (mask >> 1) | 4; + pos++; + } + } +} diff --git a/components/ota/common/lzma/3rdparty/BraIA64.c b/components/ota/common/lzma/3rdparty/BraIA64.c new file mode 100644 index 00000000..d1dbc62c --- /dev/null +++ b/components/ota/common/lzma/3rdparty/BraIA64.c @@ -0,0 +1,53 @@ +/* BraIA64.c -- Converter for IA-64 code +2017-01-26 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "Bra.h" + +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 16) + return 0; + size -= 16; + i = 0; + do + { + unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3; + if (m) + { + m++; + do + { + Byte *p = data + (i + (size_t)m * 5 - 8); + if (((p[3] >> m) & 15) == 5 + && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0) + { + unsigned raw = GetUi32(p); + unsigned v = raw >> m; + v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3); + + v <<= 4; + if (encoding) + v += ip + (UInt32)i; + else + v -= ip + (UInt32)i; + v >>= 4; + + v &= 0x1FFFFF; + v += 0x700000; + v &= 0x8FFFFF; + raw &= ~((UInt32)0x8FFFFF << m); + raw |= (v << m); + SetUi32(p, raw); + } + } + while (++m <= 4); + } + i += 16; + } + while (i <= size); + return i; +} diff --git a/components/ota/common/lzma/3rdparty/Compiler.h b/components/ota/common/lzma/3rdparty/Compiler.h new file mode 100644 index 00000000..0cc409d8 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Compiler.h @@ -0,0 +1,33 @@ +/* Compiler.h +2017-04-03 : Igor Pavlov : Public domain */ + +#ifndef __7Z_COMPILER_H +#define __7Z_COMPILER_H + +#ifdef _MSC_VER + + #ifdef UNDER_CE + #define RPC_NO_WINDOWS_H + /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ + #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union + #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int + #endif + + #if _MSC_VER >= 1300 + #pragma warning(disable : 4996) // This function or variable may be unsafe + #else + #pragma warning(disable : 4511) // copy constructor could not be generated + #pragma warning(disable : 4512) // assignment operator could not be generated + #pragma warning(disable : 4514) // unreferenced inline function has been removed + #pragma warning(disable : 4702) // unreachable code + #pragma warning(disable : 4710) // not inlined + #pragma warning(disable : 4714) // function marked as __forceinline not inlined + #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information + #endif + +#endif + +#define UNUSED_VAR(x) (void)x; +/* #define UNUSED_VAR(x) x=x; */ + +#endif diff --git a/components/ota/common/lzma/3rdparty/CpuArch.c b/components/ota/common/lzma/3rdparty/CpuArch.c new file mode 100644 index 00000000..02e482e0 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/CpuArch.c @@ -0,0 +1,218 @@ +/* CpuArch.c -- CPU specific code +2018-02-18: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + +#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) +#define USE_ASM +#endif + +#if !defined(USE_ASM) && _MSC_VER >= 1500 +#include +#endif + +#if defined(USE_ASM) && !defined(MY_CPU_AMD64) +static UInt32 CheckFlag(UInt32 flag) +{ + #ifdef _MSC_VER + __asm pushfd; + __asm pop EAX; + __asm mov EDX, EAX; + __asm xor EAX, flag; + __asm push EAX; + __asm popfd; + __asm pushfd; + __asm pop EAX; + __asm xor EAX, EDX; + __asm push EDX; + __asm popfd; + __asm and flag, EAX; + #else + __asm__ __volatile__ ( + "pushf\n\t" + "pop %%EAX\n\t" + "movl %%EAX,%%EDX\n\t" + "xorl %0,%%EAX\n\t" + "push %%EAX\n\t" + "popf\n\t" + "pushf\n\t" + "pop %%EAX\n\t" + "xorl %%EDX,%%EAX\n\t" + "push %%EDX\n\t" + "popf\n\t" + "andl %%EAX, %0\n\t": + "=c" (flag) : "c" (flag) : + "%eax", "%edx"); + #endif + return flag; +} +#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif + +void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) +{ + #ifdef USE_ASM + + #ifdef _MSC_VER + + UInt32 a2, b2, c2, d2; + __asm xor EBX, EBX; + __asm xor ECX, ECX; + __asm xor EDX, EDX; + __asm mov EAX, function; + __asm cpuid; + __asm mov a2, EAX; + __asm mov b2, EBX; + __asm mov c2, ECX; + __asm mov d2, EDX; + + *a = a2; + *b = b2; + *c = c2; + *d = d2; + + #else + + __asm__ __volatile__ ( + #if defined(MY_CPU_AMD64) && defined(__PIC__) + "mov %%rbx, %%rdi;" + "cpuid;" + "xchg %%rbx, %%rdi;" + : "=a" (*a) , + "=D" (*b) , + #elif defined(MY_CPU_X86) && defined(__PIC__) + "mov %%ebx, %%edi;" + "cpuid;" + "xchgl %%ebx, %%edi;" + : "=a" (*a) , + "=D" (*b) , + #else + "cpuid" + : "=a" (*a) , + "=b" (*b) , + #endif + "=c" (*c) , + "=d" (*d) + : "0" (function)) ; + + #endif + + #else + + int CPUInfo[4]; + __cpuid(CPUInfo, function); + *a = CPUInfo[0]; + *b = CPUInfo[1]; + *c = CPUInfo[2]; + *d = CPUInfo[3]; + + #endif +} + +BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p) +{ + CHECK_CPUID_IS_SUPPORTED + MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); + MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); + return True; +} + +static const UInt32 kVendors[][3] = +{ + { 0x756E6547, 0x49656E69, 0x6C65746E}, + { 0x68747541, 0x69746E65, 0x444D4163}, + { 0x746E6543, 0x48727561, 0x736C7561} +}; + +int x86cpuid_GetFirm(const Cx86cpuid *p) +{ + unsigned i; + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) + { + const UInt32 *v = kVendors[i]; + if (v[0] == p->vendor[0] && + v[1] == p->vendor[1] && + v[2] == p->vendor[2]) + return (int)i; + } + return -1; +} + +BoolInt CPU_Is_InOrder() +{ + Cx86cpuid p; + int firm; + UInt32 family, model; + if (!x86cpuid_CheckAndRead(&p)) + return True; + + family = x86cpuid_GetFamily(p.ver); + model = x86cpuid_GetModel(p.ver); + + firm = x86cpuid_GetFirm(&p); + + switch (firm) + { + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( + /* In-Order Atom CPU */ + model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ + || model == 0x26 /* 45 nm, Z6xx */ + || model == 0x27 /* 32 nm, Z2460 */ + || model == 0x35 /* 32 nm, Z2760 */ + || model == 0x36 /* 32 nm, N2xxx, D2xxx */ + ))); + case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); + case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); + } + return True; +} + +#if !defined(MY_CPU_AMD64) && defined(_WIN32) +#include +static BoolInt CPU_Sys_Is_SSE_Supported() +{ + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionEx(&vi)) + return False; + return (vi.dwMajorVersion >= 5); +} +#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; +#else +#define CHECK_SYS_SSE_SUPPORT +#endif + +BoolInt CPU_Is_Aes_Supported() +{ + Cx86cpuid p; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_CheckAndRead(&p)) + return False; + return (p.c >> 25) & 1; +} + +BoolInt CPU_IsSupported_PageGB() +{ + Cx86cpuid cpuid; + if (!x86cpuid_CheckAndRead(&cpuid)) + return False; + { + UInt32 d[4] = { 0 }; + MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]); + if (d[0] < 0x80000001) + return False; + } + { + UInt32 d[4] = { 0 }; + MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]); + return (d[3] >> 26) & 1; + } +} + +#endif diff --git a/components/ota/common/lzma/3rdparty/CpuArch.h b/components/ota/common/lzma/3rdparty/CpuArch.h new file mode 100644 index 00000000..bd429388 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/CpuArch.h @@ -0,0 +1,336 @@ +/* CpuArch.h -- CPU specific code +2018-02-18 : Igor Pavlov : Public domain */ + +#ifndef __CPU_ARCH_H +#define __CPU_ARCH_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* +MY_CPU_LE means that CPU is LITTLE ENDIAN. +MY_CPU_BE means that CPU is BIG ENDIAN. +If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. + +MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. +*/ + +#if defined(_M_X64) \ + || defined(_M_AMD64) \ + || defined(__x86_64__) \ + || defined(__AMD64__) \ + || defined(__amd64__) + #define MY_CPU_AMD64 + #ifdef __ILP32__ + #define MY_CPU_NAME "x32" + #else + #define MY_CPU_NAME "x64" + #endif + #define MY_CPU_64BIT +#endif + + +#if defined(_M_IX86) \ + || defined(__i386__) + #define MY_CPU_X86 + #define MY_CPU_NAME "x86" + #define MY_CPU_32BIT +#endif + + +#if defined(_M_ARM64) \ + || defined(__AARCH64EL__) \ + || defined(__AARCH64EB__) \ + || defined(__aarch64__) + #define MY_CPU_ARM64 + #define MY_CPU_NAME "arm64" + #define MY_CPU_64BIT +#endif + + +#if defined(_M_ARM) \ + || defined(_M_ARM_NT) \ + || defined(_M_ARMT) \ + || defined(__arm__) \ + || defined(__thumb__) \ + || defined(__ARMEL__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEL__) \ + || defined(__THUMBEB__) + #define MY_CPU_ARM + #define MY_CPU_NAME "arm" + #define MY_CPU_32BIT +#endif + + +#if defined(_M_IA64) \ + || defined(__ia64__) + #define MY_CPU_IA64 + #define MY_CPU_NAME "ia64" + #define MY_CPU_64BIT +#endif + + +#if defined(__mips64) \ + || defined(__mips64__) \ + || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) + #define MY_CPU_NAME "mips64" + #define MY_CPU_64BIT +#elif defined(__mips__) + #define MY_CPU_NAME "mips" + /* #define MY_CPU_32BIT */ +#endif + + +#if defined(__ppc64__) \ + || defined(__powerpc64__) + #ifdef __ILP32__ + #define MY_CPU_NAME "ppc64-32" + #else + #define MY_CPU_NAME "ppc64" + #endif + #define MY_CPU_64BIT +#elif defined(__ppc__) \ + || defined(__powerpc__) + #define MY_CPU_NAME "ppc" + #define MY_CPU_32BIT +#endif + + +#if defined(__sparc64__) + #define MY_CPU_NAME "sparc64" + #define MY_CPU_64BIT +#elif defined(__sparc__) + #define MY_CPU_NAME "sparc" + /* #define MY_CPU_32BIT */ +#endif + + +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) +#define MY_CPU_X86_OR_AMD64 +#endif + + +#ifdef _WIN32 + + #ifdef MY_CPU_ARM + #define MY_CPU_ARM_LE + #endif + + #ifdef MY_CPU_ARM64 + #define MY_CPU_ARM64_LE + #endif + + #ifdef _M_IA64 + #define MY_CPU_IA64_LE + #endif + +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_LE) \ + || defined(MY_CPU_ARM64_LE) \ + || defined(MY_CPU_IA64_LE) \ + || defined(__LITTLE_ENDIAN__) \ + || defined(__ARMEL__) \ + || defined(__THUMBEL__) \ + || defined(__AARCH64EL__) \ + || defined(__MIPSEL__) \ + || defined(__MIPSEL) \ + || defined(_MIPSEL) \ + || defined(__BFIN__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + #define MY_CPU_LE +#endif + +#if defined(__BIG_ENDIAN__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEB__) \ + || defined(__AARCH64EB__) \ + || defined(__MIPSEB__) \ + || defined(__MIPSEB) \ + || defined(_MIPSEB) \ + || defined(__m68k__) \ + || defined(__s390__) \ + || defined(__s390x__) \ + || defined(__zarch__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + #define MY_CPU_BE +#endif + + +#if defined(MY_CPU_LE) && defined(MY_CPU_BE) + #error Stop_Compiling_Bad_Endian +#endif + + +#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) + #error Stop_Compiling_Bad_32_64_BIT +#endif + + +#ifndef MY_CPU_NAME + #ifdef MY_CPU_LE + #define MY_CPU_NAME "LE" + #elif defined(MY_CPU_BE) + #define MY_CPU_NAME "BE" + #else + /* + #define MY_CPU_NAME "" + */ + #endif +#endif + + + + + +#ifdef MY_CPU_LE + #if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM64) \ + || defined(__ARM_FEATURE_UNALIGNED) + #define MY_CPU_LE_UNALIGN + #endif +#endif + + +#ifdef MY_CPU_LE_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) +#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) + +#define SetUi16(p, v) { *(UInt16 *)(p) = (v); } +#define SetUi32(p, v) { *(UInt32 *)(p) = (v); } +#define SetUi64(p, v) { *(UInt64 *)(p) = (v); } + +#else + +#define GetUi16(p) ( (UInt16) ( \ + ((const Byte *)(p))[0] | \ + ((UInt16)((const Byte *)(p))[1] << 8) )) + +#define GetUi32(p) ( \ + ((const Byte *)(p))[0] | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((UInt32)((const Byte *)(p))[2] << 16) | \ + ((UInt32)((const Byte *)(p))[3] << 24)) + +#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) + +#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); } + +#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); \ + _ppp_[2] = (Byte)(_vvv_ >> 16); \ + _ppp_[3] = (Byte)(_vvv_ >> 24); } + +#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ + SetUi32(_ppp2_ , (UInt32)_vvv2_); \ + SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } + +#endif + +#ifdef __has_builtin + #define MY__has_builtin(x) __has_builtin(x) +#else + #define MY__has_builtin(x) 0 +#endif + +#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) + +/* Note: we use bswap instruction, that is unsupported in 386 cpu */ + +#include + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */ +#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) +#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) + +#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) + +#elif defined(MY_CPU_LE_UNALIGN) && ( \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) ) + +/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */ +#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) +#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) + +#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) + +#else + +#define GetBe32(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 24) | \ + ((UInt32)((const Byte *)(p))[1] << 16) | \ + ((UInt32)((const Byte *)(p))[2] << 8) | \ + ((const Byte *)(p))[3] ) + +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) + +#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 24); \ + _ppp_[1] = (Byte)(_vvv_ >> 16); \ + _ppp_[2] = (Byte)(_vvv_ >> 8); \ + _ppp_[3] = (Byte)_vvv_; } + +#endif + + +#ifndef GetBe16 + +#define GetBe16(p) ( (UInt16) ( \ + ((UInt16)((const Byte *)(p))[0] << 8) | \ + ((const Byte *)(p))[1] )) + +#endif + + + +#ifdef MY_CPU_X86_OR_AMD64 + +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; + +void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); + +BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p); +int x86cpuid_GetFirm(const Cx86cpuid *p); + +#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) +#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF)) +#define x86cpuid_GetStepping(ver) (ver & 0xF) + +BoolInt CPU_Is_InOrder(); +BoolInt CPU_Is_Aes_Supported(); +BoolInt CPU_IsSupported_PageGB(); + +#endif + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Delta.c b/components/ota/common/lzma/3rdparty/Delta.c new file mode 100644 index 00000000..e3edd21e --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Delta.c @@ -0,0 +1,64 @@ +/* Delta.c -- Delta converter +2009-05-26 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Delta.h" + +void Delta_Init(Byte *state) +{ + unsigned i; + for (i = 0; i < DELTA_STATE_SIZE; i++) + state[i] = 0; +} + +static void MyMemCpy(Byte *dest, const Byte *src, unsigned size) +{ + unsigned i; + for (i = 0; i < size; i++) + dest[i] = src[i]; +} + +void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) +{ + Byte buf[DELTA_STATE_SIZE]; + unsigned j = 0; + MyMemCpy(buf, state, delta); + { + SizeT i; + for (i = 0; i < size;) + { + for (j = 0; j < delta && i < size; i++, j++) + { + Byte b = data[i]; + data[i] = (Byte)(b - buf[j]); + buf[j] = b; + } + } + } + if (j == delta) + j = 0; + MyMemCpy(state, buf + j, delta - j); + MyMemCpy(state + delta - j, buf, j); +} + +void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) +{ + Byte buf[DELTA_STATE_SIZE]; + unsigned j = 0; + MyMemCpy(buf, state, delta); + { + SizeT i; + for (i = 0; i < size;) + { + for (j = 0; j < delta && i < size; i++, j++) + { + buf[j] = data[i] = (Byte)(buf[j] + data[i]); + } + } + } + if (j == delta) + j = 0; + MyMemCpy(state, buf + j, delta - j); + MyMemCpy(state + delta - j, buf, j); +} diff --git a/components/ota/common/lzma/3rdparty/Delta.h b/components/ota/common/lzma/3rdparty/Delta.h new file mode 100644 index 00000000..2fa54ad6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Delta.h @@ -0,0 +1,19 @@ +/* Delta.h -- Delta converter +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __DELTA_H +#define __DELTA_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define DELTA_STATE_SIZE 256 + +void Delta_Init(Byte *state); +void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); +void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/DllSecur.c b/components/ota/common/lzma/3rdparty/DllSecur.c new file mode 100644 index 00000000..5ea108ab --- /dev/null +++ b/components/ota/common/lzma/3rdparty/DllSecur.c @@ -0,0 +1,108 @@ +/* DllSecur.c -- DLL loading security +2018-02-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 + +#include + +#include "DllSecur.h" + +#ifndef UNDER_CE + +typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags); + +#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400 +#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 + +static const char * const g_Dlls = + #ifndef _CONSOLE + "UXTHEME\0" + #endif + "USERENV\0" + "SETUPAPI\0" + "APPHELP\0" + "PROPSYS\0" + "DWMAPI\0" + "CRYPTBASE\0" + "OLEACC\0" + "CLBCATQ\0" + "VERSION\0" + ; + +#endif + +void My_SetDefaultDllDirectories() +{ + #ifndef UNDER_CE + + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + GetVersionEx(&vi); + if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) + { + Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) + GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); + if (setDllDirs) + if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) + return; + } + + #endif +} + + +void LoadSecurityDlls() +{ + #ifndef UNDER_CE + + wchar_t buf[MAX_PATH + 100]; + + { + // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) + { + Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) + GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); + if (setDllDirs) + if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) + return; + } + } + + { + unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2); + if (len == 0 || len > MAX_PATH) + return; + } + { + const char *dll; + unsigned pos = (unsigned)lstrlenW(buf); + + if (buf[pos - 1] != '\\') + buf[pos++] = '\\'; + + for (dll = g_Dlls; dll[0] != 0;) + { + unsigned k = 0; + for (;;) + { + char c = *dll++; + buf[pos + k] = (Byte)c; + k++; + if (c == 0) + break; + } + + lstrcatW(buf, L".dll"); + LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + } + } + + #endif +} + +#endif diff --git a/components/ota/common/lzma/3rdparty/DllSecur.h b/components/ota/common/lzma/3rdparty/DllSecur.h new file mode 100644 index 00000000..e2a049ad --- /dev/null +++ b/components/ota/common/lzma/3rdparty/DllSecur.h @@ -0,0 +1,20 @@ +/* DllSecur.h -- DLL loading for security +2018-02-19 : Igor Pavlov : Public domain */ + +#ifndef __DLL_SECUR_H +#define __DLL_SECUR_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#ifdef _WIN32 + +void My_SetDefaultDllDirectories(); +void LoadSecurityDlls(); + +#endif + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/LzFind.c b/components/ota/common/lzma/3rdparty/LzFind.c new file mode 100644 index 00000000..df55e86c --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzFind.c @@ -0,0 +1,1127 @@ +/* LzFind.c -- Match finder for LZ algorithms +2018-07-08 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "LzFind.h" +#include "LzHash.h" + +#define kEmptyHashValue 0 +#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ +#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1)) +#define kMaxHistorySize ((UInt32)7 << 29) + +#define kStartMaxLen 3 + +static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) +{ + if (!p->directInput) + { + ISzAlloc_Free(alloc, p->bufferBase); + p->bufferBase = NULL; + } +} + +/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ + +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc) +{ + UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; + if (p->directInput) + { + p->blockSize = blockSize; + return 1; + } + if (!p->bufferBase || p->blockSize != blockSize) + { + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize); + } + return (p->bufferBase != NULL); +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } + +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ + p->posLimit -= subValue; + p->pos -= subValue; + p->streamPos -= subValue; +} + +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + + /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */ + + if (p->directInput) + { + UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos); + if (curSize > p->directInputRem) + curSize = (UInt32)p->directInputRem; + p->directInputRem -= curSize; + p->streamPos += curSize; + if (p->directInputRem == 0) + p->streamEndWasReached = 1; + return; + } + + for (;;) + { + Byte *dest = p->buffer + (p->streamPos - p->pos); + size_t size = (p->bufferBase + p->blockSize - dest); + if (size == 0) + return; + + p->result = ISeqInStream_Read(p->stream, dest, &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (p->streamPos - p->pos > p->keepSizeAfter) + return; + } +} + +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + memmove(p->bufferBase, + p->buffer - p->keepSizeBefore, + (size_t)(p->streamPos - p->pos) + p->keepSizeBefore); + p->buffer = p->bufferBase + p->keepSizeBefore; +} + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + if (p->directInput) + return 0; + /* if (p->streamEndWasReached) return 0; */ + return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->streamEndWasReached) + return; + if (p->keepSizeAfter >= p->streamPos - p->pos) + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +{ + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + unsigned i; + p->bufferBase = NULL; + p->directInput = 0; + p->hash = NULL; + p->expectedDataSize = (UInt64)(Int64)-1; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = (UInt32)i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + p->crc[i] = r; + } +} + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->hash); + p->hash = NULL; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) +{ + size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return NULL; + return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); +} + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAllocPtr alloc) +{ + UInt32 sizeReserv; + + if (historySize > kMaxHistorySize) + { + MatchFinder_Free(p, alloc); + return 0; + } + + sizeReserv = historySize >> 1; + if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3; + else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2; + + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); + + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; + + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ + + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + UInt32 newCyclicBufferSize = historySize + 1; + UInt32 hs; + p->matchMaxLen = matchMaxLen; + { + p->fixedHashSize = 0; + if (p->numHashBytes == 2) + hs = (1 << 16) - 1; + else + { + hs = historySize; + if (hs > p->expectedDataSize) + hs = (UInt32)p->expectedDataSize; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; /* don't change it! It's required for Deflate */ + if (hs > (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + } + p->hashMask = hs; + hs++; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + hs += p->fixedHashSize; + } + + { + size_t newSize; + size_t numSons; + p->historySize = historySize; + p->hashSizeSum = hs; + p->cyclicBufferSize = newCyclicBufferSize; + + numSons = newCyclicBufferSize; + if (p->btMode) + numSons <<= 1; + newSize = hs + numSons; + + if (p->hash && p->numRefs == newSize) + return 1; + + MatchFinder_FreeThisClassMemory(p, alloc); + p->numRefs = newSize; + p->hash = AllocRefs(newSize, alloc); + + if (p->hash) + { + p->son = p->hash + p->hashSizeSum; + return 1; + } + } + } + + MatchFinder_Free(p, alloc); + return 0; +} + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 limit = kMaxValForNormalize - p->pos; + UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; + + if (limit2 < limit) + limit = limit2; + limit2 = p->streamPos - p->pos; + + if (limit2 <= p->keepSizeAfter) + { + if (limit2 > 0) + limit2 = 1; + } + else + limit2 -= p->keepSizeAfter; + + if (limit2 < limit) + limit = limit2; + + { + UInt32 lenLimit = p->streamPos - p->pos; + if (lenLimit > p->matchMaxLen) + lenLimit = p->matchMaxLen; + p->lenLimit = lenLimit; + } + p->posLimit = p->pos + limit; +} + + +void MatchFinder_Init_LowHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash; + size_t numItems = p->fixedHashSize; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_HighHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash + p->fixedHashSize; + size_t numItems = (size_t)p->hashMask + 1; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_3(CMatchFinder *p, int readData) +{ + p->cyclicBufferPos = 0; + p->buffer = p->bufferBase; + p->pos = + p->streamPos = p->cyclicBufferSize; + p->result = SZ_OK; + p->streamEndWasReached = 0; + + if (readData) + MatchFinder_ReadBlock(p); + + MatchFinder_SetLimits(p); +} + + +void MatchFinder_Init(CMatchFinder *p) +{ + MatchFinder_Init_HighHash(p); + MatchFinder_Init_LowHash(p); + MatchFinder_Init_3(p, True); +} + + +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +{ + return (p->pos - p->historySize - 1) & kNormalizeMask; +} + +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) +{ + size_t i; + for (i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } +} + +static void MatchFinder_Normalize(CMatchFinder *p) +{ + UInt32 subValue = MatchFinder_GetSubValue(p); + MatchFinder_Normalize3(subValue, p->hash, p->numRefs); + MatchFinder_ReduceOffsets(p, subValue); +} + + +MY_NO_INLINE +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (p->pos == kMaxValForNormalize) + MatchFinder_Normalize(p); + if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) + MatchFinder_CheckAndMoveAndRead(p); + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + MatchFinder_SetLimits(p); +} + + +/* + (lenLimit > maxLen) +*/ +MY_FORCE_INLINE +static UInt32 * Hc_GetMatchesSpec(unsigned lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, unsigned maxLen) +{ + /* + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return distances; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = len; + *distances++ = len; + *distances++ = delta - 1; + if (len == lenLimit) + return distances; + } + } + } + } + */ + + const Byte *lim = cur + lenLimit; + son[_cyclicBufferPos] = curMatch; + do + { + UInt32 delta = pos - curMatch; + if (delta >= _cyclicBufferSize) + break; + { + ptrdiff_t diff; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + diff = (ptrdiff_t)0 - delta; + if (cur[maxLen] == cur[maxLen + diff]) + { + const Byte *c = cur; + while (*c == c[diff]) + { + if (++c == lim) + { + distances[0] = (UInt32)(lim - cur); + distances[1] = delta - 1; + return distances + 2; + } + } + { + unsigned len = (unsigned)(c - cur); + if (maxLen < len) + { + maxLen = len; + distances[0] = (UInt32)len; + distances[1] = delta - 1; + distances += 2; + } + } + } + } + } + while (--cutValue); + + return distances; +} + + +MY_FORCE_INLINE +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return distances; + } + { + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + UInt32 pair0 = pair[0]; + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = (UInt32)len; + *distances++ = (UInt32)len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair0; + *ptr0 = pair[1]; + return distances; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return; + } + { + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +#define MOVE_POS \ + ++p->cyclicBufferPos; \ + p->buffer++; \ + if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + +#define MOVE_POS_RET MOVE_POS return (UInt32)offset; + +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \ + lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define GET_MATCHES_FOOTER(offset, maxLen) \ + offset = (unsigned)(GetMatchesSpec1((UInt32)lenLimit, curMatch, MF_PARAMS(p), \ + distances + offset, (UInt32)maxLen) - distances); MOVE_POS_RET; + +#define SKIP_FOOTER \ + SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; + +#define UPDATE_maxLen { \ + ptrdiff_t diff = (ptrdiff_t)0 - d2; \ + const Byte *c = cur + maxLen; \ + const Byte *lim = cur + lenLimit; \ + for (; c != lim; c++) if (*(c + diff) != *c) break; \ + maxLen = (unsigned)(c - cur); } + +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + unsigned offset; + GET_MATCHES_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 1) +} + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + unsigned offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 2) +} + +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 h2, d2, pos; + unsigned maxLen, offset; + UInt32 *hash; + GET_MATCHES_HEADER(3) + + HASH3_CALC; + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash[h2]; + + curMatch = (hash + kFix3HashSize)[hv]; + + hash[h2] = pos; + (hash + kFix3HashSize)[hv] = pos; + + maxLen = 2; + offset = 0; + + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) + { + UPDATE_maxLen + distances[0] = (UInt32)maxLen; + distances[1] = d2 - 1; + offset = 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen, offset; + UInt32 *hash; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + + curMatch = (hash + kFix4HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + maxLen = 0; + offset = 0; + + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) + { + maxLen = 2; + distances[0] = 2; + distances[1] = d2 - 1; + offset = 2; + } + + if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + maxLen = 3; + distances[(size_t)offset + 1] = d3 - 1; + offset += 2; + d2 = d3; + } + + if (offset != 0) + { + UPDATE_maxLen + distances[(size_t)offset - 2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + + if (maxLen < 3) + maxLen = 3; + + GET_MATCHES_FOOTER(offset, maxLen) +} + +/* +static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos; + UInt32 *hash; + GET_MATCHES_HEADER(5) + + HASH5_CALC; + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + d4 = pos - (hash + kFix4HashSize)[h4]; + + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + maxLen = 0; + offset = 0; + + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = d2 - 1; + offset = 2; + if (*(cur - d2 + 2) == cur[2]) + distances[0] = maxLen = 3; + else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + distances[2] = maxLen = 3; + distances[3] = d3 - 1; + offset = 4; + d2 = d3; + } + } + else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + distances[0] = maxLen = 3; + distances[1] = d3 - 1; + offset = 2; + d2 = d3; + } + + if (d2 != d4 && d4 < p->cyclicBufferSize + && *(cur - d4) == *cur + && *(cur - d4 + 3) == *(cur + 3)) + { + maxLen = 4; + distances[(size_t)offset + 1] = d4 - 1; + offset += 2; + d2 = d4; + } + + if (offset != 0) + { + UPDATE_maxLen + distances[(size_t)offset - 2] = maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + + if (maxLen < 4) + maxLen = 4; + + GET_MATCHES_FOOTER(offset, maxLen) +} +*/ + +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen, offset; + UInt32 *hash; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + curMatch = (hash + kFix4HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + maxLen = 0; + offset = 0; + + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) + { + maxLen = 2; + distances[0] = 2; + distances[1] = d2 - 1; + offset = 2; + } + + if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + maxLen = 3; + distances[(size_t)offset + 1] = d3 - 1; + offset += 2; + d2 = d3; + } + + if (offset != 0) + { + UPDATE_maxLen + distances[(size_t)offset - 2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + + if (maxLen < 3) + maxLen = 3; + + offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} + +/* +static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos + UInt32 *hash; + GET_MATCHES_HEADER(5) + + HASH5_CALC; + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + d4 = pos - (hash + kFix4HashSize)[h4]; + + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + maxLen = 0; + offset = 0; + + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = d2 - 1; + offset = 2; + if (*(cur - d2 + 2) == cur[2]) + distances[0] = maxLen = 3; + else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + distances[2] = maxLen = 3; + distances[3] = d3 - 1; + offset = 4; + d2 = d3; + } + } + else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) + { + distances[0] = maxLen = 3; + distances[1] = d3 - 1; + offset = 2; + d2 = d3; + } + + if (d2 != d4 && d4 < p->cyclicBufferSize + && *(cur - d4) == *cur + && *(cur - d4 + 3) == *(cur + 3)) + { + maxLen = 4; + distances[(size_t)offset + 1] = d4 - 1; + offset += 2; + d2 = d4; + } + + if (offset != 0) + { + UPDATE_maxLen + distances[(size_t)offset - 2] = maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + + if (maxLen < 4) + maxLen = 4; + + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} +*/ + +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + unsigned offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances, 2) - (distances)); + MOVE_POS_RET +} + +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 h2; + UInt32 *hash; + SKIP_HEADER(3) + HASH3_CALC; + hash = p->hash; + curMatch = (hash + kFix3HashSize)[hv]; + hash[h2] = + (hash + kFix3HashSize)[hv] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 h2, h3; + UInt32 *hash; + SKIP_HEADER(4) + HASH4_CALC; + hash = p->hash; + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +/* +static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 h2, h3, h4; + UInt32 *hash; + SKIP_HEADER(5) + HASH5_CALC; + hash = p->hash; + curMatch = (hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} +*/ + +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 h2, h3; + UInt32 *hash; + SKIP_HEADER(4) + HASH4_CALC; + hash = p->hash; + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +/* +static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 h2, h3, h4; + UInt32 *hash; + SKIP_HEADER(5) + HASH5_CALC; + hash = p->hash; + curMatch = hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} +*/ + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinder_Init; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + /* if (p->numHashBytes <= 4) */ + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + } + /* + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip; + } + */ + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + } + else /* if (p->numHashBytes == 4) */ + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + } + /* + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip; + } + */ +} diff --git a/components/ota/common/lzma/3rdparty/LzFind.h b/components/ota/common/lzma/3rdparty/LzFind.h new file mode 100644 index 00000000..42c13be1 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzFind.h @@ -0,0 +1,121 @@ +/* LzFind.h -- Match finder for LZ algorithms +2017-06-10 : Igor Pavlov : Public domain */ + +#ifndef __LZ_FIND_H +#define __LZ_FIND_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef UInt32 CLzRef; + +typedef struct _CMatchFinder +{ + Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + Byte streamEndWasReached; + Byte btMode; + Byte bigHash; + Byte directInput; + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufferBase; + ISeqInStream *stream; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + size_t directInputRem; + UInt32 historySize; + UInt32 fixedHashSize; + UInt32 hashSizeSum; + SRes result; + UInt32 crc[256]; + size_t numRefs; + + UInt64 expectedDataSize; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) + +#define Inline_MatchFinder_IsFinishedOK(p) \ + ((p)->streamEndWasReached \ + && (p)->streamPos == (p)->pos \ + && (!(p)->directInput || (p)->directInputRem == 0)) + +int MatchFinder_NeedMove(CMatchFinder *p); +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* Conditions: + historySize <= 3 GB + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +*/ +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAllocPtr alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct _IMatchFinder +{ + Mf_Init_Func Init; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); + +void MatchFinder_Init_LowHash(CMatchFinder *p); +void MatchFinder_Init_HighHash(CMatchFinder *p); +void MatchFinder_Init_3(CMatchFinder *p, int readData); +void MatchFinder_Init(CMatchFinder *p); + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/LzHash.h b/components/ota/common/lzma/3rdparty/LzHash.h new file mode 100644 index 00000000..e7c94230 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzHash.h @@ -0,0 +1,57 @@ +/* LzHash.h -- HASH functions for LZ algorithms +2015-04-12 : Igor Pavlov : Public domain */ + +#ifndef __LZ_HASH_H +#define __LZ_HASH_H + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +#define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8); + +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + temp ^= (p->crc[cur[3]] << 5); \ + h4 = temp & (kHash4Size - 1); \ + hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; } + +/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +#define MT_HASH2_CALC \ + h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } + +#endif diff --git a/components/ota/common/lzma/3rdparty/Lzma2Dec.c b/components/ota/common/lzma/3rdparty/Lzma2Dec.c new file mode 100644 index 00000000..4e138a4a --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma2Dec.c @@ -0,0 +1,488 @@ +/* Lzma2Dec.c -- LZMA2 Decoder +2019-02-02 : Igor Pavlov : Public domain */ + +/* #define SHOW_DEBUG_INFO */ + +#include "Precomp.h" + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include + +#include "Lzma2Dec.h" + +/* +00000000 - End of data +00000001 U U - Uncompressed, reset dic, need reset state and set new prop +00000010 U U - Uncompressed, no reset +100uuuuu U U P P - LZMA, no reset +101uuuuu U U P P - LZMA, reset state +110uuuuu U U P P S - LZMA, reset state + set new prop +111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic + + u, U - Unpack Size + P - Pack Size + S - Props +*/ + +#define LZMA2_CONTROL_COPY_RESET_DIC 1 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +typedef enum +{ + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) +{ + UInt32 dicSize; + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (Byte)LZMA2_LCLP_MAX; + props[1] = (Byte)(dicSize); + props[2] = (Byte)(dicSize >> 8); + props[3] = (Byte)(dicSize >> 16); + props[4] = (Byte)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitLevel = 0xE0; + p->isExtraMode = False; + p->unpackSize = 0; + + // p->decoder.dicPos = 0; // we can use it instead of full init + LzmaDec_Init(&p->decoder); +} + +static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) +{ + switch (p->state) + { + case LZMA2_STATE_CONTROL: + p->isExtraMode = False; + p->control = b; + PRF(printf("\n %8X", (unsigned)p->decoder.dicPos)); + PRF(printf(" %02X", (unsigned)b)); + if (b == 0) + return LZMA2_STATE_FINISHED; + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (b == LZMA2_CONTROL_COPY_RESET_DIC) + p->needInitLevel = 0xC0; + else if (b > 2 || p->needInitLevel == 0xE0) + return LZMA2_STATE_ERROR; + } + else + { + if (b < p->needInitLevel) + return LZMA2_STATE_ERROR; + p->needInitLevel = 0; + p->unpackSize = (UInt32)(b & 0x1F) << 16; + } + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (UInt32)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (UInt32)b; + p->unpackSize++; + PRF(printf(" %7u", (unsigned)p->unpackSize)); + return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (UInt32)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (UInt32)b; + p->packSize++; + // if (p->packSize < 5) return LZMA2_STATE_ERROR; + PRF(printf(" %5u", (unsigned)p->packSize)); + return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA; + + case LZMA2_STATE_PROP: + { + unsigned lc, lp; + if (b >= (9 * 5 * 5)) + return LZMA2_STATE_ERROR; + lc = b % 9; + b /= 9; + p->decoder.prop.pb = (Byte)(b / 5); + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) + return LZMA2_STATE_ERROR; + p->decoder.prop.lc = (Byte)lc; + p->decoder.prop.lp = (Byte)lp; + return LZMA2_STATE_DATA; + } + } + return LZMA2_STATE_ERROR; +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) + p->checkDicSize = p->prop.dicSize; + p->processedPos += (UInt32)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); + + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_ERROR) + { + SizeT dicPos; + + if (p->state == LZMA2_STATE_FINISHED) + { + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + + dicPos = p->decoder.dicPos; + + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) + break; + continue; + } + + { + SizeT inCur = inSize - *srcLen; + SizeT outCur = dicLimit - dicPos; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (outCur >= p->unpackSize) + { + outCur = (SizeT)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (inCur == 0) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) + { + BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + LzmaDec_InitDicAndState(&p->decoder, initDic, False); + } + + if (inCur > outCur) + inCur = outCur; + if (inCur == 0) + break; + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); + + src += inCur; + *srcLen += inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + SRes res; + + if (p->state == LZMA2_STATE_DATA) + { + BoolInt initDic = (p->control >= 0xE0); + BoolInt initState = (p->control >= 0xA0); + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->state = LZMA2_STATE_DATA_CONT; + } + + if (inCur > p->packSize) + inCur = (SizeT)p->packSize; + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + outCur = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outCur; + + if (res != 0) + break; + + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (p->packSize == 0) + break; + return SZ_OK; + } + + if (inCur == 0 && outCur == 0) + { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + || p->unpackSize != 0 + || p->packSize != 0) + break; + p->state = LZMA2_STATE_CONTROL; + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + } + } + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + p->state = LZMA2_STATE_ERROR; + return SZ_ERROR_DATA; +} + + + + +ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, + SizeT outSize, + const Byte *src, SizeT *srcLen, + int checkFinishBlock) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + + while (p->state != LZMA2_STATE_ERROR) + { + if (p->state == LZMA2_STATE_FINISHED) + return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK; + + if (outSize == 0 && !checkFinishBlock) + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + (*srcLen)++; + + p->state = Lzma2Dec_UpdateState(p, *src++); + + if (p->state == LZMA2_STATE_UNPACK0) + { + // if (p->decoder.dicPos != 0) + if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0) + return LZMA2_PARSE_STATUS_NEW_BLOCK; + // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; + } + + // The following code can be commented. + // It's not big problem, if we read additional input bytes. + // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state. + + if (outSize == 0 && p->state != LZMA2_STATE_FINISHED) + { + // checkFinishBlock is true. So we expect that block must be finished, + // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here + // break; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + } + + if (p->state == LZMA2_STATE_DATA) + return LZMA2_PARSE_STATUS_NEW_CHUNK; + + continue; + } + + if (outSize == 0) + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + + { + SizeT inCur = inSize - *srcLen; + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (inCur == 0) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + if (inCur > p->unpackSize) + inCur = p->unpackSize; + if (inCur > outSize) + inCur = outSize; + p->decoder.dicPos += inCur; + src += inCur; + *srcLen += inCur; + outSize -= inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + p->isExtraMode = True; + + if (inCur == 0) + { + if (p->packSize != 0) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + } + else if (p->state == LZMA2_STATE_DATA) + { + p->state = LZMA2_STATE_DATA_CONT; + if (*src != 0) + { + // first byte of lzma chunk must be Zero + *srcLen += 1; + p->packSize--; + break; + } + } + + if (inCur > p->packSize) + inCur = (SizeT)p->packSize; + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + + if (p->packSize == 0) + { + SizeT rem = outSize; + if (rem > p->unpackSize) + rem = p->unpackSize; + p->decoder.dicPos += rem; + p->unpackSize -= (UInt32)rem; + outSize -= rem; + if (p->unpackSize == 0) + p->state = LZMA2_STATE_CONTROL; + } + } + } + } + + p->state = LZMA2_STATE_ERROR; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; +} + + + + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + + for (;;) + { + SizeT inCur = inSize, outCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + + if (p->decoder.dicPos == p->decoder.dicBufSize) + p->decoder.dicPos = 0; + dicPos = p->decoder.dicPos; + curFinishMode = LZMA_FINISH_ANY; + outCur = p->decoder.dicBufSize - dicPos; + + if (outCur >= outSize) + { + outCur = outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + inSize -= inCur; + *srcLen += inCur; + outCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outCur); + dest += outCur; + outSize -= outCur; + *destLen += outCur; + if (res != 0) + return res; + if (outCur == 0 || outSize == 0) + return SZ_OK; + } +} + + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) +{ + CLzma2Dec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + Lzma2Dec_Construct(&p); + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); + p.decoder.dic = dest; + p.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&p); + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + Lzma2Dec_FreeProbs(&p, alloc); + return res; +} diff --git a/components/ota/common/lzma/3rdparty/Lzma2Dec.h b/components/ota/common/lzma/3rdparty/Lzma2Dec.h new file mode 100644 index 00000000..b8ddeac8 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma2Dec.h @@ -0,0 +1,120 @@ +/* Lzma2Dec.h -- LZMA2 Decoder +2018-02-19 : Igor Pavlov : Public domain */ + +#ifndef __LZMA2_DEC_H +#define __LZMA2_DEC_H + +#include "LzmaDec.h" + +EXTERN_C_BEGIN + +/* ---------- State Interface ---------- */ + +typedef struct +{ + unsigned state; + Byte control; + Byte needInitLevel; + Byte isExtraMode; + Byte _pad_; + UInt32 packSize; + UInt32 unpackSize; + CLzmaDec decoder; +} CLzma2Dec; + +#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- LZMA2 block and chunk parsing ---------- */ + +/* +Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data. +It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code: + - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input. + - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read. + CLzma2Dec::unpackSize contains unpack size of that chunk +*/ + +typedef enum +{ +/* + LZMA_STATUS_NOT_SPECIFIED // data error + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED // + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused +*/ + LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1, + LZMA2_PARSE_STATUS_NEW_CHUNK +} ELzma2ParseStatus; + +ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, + SizeT outSize, // output size + const Byte *src, SizeT *srcLen, + int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position. + ); + +/* +LZMA2 parser doesn't decode LZMA chunks, so we must read + full input LZMA chunk to decode some part of LZMA chunk. + +Lzma2Dec_GetUnpackExtra() returns the value that shows + max possible number of output bytes that can be output by decoder + at current input positon. +*/ + +#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0); + + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Lzma2Enc.c b/components/ota/common/lzma/3rdparty/Lzma2Enc.c new file mode 100644 index 00000000..99a35240 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma2Enc.c @@ -0,0 +1,803 @@ +/* Lzma2Enc.c -- LZMA2 Encoder +2018-07-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#define _7ZIP_ST + +#include "Lzma2Enc.h" + +#ifndef _7ZIP_ST +#include "MtCoder.h" +#else +#define MTCODER__THREADS_MAX 1 +#endif + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_LCLP_MAX 4 + +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#define LZMA2_PACK_SIZE_MAX (1 << 16) +#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX +#define LZMA2_UNPACK_SIZE_MAX (1 << 21) +#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX + +#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16) + + +#define PRF(x) /* x */ + + +/* ---------- CLimitedSeqInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStream *realStream; + UInt64 limit; + UInt64 processed; + int finished; +} CLimitedSeqInStream; + +static void LimitedSeqInStream_Init(CLimitedSeqInStream *p) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->finished = 0; +} + +static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +{ + CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt); + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->finished = (size2 == 0 ? 1 : 0); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CLzma2EncInt ---------- */ + +typedef struct +{ + CLzmaEncHandle enc; + Byte propsAreSet; + Byte propsByte; + Byte needInitState; + Byte needInitProp; + UInt64 srcPos; +} CLzma2EncInt; + + +static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props) +{ + if (!p->propsAreSet) + { + SizeT propsSize = LZMA_PROPS_SIZE; + Byte propsEncoded[LZMA_PROPS_SIZE]; + RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)); + RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)); + p->propsByte = propsEncoded[0]; + p->propsAreSet = True; + } + return SZ_OK; +} + +static void Lzma2EncInt_InitBlock(CLzma2EncInt *p) +{ + p->srcPos = 0; + p->needInitState = True; + p->needInitProp = True; +} + + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); +void LzmaEnc_Finish(CLzmaEncHandle pp); +void LzmaEnc_SaveState(CLzmaEncHandle pp); +void LzmaEnc_RestoreState(CLzmaEncHandle pp); + +/* +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp); +*/ + +static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, + size_t *packSizeRes, ISeqOutStream *outStream) +{ + size_t packSizeLimit = *packSizeRes; + size_t packSize = packSizeLimit; + UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; + unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); + BoolInt useCopyBlock; + SRes res; + + *packSizeRes = 0; + if (packSize < lzHeaderSize) + return SZ_ERROR_OUTPUT_EOF; + packSize -= lzHeaderSize; + + LzmaEnc_SaveState(p->enc); + res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, + outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); + + PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); + + if (unpackSize == 0) + return res; + + if (res == SZ_OK) + useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16)); + else + { + if (res != SZ_ERROR_OUTPUT_EOF) + return res; + res = SZ_OK; + useCopyBlock = True; + } + + if (useCopyBlock) + { + size_t destPos = 0; + PRF(printf("################# COPY ")); + + while (unpackSize > 0) + { + UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; + if (packSizeLimit - destPos < u + 3) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); + outBuf[destPos++] = (Byte)((u - 1) >> 8); + outBuf[destPos++] = (Byte)(u - 1); + memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u); + unpackSize -= u; + destPos += u; + p->srcPos += u; + + if (outStream) + { + *packSizeRes += destPos; + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + destPos = 0; + } + else + *packSizeRes = destPos; + /* needInitState = True; */ + } + + LzmaEnc_RestoreState(p->enc); + return SZ_OK; + } + + { + size_t destPos = 0; + UInt32 u = unpackSize - 1; + UInt32 pm = (UInt32)(packSize - 1); + unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); + + PRF(printf(" ")); + + outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F)); + outBuf[destPos++] = (Byte)(u >> 8); + outBuf[destPos++] = (Byte)u; + outBuf[destPos++] = (Byte)(pm >> 8); + outBuf[destPos++] = (Byte)pm; + + if (p->needInitProp) + outBuf[destPos++] = p->propsByte; + + p->needInitProp = False; + p->needInitState = False; + destPos += packSize; + p->srcPos += unpackSize; + + if (outStream) + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + + *packSizeRes = destPos; + return SZ_OK; + } +} + + +/* ---------- Lzma2 Props ---------- */ + +void Lzma2EncProps_Init(CLzma2EncProps *p) +{ + LzmaEncProps_Init(&p->lzmaProps); + p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; +} + +void Lzma2EncProps_Normalize(CLzma2EncProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzmaEncProps lzmaProps = p->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + t1n = lzmaProps.numThreads; + } + + t1 = p->lzmaProps.numThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER__THREADS_MAX) + t2 = MTCODER__THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER__THREADS_MAX) + t2 = MTCODER__THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzmaProps.numThreads = t1; + + t2r = t2; + + fileSize = p->lzmaProps.reduceSize; + + if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + && p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO + && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzmaProps.reduceSize = p->blockSize; + + LzmaEncProps_Normalize(&p->lzmaProps); + + p->lzmaProps.reduceSize = fileSize; + + t1 = p->lzmaProps.numThreads; + + if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + { + t2r = t2 = 1; + t3 = t1; + } + else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1) + { + /* if there is no block multi-threading, we use SOLID block */ + p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID; + } + else + { + if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + { + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt32 dictSize = p->lzmaProps.dictSize; + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + p->blockSize = blockSize; + } + + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (unsigned)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) +{ + return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; +} + + +/* ---------- Lzma2 ---------- */ + +typedef struct +{ + Byte propEncoded; + CLzma2EncProps props; + UInt64 expectedDataSize; + + Byte *tempBufLzma; + + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CLzma2EncInt coders[MTCODER__THREADS_MAX]; + + #ifndef _7ZIP_ST + + ISeqOutStream *outStream; + Byte *outBuf; + size_t outBuf_Rem; /* remainder in outBuf */ + + size_t outBufSize; /* size of allocated outBufs[i] */ + size_t outBufsDataSizes[MTCODER__BLOCKS_MAX]; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + Byte *outBufs[MTCODER__BLOCKS_MAX]; + + #endif + +} CLzma2Enc; + + + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc)); + if (!p) + return NULL; + Lzma2EncProps_Init(&p->props); + Lzma2EncProps_Normalize(&p->props); + p->expectedDataSize = (UInt64)(Int64)-1; + p->tempBufLzma = NULL; + p->alloc = alloc; + p->allocBig = allocBig; + { + unsigned i; + for (i = 0; i < MTCODER__THREADS_MAX; i++) + p->coders[i].enc = NULL; + } + + #ifndef _7ZIP_ST + p->mtCoder_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif + + return p; +} + + +#ifndef _7ZIP_ST + +static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p) +{ + unsigned i; + for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + +#endif + + +void Lzma2Enc_Destroy(CLzma2EncHandle pp) +{ + CLzma2Enc *p = (CLzma2Enc *)pp; + unsigned i; + for (i = 0; i < MTCODER__THREADS_MAX; i++) + { + CLzma2EncInt *t = &p->coders[i]; + if (t->enc) + { + LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); + t->enc = NULL; + } + } + + + #ifndef _7ZIP_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + Lzma2Enc_FreeOutBufs(p); + #endif + + ISzAlloc_Free(p->alloc, p->tempBufLzma); + p->tempBufLzma = NULL; + + ISzAlloc_Free(p->alloc, pp); +} + + +SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props) +{ + CLzma2Enc *p = (CLzma2Enc *)pp; + CLzmaEncProps lzmaProps = props->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) + return SZ_ERROR_PARAM; + p->props = *props; + Lzma2EncProps_Normalize(&p->props); + return SZ_OK; +} + + +void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +{ + CLzma2Enc *p = (CLzma2Enc *)pp; + p->expectedDataSize = expectedDataSiize; +} + + +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp) +{ + CLzma2Enc *p = (CLzma2Enc *)pp; + unsigned i; + UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); + for (i = 0; i < 40; i++) + if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i)) + break; + return (Byte)i; +} + + +static SRes Lzma2Enc_EncodeMt1( + CLzma2Enc *me, + CLzma2EncInt *p, + ISeqOutStream *outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStream *inStream, + const Byte *inData, size_t inDataSize, + int finished, + ICompressProgress *progress) +{ + UInt64 unpackTotal = 0; + UInt64 packTotal = 0; + size_t outLim = 0; + CLimitedSeqInStream limitedInStream; + + if (outBuf) + { + outLim = *outBufSize; + *outBufSize = 0; + } + + if (!p->enc) + { + p->propsAreSet = False; + p->enc = LzmaEnc_Create(me->alloc); + if (!p->enc) + return SZ_ERROR_MEM; + } + + limitedInStream.realStream = inStream; + if (inStream) + { + limitedInStream.vt.Read = LimitedSeqInStream_Read; + } + + if (!outBuf) + { + // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma + if (!me->tempBufLzma) + { + me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); + if (!me->tempBufLzma) + return SZ_ERROR_MEM; + } + } + + RINOK(Lzma2EncInt_InitStream(p, &me->props)); + + for (;;) + { + SRes res = SZ_OK; + size_t inSizeCur = 0; + + Lzma2EncInt_InitBlock(p); + + LimitedSeqInStream_Init(&limitedInStream); + limitedInStream.limit = me->props.blockSize; + + if (inStream) + { + UInt64 expected = (UInt64)(Int64)-1; + // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize + if (me->expectedDataSize != (UInt64)(Int64)-1 + && me->expectedDataSize >= unpackTotal) + expected = me->expectedDataSize - unpackTotal; + if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + && expected > me->props.blockSize) + expected = (size_t)me->props.blockSize; + + LzmaEnc_SetDataSize(p->enc, expected); + + RINOK(LzmaEnc_PrepareForLzma2(p->enc, + &limitedInStream.vt, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)); + } + else + { + inSizeCur = inDataSize - (size_t)unpackTotal; + if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + && inSizeCur > me->props.blockSize) + inSizeCur = (size_t)me->props.blockSize; + + // LzmaEnc_SetDataSize(p->enc, inSizeCur); + + RINOK(LzmaEnc_MemPrepare(p->enc, + inData + (size_t)unpackTotal, inSizeCur, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)); + } + + for (;;) + { + size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; + if (outBuf) + packSize = outLim - (size_t)packTotal; + + res = Lzma2EncInt_EncodeSubblock(p, + outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize, + outBuf ? NULL : outStream); + + if (res != SZ_OK) + break; + + packTotal += packSize; + if (outBuf) + *outBufSize = (size_t)packTotal; + + res = Progress(progress, unpackTotal + p->srcPos, packTotal); + if (res != SZ_OK) + break; + + /* + if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0) + break; + */ + + if (packSize == 0) + break; + } + + LzmaEnc_Finish(p->enc); + + unpackTotal += p->srcPos; + + RINOK(res); + + if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur)) + return SZ_ERROR_FAIL; + + if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize)) + { + if (finished) + { + if (outBuf) + { + size_t destPos = *outBufSize; + if (destPos >= outLim) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos] = 0; + *outBufSize = destPos + 1; + } + else + { + Byte b = 0; + if (ISeqOutStream_Write(outStream, &b, 1) != 1) + return SZ_ERROR_WRITE; + } + } + return SZ_OK; + } + } +} + + + +#ifndef _7ZIP_ST + +static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CLzma2Enc *me = (CLzma2Enc *)pp; + size_t destSize = me->outBufSize; + SRes res; + CMtProgressThunk progressThunk; + + Byte *dest = me->outBufs[outBufIndex]; + + me->outBufsDataSizes[outBufIndex] = 0; + + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + progressThunk.inSize = 0; + progressThunk.outSize = 0; + + res = Lzma2Enc_EncodeMt1(me, + &me->coders[coderIndex], + NULL, dest, &destSize, + NULL, src, srcSize, + finished, + &progressThunk.vt); + + me->outBufsDataSizes[outBufIndex] = destSize; + + return res; +} + + +static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex) +{ + CLzma2Enc *me = (CLzma2Enc *)pp; + size_t size = me->outBufsDataSizes[outBufIndex]; + const Byte *data = me->outBufs[outBufIndex]; + + if (me->outStream) + return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE; + + if (size > me->outBuf_Rem) + return SZ_ERROR_OUTPUT_EOF; + memcpy(me->outBuf, data, size); + me->outBuf_Rem -= size; + me->outBuf += size; + return SZ_OK; +} + +#endif + + + +SRes Lzma2Enc_Encode2(CLzma2EncHandle pp, + ISeqOutStream *outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStream *inStream, + const Byte *inData, size_t inDataSize, + ICompressProgress *progress) +{ + CLzma2Enc *p = (CLzma2Enc *)pp; + + if (inStream && inData) + return SZ_ERROR_PARAM; + + if (outStream && outBuf) + return SZ_ERROR_PARAM; + + { + unsigned i; + for (i = 0; i < MTCODER__THREADS_MAX; i++) + p->coders[i].propsAreSet = False; + } + + #ifndef _7ZIP_ST + + if (p->props.numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = Lzma2Enc_MtCallback_Code; + vt.Write = Lzma2Enc_MtCallback_Write; + + p->outStream = outStream; + p->outBuf = NULL; + p->outBuf_Rem = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBuf_Rem = *outBufSize; + *outBufSize = 0; + } + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = inData; + p->mtCoder.inDataSize = inDataSize; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + p->mtCoder.blockSize = (size_t)p->props.blockSize; + if (p->mtCoder.blockSize != p->props.blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16; + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + Lzma2Enc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = p->props.numBlockThreads_Max; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + { + SRes res = MtCoder_Code(&p->mtCoder); + if (!outStream) + *outBufSize = p->outBuf - outBuf; + return res; + } + } + + #endif + + + return Lzma2Enc_EncodeMt1(p, + &p->coders[0], + outStream, outBuf, outBufSize, + inStream, inData, inDataSize, + True, /* finished */ + progress); +} diff --git a/components/ota/common/lzma/3rdparty/Lzma2Enc.h b/components/ota/common/lzma/3rdparty/Lzma2Enc.h new file mode 100644 index 00000000..6a6110ff --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma2Enc.h @@ -0,0 +1,55 @@ +/* Lzma2Enc.h -- LZMA2 Encoder +2017-07-27 : Igor Pavlov : Public domain */ + +#ifndef __LZMA2_ENC_H +#define __LZMA2_ENC_H + +#include "LzmaEnc.h" + +EXTERN_C_BEGIN + +#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0 +#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1) + +typedef struct +{ + CLzmaEncProps lzmaProps; + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; +} CLzma2EncProps; + +void Lzma2EncProps_Init(CLzma2EncProps *p); +void Lzma2EncProps_Normalize(CLzma2EncProps *p); + +/* ---------- CLzmaEnc2Handle Interface ---------- */ + +/* Lzma2Enc_* functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef void * CLzma2EncHandle; + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void Lzma2Enc_Destroy(CLzma2EncHandle p); +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize); +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStream *outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStream *inStream, + const Byte *inData, size_t inDataSize, + ICompressProgress *progress); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Lzma86.h b/components/ota/common/lzma/3rdparty/Lzma86.h new file mode 100644 index 00000000..bebed5cb --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma86.h @@ -0,0 +1,111 @@ +/* Lzma86.h -- LZMA + x86 (BCJ) Filter +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __LZMA86_H +#define __LZMA86_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define LZMA86_SIZE_OFFSET (1 + 5) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +/* +It's an example for LZMA + x86 Filter use. +You can use .lzma86 extension, if you write that stream to file. +.lzma86 header adds one additional byte to standard .lzma header. +.lzma86 header (14 bytes): + Offset Size Description + 0 1 = 0 - no filter, pure LZMA + = 1 - x86 filter + LZMA + 1 1 lc, lp and pb in encoded form + 2 4 dictSize (little endian) + 6 8 uncompressed size (little endian) + + +Lzma86_Encode +------------- +level - compression level: 0 <= level <= 9, the default value for "level" is 5. + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes, for level = 5. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + For better compression ratio dictSize must be >= inSize. + +filterMode: + SZ_FILTER_NO - no Filter + SZ_FILTER_YES - x86 Filter + SZ_FILTER_AUTO - it tries both alternatives to select best. + Encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. + +Lzma86Encode allocates Data with MyAlloc functions. +RAM Requirements for compressing: + RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize + filterMode FilterBlockSize + SZ_FILTER_NO 0 + SZ_FILTER_YES inSize + SZ_FILTER_AUTO inSize + + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode); + + +/* +Lzma86_GetUnpackSize: + In: + src - input data + srcLen - input data size + Out: + unpackSize - size of uncompressed stream + Return code: + SZ_OK - OK + SZ_ERROR_INPUT_EOF - Error in headers +*/ + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); + +/* +Lzma86_Decode: + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + Out: + destLen - processed output size + srcLen - processed input size + Return code: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - unsupported file + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer +*/ + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Lzma86Dec.c b/components/ota/common/lzma/3rdparty/Lzma86Dec.c new file mode 100644 index 00000000..21031745 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma86Dec.c @@ -0,0 +1,54 @@ +/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder +2016-05-16 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaDec.h" + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) +{ + unsigned i; + if (srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + *unpackSize = 0; + for (i = 0; i < sizeof(UInt64); i++) + *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); + return SZ_OK; +} + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SRes res; + int useFilter; + SizeT inSizePure; + ELzmaStatus status; + + if (*srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + + useFilter = src[0]; + + if (useFilter > 1) + { + *destLen = 0; + return SZ_ERROR_UNSUPPORTED; + } + + inSizePure = *srcLen - LZMA86_HEADER_SIZE; + res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, + src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); + *srcLen = inSizePure + LZMA86_HEADER_SIZE; + if (res != SZ_OK) + return res; + if (useFilter == 1) + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(dest, *destLen, 0, &x86State, 0); + } + return SZ_OK; +} diff --git a/components/ota/common/lzma/3rdparty/Lzma86Enc.c b/components/ota/common/lzma/3rdparty/Lzma86Enc.c new file mode 100644 index 00000000..2617bab8 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Lzma86Enc.c @@ -0,0 +1,106 @@ +/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder +2018-07-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaEnc.h" + +#define SZE_OUT_OVERFLOW SZE_DATA_ERROR + +int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode) +{ + size_t outSize2 = *destLen; + Byte *filteredStream; + BoolInt useFilter; + int mainResult = SZ_ERROR_OUTPUT_EOF; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + + *destLen = 0; + if (outSize2 < LZMA86_HEADER_SIZE) + return SZ_ERROR_OUTPUT_EOF; + + { + int i; + UInt64 t = srcLen; + for (i = 0; i < 8; i++, t >>= 8) + dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; + } + + filteredStream = 0; + useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (srcLen != 0) + { + filteredStream = (Byte *)MyAlloc(srcLen); + if (filteredStream == 0) + return SZ_ERROR_MEM; + memcpy(filteredStream, src, srcLen); + } + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(filteredStream, srcLen, 0, &x86State, 1); + } + } + + { + size_t minSize = 0; + BoolInt bestIsFiltered = False; + + /* passes for SZ_FILTER_AUTO: + 0 - BCJ + LZMA + 1 - LZMA + 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. + */ + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + + int i; + for (i = 0; i < numPasses; i++) + { + size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; + size_t outPropsSize = 5; + SRes curRes; + BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); + if (curModeIsFiltered && !bestIsFiltered) + break; + if (useFilter && i == 0) + curModeIsFiltered = True; + + curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, + curModeIsFiltered ? filteredStream : src, srcLen, + &props, dest + 1, &outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); + + if (curRes != SZ_ERROR_OUTPUT_EOF) + { + if (curRes != SZ_OK) + { + mainResult = curRes; + break; + } + if (outSizeProcessed <= minSize || mainResult != SZ_OK) + { + minSize = outSizeProcessed; + bestIsFiltered = curModeIsFiltered; + mainResult = SZ_OK; + } + } + } + dest[0] = (Byte)(bestIsFiltered ? 1 : 0); + *destLen = LZMA86_HEADER_SIZE + minSize; + } + if (useFilter) + MyFree(filteredStream); + return mainResult; +} diff --git a/components/ota/common/lzma/3rdparty/LzmaDec.c b/components/ota/common/lzma/3rdparty/LzmaDec.c new file mode 100644 index 00000000..ba3e1dd5 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaDec.c @@ -0,0 +1,1185 @@ +/* LzmaDec.c -- LZMA Decoder +2018-07-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #include "CpuArch.h" */ +#include "LzmaDec.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } + +#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } + +#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ + { UPDATE_0(p + i); A0; } else \ + { UPDATE_1(p + i); A1; } +#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) +#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) +#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) + +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) +#define MATCHED_LITER_DEC \ + matchByte += matchByte; \ + bit = offs; \ + offs &= matchByte; \ + probLit = prob + (offs + bit + symbol); \ + GET_BIT2(probLit, symbol, offs ^= bit; , ;) + + + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ + { UPDATE_0_CHECK; i += m; m += m; } else \ + { UPDATE_1_CHECK; m += m; i += m; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenLow 0 +#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +#define LenChoice LenLow +#define LenChoice2 (LenLow + (1 << kLenNumLowBits)) + +#define kNumStates 12 +#define kNumStates2 16 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +/* External ASM code needs same CLzmaProb array layout. So don't change it. */ + +/* (probs_1664) is faster and better for code size at some platforms */ +/* +#ifdef MY_CPU_X86_OR_AMD64 +*/ +#define kStartOffset 1664 +#define GET_PROBS p->probs_1664 +/* +#define GET_PROBS p->probs + kStartOffset +#else +#define kStartOffset 0 +#define GET_PROBS p->probs +#endif +*/ + +#define SpecPos (-kStartOffset) +#define IsRep0Long (SpecPos + kNumFullDistances) +#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) +#define LenCoder (RepLenCoder + kNumLenProbs) +#define IsMatch (LenCoder + kNumLenProbs) +#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax)) +#define IsRep (Align + kAlignTableSize) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define PosSlot (IsRepG2 + kNumStates) +#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define NUM_BASE_PROBS (Literal + kStartOffset) + +#if Align != 0 && kStartOffset != 0 + #error Stop_Compiling_Bad_LZMA_kAlign +#endif + +#if NUM_BASE_PROBS != 1984 + #error Stop_Compiling_Bad_LZMA_PROBS +#endif + + +#define LZMA_LIT_SIZE 0x300 + +#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + + +#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4) +#define COMBINED_PS_STATE (posState + state) +#define GET_LEN_STATE (posState) + +#define LZMA_DIC_MIN (1 << 12) + +/* +p->remainLen : shows status of LZMA decoder: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : need init range coder + = kMatchSpecLenStart + 2 : need init range coder and state +*/ + +/* ---------- LZMA_DECODE_REAL ---------- */ +/* +LzmaDec_DecodeReal_3() can be implemented in external ASM file. +3 - is the code compatibility version of that function for check at link time. +*/ + +#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3 + +/* +LZMA_DECODE_REAL() +In: + RangeCoder is normalized + if (p->dicPos == limit) + { + LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases. + So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol + is not END_OF_PAYALOAD_MARKER, then function returns error code. + } + +Processing: + first LZMA symbol will be decoded in any case + All checks for limits are at the end of main loop, + It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit), + RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked. + +Out: + RangeCoder is normalized + Result: + SZ_OK - OK + SZ_ERROR_DATA - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished +*/ + + +#ifdef _LZMA_DEC_OPT + +int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); + +#else + +static +int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lc = p->prop.lc; + unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(processedPos, pbMask); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (processedPos != 0 || checkDicSize != 0) + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); + processedPos++; + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + #ifdef _LZMA_SIZE_OPT + do { NORMAL_LITER_DEC } while (symbol < 0x100); + #else + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + #endif + } + else + { + unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + #ifdef _LZMA_SIZE_OPT + do + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + } + while (symbol < 0x100); + #else + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + } + #endif + } + + dic[dicPos++] = (Byte)symbol; + continue; + } + + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + /* + // that case was checked before with kBadRepCode + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + */ + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + + #ifdef _LZMA_SIZE_OPT + { + unsigned lim, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + lim = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, lim, len); + len += offset; + } + #else + { + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + GET_LEN_STATE; + len = 1; + TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len); + len -= 8; + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + len = 1; + TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + TREE_DECODE(probLen, (1 << kLenNumHighBits), len); + len += kLenNumLowSymbols * 2; + } + } + } + #endif + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos; + { + UInt32 m = 1; + distance++; + do + { + REV_BIT_VAR(prob, distance, m); + } + while (--numDirectBits); + distance -= m; + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + REV_BIT_CONST(prob, i, 1); + REV_BIT_CONST(prob, i, 2); + REV_BIT_CONST(prob, i, 4); + REV_BIT_LAST (prob, i, 8); + distance |= i; + } + if (distance == (UInt32)0xFFFFFFFF) + { + len = kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) + { + p->dicPos = dicPos; + return SZ_ERROR_DATA; + } + } + + len += kMatchMinLen; + + { + SizeT rem; + unsigned curLen; + SizeT pos; + + if ((rem = limit - dicPos) == 0) + { + p->dicPos = dicPos; + return SZ_ERROR_DATA; + } + + curLen = ((rem < len) ? (unsigned)rem : len); + pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + + processedPos += (UInt32)curLen; + + len -= curLen; + if (curLen <= dicBufSize - pos) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += (SizeT)curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + + NORMALIZE; + + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = (UInt32)len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = (UInt32)state; + + return SZ_OK; +} +#endif + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = (unsigned)p->remainLen; + SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ + SizeT rem = limit - dicPos; + if (rem < len) + len = (unsigned)(rem); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += (UInt32)len; + p->remainLen -= (UInt32)len; + while (len != 0) + { + len--; + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + + +#define kRange0 0xFFFFFFFF +#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)) +#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))) +#if kBadRepCode != (0xC0000000 - 0x400) + #error Stop_Compiling_Bad_LZMA_Check +#endif + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + + if (p->processedPos == 0) + if (p->code >= kBadRepCode) + return SZ_ERROR_DATA; + } + + RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit)); + + if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + const CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + ELzmaDummy res; + + { + const CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += ((UInt32)LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + const CLzmaProb *probLit; + matchByte += matchByte; + bit = offs; + offs &= matchByte; + probLit = prob + (offs + bit + symbol); + GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; ) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + const CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + unsigned numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits); + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + unsigned m = 1; + do + { + REV_BIT_CHECK(prob, i, m); + } + while (--numDirectBits); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState) +{ + p->remainLen = kMatchSpecLenStart + 1; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->remainLen = kMatchSpecLenStart + 2; + } + if (initState) + p->remainLen = kMatchSpecLenStart + 2; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + + *status = LZMA_STATUS_NOT_SPECIFIED; + + if (p->remainLen > kMatchSpecLenStart) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize != 0 && p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + p->code = + ((UInt32)p->tempBuf[1] << 24) + | ((UInt32)p->tempBuf[2] << 16) + | ((UInt32)p->tempBuf[3] << 8) + | ((UInt32)p->tempBuf[4]); + p->range = 0xFFFFFFFF; + p->tempBufSize = 0; + + if (p->remainLen > kMatchSpecLenStart + 1) + { + SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); + SizeT i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + } + + p->remainLen = 0; + } + + LzmaDec_WriteRem(p, dicLimit); + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow = 0; + + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = (SizeT)(p->buf - src); + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, (SizeT)rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += (SizeT)lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + + { + unsigned kkk = (unsigned)(p->buf - p->tempBuf); + if (rem < kkk) + return SZ_ERROR_FAIL; /* some internal error */ + rem -= kkk; + if (lookAhead < rem) + return SZ_ERROR_FAIL; /* some internal error */ + lookAhead -= rem; + } + (*srcLen) += (SizeT)lookAhead; + src += lookAhead; + inSize -= (SizeT)lookAhead; + p->tempBufSize = 0; + } + } + + if (p->code != 0) + return SZ_ERROR_DATA; + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; +} + + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->probs); + p->probs = NULL; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->dic); + p->dic = NULL; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = (Byte)(d % 9); + d /= 9; + p->pb = (Byte)(d / 5); + p->lp = (Byte)(d % 5); + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (!p->probs || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); + if (!p->probs) + return SZ_ERROR_MEM; + p->probs_1664 = p->probs + 1664; + p->numProbs = numProbs; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + + { + UInt32 dictSize = propNew.dicSize; + SizeT mask = ((UInt32)1 << 12) - 1; + if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; + dicBufSize = ((SizeT)dictSize + mask) & ~mask; + if (dicBufSize < dictSize) + dicBufSize = dictSize; + } + + if (!p->dic || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); + if (!p->dic) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAllocPtr alloc) +{ + CLzmaDec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + LzmaDec_Construct(&p); + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); + p.dic = dest; + p.dicBufSize = outSize; + LzmaDec_Init(&p); + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/components/ota/common/lzma/3rdparty/LzmaDec.h b/components/ota/common/lzma/3rdparty/LzmaDec.h new file mode 100644 index 00000000..1f0927ab --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaDec.h @@ -0,0 +1,234 @@ +/* LzmaDec.h -- LZMA Decoder +2018-04-21 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +typedef +#ifdef _LZMA_PROB32 + UInt32 +#else + UInt16 +#endif + CLzmaProb; + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + Byte lc; + Byte lp; + Byte pb; + Byte _pad_; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + /* Don't change this structure. ASM code can use it. */ + CLzmaProps prop; + CLzmaProb *probs; + CLzmaProb *probs_1664; + Byte *dic; + SizeT dicBufSize; + SizeT dicPos; + const Byte *buf; + UInt32 range; + UInt32 code; + UInt32 processedPos; + UInt32 checkDicSize; + UInt32 reps[4]; + UInt32 state; + UInt32 remainLen; + + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + - Stream with end mark. That end mark adds about 6 bytes to compressed size. + - Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Construct() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/LzmaEnc.c b/components/ota/common/lzma/3rdparty/LzmaEnc.c new file mode 100644 index 00000000..6bd3b27c --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaEnc.c @@ -0,0 +1,2978 @@ +/* LzmaEnc.c -- LZMA Encoder +2019-01-10: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#define _7ZIP_ST + +#if defined(SHOW_STAT) || defined(SHOW_STAT2) +#include +#endif + +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifndef _7ZIP_ST +#include "LzFindMt.h" +#endif + +#ifdef SHOW_STAT +static unsigned g_STAT_OFFSET = 0; +#endif + +#define kLzmaMaxHistorySize ((UInt32)3 << 29) +/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */ + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +#define REP_LEN_COUNT 64 + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->reduceSize = (UInt64)(Int64)-1; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26))); + if (p->dictSize > p->reduceSize) + { + unsigned i; + UInt32 reduceSize = (UInt32)p->reduceSize; + for (i = 11; i <= 30; i++) + { + if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } + if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } + } + } + + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); + + if (p->numThreads < 0) + p->numThreads = + #ifndef _7ZIP_ST + ((p->btMode && p->algo) ? 2 : 1); + #else + 1; + #endif +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +#if (_MSC_VER >= 1400) +/* BSR code is fast for some new CPUs */ +/* #define LZMA_LOG_BSR */ +#endif + +#ifdef LZMA_LOG_BSR + +#define kDicLogSizeMaxCompress 32 + +#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); } + +static unsigned GetPosSlot1(UInt32 pos) +{ + unsigned res; + BSR2_RET(pos, res); + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } + +#else + +#define kNumLogBits (9 + sizeof(size_t) / 2) +/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */ + +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +static void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + unsigned slot; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + g_FastPos += 2; + + for (slot = 2; slot < kNumLogBits * 2; slot++) + { + size_t k = ((size_t)1 << ((slot >> 1) - 1)); + size_t j; + for (j = 0; j < k; j++) + g_FastPos[j] = (Byte)slot; + g_FastPos += k; + } +} + +/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } + +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); } + +#endif + + +#define LZMA_NUM_REPS 4 + +typedef UInt16 CState; +typedef UInt16 CExtra; + +typedef struct +{ + UInt32 price; + CState state; + CExtra extra; + // 0 : normal + // 1 : LIT : MATCH + // > 1 : MATCH (extra-1) : LIT : REP0 (len) + UInt32 len; + UInt32 dist; + UInt32 reps[LZMA_NUM_REPS]; +} COptimal; + + +// 18.06 +#define kNumOpts (1 << 11) +#define kPackReserve (kNumOpts * 8) +// #define kNumOpts (1 << 12) +// #define kPackReserve (1 + kNumOpts * 2) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +typedef +#ifdef _LZMA_PROB32 + UInt32 +#else + UInt16 +#endif + CLzmaProb; + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) +#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + + +typedef struct +{ + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + + +typedef struct +{ + unsigned tableSize; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2]; + // UInt32 prices2[kLenNumSymbolsTotal]; +} CLenPriceEnc; + +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN]) + +/* +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9))) +*/ + +typedef struct +{ + UInt32 range; + unsigned cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + + +typedef struct +{ + CLzmaProb *litProbs; + + unsigned state; + UInt32 reps[LZMA_NUM_REPS]; + + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; + +} CSaveState; + + +typedef UInt32 CProbPrice; + + +typedef struct +{ + void *matchFinderObj; + IMatchFinder matchFinder; + + unsigned optCur; + unsigned optEnd; + + unsigned longestMatchLen; + unsigned numPairs; + UInt32 numAvail; + + unsigned state; + unsigned numFastBytes; + unsigned additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + unsigned lpMask, pbMask; + CLzmaProb *litProbs; + CRangeEnc rc; + + UInt32 backRes; + + unsigned lc, lp, pb; + unsigned lclp; + + BoolInt fastMode; + BoolInt writeEndMark; + BoolInt finished; + BoolInt multiThread; + BoolInt needInit; + // BoolInt _maxMode; + + UInt64 nowPos64; + + unsigned matchPriceCount; + // unsigned alignPriceCount; + int repLenEncCounter; + + unsigned distTableSize; + + UInt32 dictSize; + SRes result; + + #ifndef _7ZIP_ST + BoolInt mtMode; + // begin of CMatchFinderMt is used in LZ thread + CMatchFinderMt matchFinderMt; + // end of CMatchFinderMt is used in BT and HASH threads + #endif + + CMatchFinder matchFinderBase; + + #ifndef _7ZIP_ST + Byte pad[128]; + #endif + + // LZ thread + CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + + UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + + UInt32 alignPrices[kAlignTableSize]; + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + COptimal opt[kNumOpts]; + + CSaveState saveState; + + #ifndef _7ZIP_ST + Byte pad2[128]; + #endif +} CLzmaEnc; + + + +#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr)); + +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + + dest->state = p->state; + + dest->lenProbs = p->lenProbs; + dest->repLenProbs = p->repLenProbs; + + COPY_ARR(dest, p, reps); + + COPY_ARR(dest, p, posAlignEncoder); + COPY_ARR(dest, p, isRep); + COPY_ARR(dest, p, isRepG0); + COPY_ARR(dest, p, isRepG1); + COPY_ARR(dest, p, isRepG2); + COPY_ARR(dest, p, isMatch); + COPY_ARR(dest, p, isRep0Long); + COPY_ARR(dest, p, posSlotEncoder); + COPY_ARR(dest, p, posEncoders); + + memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb)); +} + + +void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + + dest->state = p->state; + + dest->lenProbs = p->lenProbs; + dest->repLenProbs = p->repLenProbs; + + COPY_ARR(dest, p, reps); + + COPY_ARR(dest, p, posAlignEncoder); + COPY_ARR(dest, p, isRep); + COPY_ARR(dest, p, isRepG0); + COPY_ARR(dest, p, isRepG1); + COPY_ARR(dest, p, isRepG2); + COPY_ARR(dest, p, isMatch); + COPY_ARR(dest, p, isRep0Long); + COPY_ARR(dest, p, posSlotEncoder); + COPY_ARR(dest, p, posEncoders); + + memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb)); +} + + + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX + || props.lp > LZMA_LP_MAX + || props.pb > LZMA_PB_MAX + || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress) + || props.dictSize > kLzmaMaxHistorySize) + return SZ_ERROR_PARAM; + + p->dictSize = props.dictSize; + { + unsigned fb = props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = props.lc; + p->lp = props.lp; + p->pb = props.pb; + p->fastMode = (props.algo == 0); + // p->_maxMode = True; + p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0); + { + unsigned numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = props.numHashBytes; + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = props.writeEndMark; + + #ifndef _7ZIP_ST + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + #endif + + return SZ_OK; +} + + +void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.expectedDataSize = expectedDataSiize; +} + + +#define kState_Start 0 +#define kState_LitAfterMatch 4 +#define kState_LitAfterRep 5 +#define kState_MatchAfterLit 7 +#define kState_RepAfterLit 8 + +static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +#define IsLitState(s) ((s) < 7) +#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1) +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = NULL; + p->bufBase = NULL; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) +#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + ((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) + +static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc) +{ + if (!p->bufBase) + { + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE); + if (!p->bufBase) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->range = 0xFFFFFFFF; + p->cache = 0; + p->low = 0; + p->cacheSize = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = p->buf - p->bufBase; + if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + UInt32 low = (UInt32)p->low; + unsigned high = (unsigned)(p->low >> 32); + p->low = (UInt32)(low << 8); + if (low < (UInt32)0xFF000000 || high != 0) + { + { + Byte *buf = p->buf; + *buf++ = (Byte)(p->cache + high); + p->cache = (unsigned)(low >> 24); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (p->cacheSize == 0) + return; + } + high += 0xFF; + for (;;) + { + Byte *buf = p->buf; + *buf++ = (Byte)(high); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (--p->cacheSize == 0) + return; + } + } + p->cacheSize++; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); } + +#define RC_BIT_PRE(p, prob) \ + ttt = *(prob); \ + newBound = (range >> kNumBitModelTotalBits) * ttt; + +// #define _LZMA_ENC_USE_BRANCH + +#ifdef _LZMA_ENC_USE_BRANCH + +#define RC_BIT(p, prob, bit) { \ + RC_BIT_PRE(p, prob) \ + if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \ + else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#else + +#define RC_BIT(p, prob, bit) { \ + UInt32 mask; \ + RC_BIT_PRE(p, prob) \ + mask = 0 - (UInt32)bit; \ + range &= mask; \ + mask &= newBound; \ + range -= mask; \ + (p)->low += mask; \ + mask = (UInt32)bit - 1; \ + range += newBound & mask; \ + mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \ + mask += ((1 << kNumMoveBits) - 1); \ + ttt += (Int32)(mask - ttt) >> kNumMoveBits; \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#endif + + + + +#define RC_BIT_0_BASE(p, prob) \ + range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + +#define RC_BIT_1_BASE(p, prob) \ + range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \ + +#define RC_BIT_0(p, prob) \ + RC_BIT_0_BASE(p, prob) \ + RC_NORM(p) + +#define RC_BIT_1(p, prob) \ + RC_BIT_1_BASE(p, prob) \ + RC_NORM(p) + +static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob) +{ + UInt32 range, ttt, newBound; + range = p->range; + RC_BIT_PRE(p, prob) + RC_BIT_0(p, prob) + p->range = range; +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym) +{ + UInt32 range = p->range; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1); + CLzmaProb *prob = probs + (sym >> 8); + UInt32 bit = (sym >> 7) & 1; + sym <<= 1; + RC_BIT(p, prob, bit); + } + while (sym < 0x10000); + p->range = range; +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte) +{ + UInt32 range = p->range; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + CLzmaProb *prob; + UInt32 bit; + matchByte <<= 1; + // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1); + prob = probs + (offs + (matchByte & offs) + (sym >> 8)); + bit = (sym >> 7) & 1; + sym <<= 1; + offs &= ~(matchByte ^ sym); + RC_BIT(p, prob, bit); + } + while (sym < 0x10000); + p->range = range; +} + + + +static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices) +{ + UInt32 i; + for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++) + { + const unsigned kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1)); + unsigned bitCount = 0; + unsigned j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i] = (CProbPrice)((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + // printf("\n%3d: %5d", i, ProbPrices[i]); + } +} + + +#define GET_PRICE(prob, bit) \ + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, bit) \ + ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices) +{ + UInt32 price = 0; + sym |= 0x100; + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); + } + while (sym >= 2); + return price; +} + + +static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1); + sym <<= 1; + offs &= ~(matchByte ^ sym); + } + while (sym < 0x10000); + return price; +} + + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym) +{ + UInt32 range = rc->range; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + unsigned bit = sym & 1; + // RangeEnc_EncodeBit(rc, probs + m, bit); + sym >>= 1; + RC_BIT(rc, probs + m, bit); + m = (m << 1) | bit; + } + while (--numBits); + rc->range = range; +} + + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState) +{ + UInt32 range, ttt, newBound; + CLzmaProb *probs = p->low; + range = rc->range; + RC_BIT_PRE(rc, probs); + if (sym >= kLenNumLowSymbols) + { + RC_BIT_1(rc, probs); + probs += kLenNumLowSymbols; + RC_BIT_PRE(rc, probs); + if (sym >= kLenNumLowSymbols * 2) + { + RC_BIT_1(rc, probs); + rc->range = range; + // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2); + LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2); + return; + } + sym -= kLenNumLowSymbols; + } + + // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym); + { + unsigned m; + unsigned bit; + RC_BIT_0(rc, probs); + probs += (posState << (1 + kLenNumLowBits)); + bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit; + bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit; + bit = sym & 1; RC_BIT(rc, probs + m, bit); + rc->range = range; + } +} + +static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices) +{ + unsigned i; + for (i = 0; i < 8; i += 2) + { + UInt32 price = startPrice; + UInt32 prob; + price += GET_PRICEa(probs[1 ], (i >> 2)); + price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1); + prob = probs[4 + (i >> 1)]; + prices[i ] = price + GET_PRICEa_0(prob); + prices[i + 1] = price + GET_PRICEa_1(prob); + } +} + + +MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTables( + CLenPriceEnc *p, + unsigned numPosStates, + const CLenEnc *enc, + const CProbPrice *ProbPrices) +{ + UInt32 b; + + { + unsigned prob = enc->low[0]; + UInt32 a, c; + unsigned posState; + b = GET_PRICEa_1(prob); + a = GET_PRICEa_0(prob); + c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); + for (posState = 0; posState < numPosStates; posState++) + { + UInt32 *prices = p->prices[posState]; + const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits)); + SetPrices_3(probs, a, prices, ProbPrices); + SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices); + } + } + + /* + { + unsigned i; + UInt32 b; + a = GET_PRICEa_0(enc->low[0]); + for (i = 0; i < kLenNumLowSymbols; i++) + p->prices2[i] = a; + a = GET_PRICEa_1(enc->low[0]); + b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); + for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++) + p->prices2[i] = b; + a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + } + */ + + // p->counter = numSymbols; + // p->counter = 64; + + { + unsigned i = p->tableSize; + + if (i > kLenNumLowSymbols * 2) + { + const CLzmaProb *probs = enc->high; + UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2; + i -= kLenNumLowSymbols * 2 - 1; + i >>= 1; + b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + do + { + /* + p->prices2[i] = a + + // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices); + LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices); + */ + // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices); + unsigned sym = --i + (1 << (kLenNumHighBits - 1)); + UInt32 price = b; + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); + } + while (sym >= 2); + + { + unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))]; + prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob); + prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob); + } + } + while (i); + + { + unsigned posState; + size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]); + for (posState = 1; posState < numPosStates; posState++) + memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num); + } + } + } +} + +/* + #ifdef SHOW_STAT + g_STAT_OFFSET += num; + printf("\n MovePos %u", num); + #endif +*/ + +#define MOVE_POS(p, num) { \ + p->additionalOffset += (num); \ + p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); } + + +static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes) +{ + unsigned numPairs; + + p->additionalOffset++; + p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + *numPairsRes = numPairs; + + #ifdef SHOW_STAT + printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2); + g_STAT_OFFSET++; + { + unsigned i; + for (i = 0; i < numPairs; i += 2) + printf("%2u %6u | ", p->matches[i], p->matches[i + 1]); + } + #endif + + if (numPairs == 0) + return 0; + { + unsigned len = p->matches[(size_t)numPairs - 2]; + if (len != p->numFastBytes) + return len; + { + UInt32 numAvail = p->numAvail; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + { + const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + const Byte *p2 = p1 + len; + ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1]; + const Byte *lim = p1 + numAvail; + for (; p2 != lim && *p2 == p2[dif]; p2++) + {} + return (unsigned)(p2 - p1); + } + } + } +} + +#define MARK_LIT ((UInt32)(Int32)-1) + +#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; } +#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; } +#define IsShortRep(p) ((p)->dist == 0) + + +#define GetPrice_ShortRep(p, state, posState) \ + ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState])) + +#define GetPrice_Rep_0(p, state, posState) ( \ + GET_PRICE_1(p->isMatch[state][posState]) \ + + GET_PRICE_1(p->isRep0Long[state][posState])) \ + + GET_PRICE_1(p->isRep[state]) \ + + GET_PRICE_0(p->isRepG0[state]) + +MY_FORCE_INLINE +static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState) +{ + UInt32 price; + UInt32 prob = p->isRepG0[state]; + if (repIndex == 0) + { + price = GET_PRICE_0(prob); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(prob); + prob = p->isRepG1[state]; + if (repIndex == 1) + price += GET_PRICE_0(prob); + else + { + price += GET_PRICE_1(prob); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + + +static unsigned Backward(CLzmaEnc *p, unsigned cur) +{ + unsigned wr = cur + 1; + p->optEnd = wr; + + for (;;) + { + UInt32 dist = p->opt[cur].dist; + unsigned len = (unsigned)p->opt[cur].len; + unsigned extra = (unsigned)p->opt[cur].extra; + cur -= len; + + if (extra) + { + wr--; + p->opt[wr].len = (UInt32)len; + cur -= extra; + len = extra; + if (extra == 1) + { + p->opt[wr].dist = dist; + dist = MARK_LIT; + } + else + { + p->opt[wr].dist = 0; + len--; + wr--; + p->opt[wr].dist = MARK_LIT; + p->opt[wr].len = 1; + } + } + + if (cur == 0) + { + p->backRes = dist; + p->optCur = wr; + return len; + } + + wr--; + p->opt[wr].dist = dist; + p->opt[wr].len = (UInt32)len; + } +} + + + +#define LIT_PROBS(pos, prevByte) \ + (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc)) + + +static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) +{ + unsigned last, cur; + UInt32 reps[LZMA_NUM_REPS]; + unsigned repLens[LZMA_NUM_REPS]; + UInt32 *matches; + + { + UInt32 numAvail; + unsigned numPairs, mainLen, repMaxIndex, i, posState; + UInt32 matchPrice, repMatchPrice; + const Byte *data; + Byte curByte, matchByte; + + p->optCur = p->optEnd = 0; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLen; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + if (numAvail < 2) + { + p->backRes = MARK_LIT; + return 1; + } + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repMaxIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + + if (repLens[repMaxIndex] >= p->numFastBytes) + { + unsigned len; + p->backRes = (UInt32)repMaxIndex; + len = repLens[repMaxIndex]; + MOVE_POS(p, len - 1) + return len; + } + + matches = p->matches; + + if (mainLen >= p->numFastBytes) + { + p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) + return mainLen; + } + + curByte = *data; + matchByte = *(data - reps[0]); + + last = repLens[repMaxIndex]; + if (last <= mainLen) + last = mainLen; + + if (last < 2 && curByte != matchByte) + { + p->backRes = MARK_LIT; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsLitState(p->state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + } + + MakeAs_Lit(&p->opt[1]); + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + // 18.06 + if (matchByte == curByte && repLens[0] == 0) + { + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAs_ShortRep(&p->opt[1]); + } + if (last < 2) + { + p->backRes = p->opt[1].dist; + return 1; + } + } + + p->opt[1].len = 1; + + p->opt[0].reps[0] = reps[0]; + p->opt[0].reps[1] = reps[1]; + p->opt[0].reps[2] = reps[2]; + p->opt[0].reps[3] = reps[3]; + + // ---------- REP ---------- + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen); + COptimal *opt = &p->opt[repLen]; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)repLen; + opt->dist = (UInt32)i; + opt->extra = 0; + } + } + while (--repLen >= 2); + } + + + // ---------- MATCH ---------- + { + unsigned len = repLens[0] + 1; + if (len <= mainLen) + { + unsigned offs = 0; + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + if (len < 2) + len = 2; + else + while (len > matches[offs]) + offs += 2; + + for (; ; len++) + { + COptimal *opt; + UInt32 dist = matches[(size_t)offs + 1]; + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + unsigned lenToPosState = GetLenToPosState(len); + + if (dist < kNumFullDistances) + price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)]; + else + { + unsigned slot; + GetPosSlot2(dist, slot); + price += p->alignPrices[dist & kAlignMask]; + price += p->posSlotPrices[lenToPosState][slot]; + } + + opt = &p->opt[len]; + + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + + if (len == matches[offs]) + { + offs += 2; + if (offs == numPairs) + break; + } + } + } + } + + + cur = 0; + + #ifdef SHOW_STAT2 + /* if (position >= 0) */ + { + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= last; i++) + printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); + } + #endif + } + + + + // ---------- Optimal Parsing ---------- + + for (;;) + { + unsigned numAvail; + UInt32 numAvailFull; + unsigned newLen, numPairs, prev, state, posState, startLen; + UInt32 litPrice, matchPrice, repMatchPrice; + BoolInt nextIsLit; + Byte curByte, matchByte; + const Byte *data; + COptimal *curOpt, *nextOpt; + + if (++cur == last) + break; + + // 18.06 + if (cur >= kNumOpts - 64) + { + unsigned j, best; + UInt32 price = p->opt[cur].price; + best = cur; + for (j = cur + 1; j <= last; j++) + { + UInt32 price2 = p->opt[j].price; + if (price >= price2) + { + price = price2; + best = j; + } + } + { + unsigned delta = best - cur; + if (delta != 0) + { + MOVE_POS(p, delta); + } + } + cur = best; + break; + } + + newLen = ReadMatchDistances(p, &numPairs); + + if (newLen >= p->numFastBytes) + { + p->numPairs = numPairs; + p->longestMatchLen = newLen; + break; + } + + curOpt = &p->opt[cur]; + + position++; + + // we need that check here, if skip_items in p->opt are possible + /* + if (curOpt->price >= kInfinityPrice) + continue; + */ + + prev = cur - curOpt->len; + + if (curOpt->len == 1) + { + state = (unsigned)p->opt[prev].state; + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + const COptimal *prevOpt; + UInt32 b0; + UInt32 dist = curOpt->dist; + + if (curOpt->extra) + { + prev -= (unsigned)curOpt->extra; + state = kState_RepAfterLit; + if (curOpt->extra == 1) + state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit); + } + else + { + state = (unsigned)p->opt[prev].state; + if (dist < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + + prevOpt = &p->opt[prev]; + b0 = prevOpt->reps[0]; + + if (dist < LZMA_NUM_REPS) + { + if (dist == 0) + { + reps[0] = b0; + reps[1] = prevOpt->reps[1]; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; + } + else + { + reps[1] = b0; + b0 = prevOpt->reps[1]; + if (dist == 1) + { + reps[0] = b0; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; + } + else + { + reps[2] = b0; + reps[0] = prevOpt->reps[dist]; + reps[3] = prevOpt->reps[dist ^ 1]; + } + } + } + else + { + reps[0] = (dist - LZMA_NUM_REPS + 1); + reps[1] = b0; + reps[2] = prevOpt->reps[1]; + reps[3] = prevOpt->reps[2]; + } + } + + curOpt->state = (CState)state; + curOpt->reps[0] = reps[0]; + curOpt->reps[1] = reps[1]; + curOpt->reps[2] = reps[2]; + curOpt->reps[3] = reps[3]; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + curByte = *data; + matchByte = *(data - reps[0]); + + posState = (position & p->pbMask); + + /* + The order of Price checks: + < LIT + <= SHORT_REP + < LIT : REP_0 + < REP [ : LIT : REP_0 ] + < MATCH [ : LIT : REP_0 ] + */ + + { + UInt32 curPrice = curOpt->price; + unsigned prob = p->isMatch[state][posState]; + matchPrice = curPrice + GET_PRICE_1(prob); + litPrice = curPrice + GET_PRICE_0(prob); + } + + nextOpt = &p->opt[(size_t)cur + 1]; + nextIsLit = False; + + // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice) + // 18.new.06 + if ((nextOpt->price < kInfinityPrice + // && !IsLitState(state) + && matchByte == curByte) + || litPrice > nextOpt->price + ) + litPrice = 0; + else + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + litPrice += (!IsLitState(state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + + if (litPrice < nextOpt->price) + { + nextOpt->price = litPrice; + nextOpt->len = 1; + MakeAs_Lit(nextOpt); + nextIsLit = True; + } + } + + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + numAvailFull = p->numAvail; + { + unsigned temp = kNumOpts - 1 - cur; + if (numAvailFull > temp) + numAvailFull = (UInt32)temp; + } + + // 18.06 + // ---------- SHORT_REP ---------- + if (IsLitState(state)) // 18.new + if (matchByte == curByte) + if (repMatchPrice < nextOpt->price) // 18.new + // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1)) + if ( + // nextOpt->price >= kInfinityPrice || + nextOpt->len < 2 // we can check nextOpt->len, if skip items are not allowed in p->opt + || (nextOpt->dist != 0 + // && nextOpt->extra <= 1 // 17.old + ) + ) + { + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState); + // if (shortRepPrice <= nextOpt->price) // 17.old + if (shortRepPrice < nextOpt->price) // 18.new + { + nextOpt->price = shortRepPrice; + nextOpt->len = 1; + MakeAs_ShortRep(nextOpt); + nextIsLit = False; + } + } + + if (numAvailFull < 2) + continue; + numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); + + // numAvail <= p->numFastBytes + + // ---------- LIT : REP_0 ---------- + + if (!nextIsLit + && litPrice != 0 // 18.new + && matchByte != curByte + && numAvailFull > 2) + { + const Byte *data2 = data - reps[0]; + if (data[1] == data2[1] && data[2] == data2[2]) + { + unsigned len; + unsigned limit = p->numFastBytes + 1; + if (limit > numAvailFull) + limit = numAvailFull; + for (len = 3; len < limit && data[len] == data2[len]; len++) + {} + + { + unsigned state2 = kLiteralNextStates[state]; + unsigned posState2 = (position + 1) & p->pbMask; + UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2); + { + unsigned offset = cur + len; + + if (last < offset) + last = offset; + + // do + { + UInt32 price2; + COptimal *opt; + len--; + // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len); + + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len; + opt->dist = 0; + opt->extra = 1; + } + } + // while (len >= 3); + } + } + } + } + + startLen = 2; /* speed optimization */ + + { + // ---------- REP ---------- + unsigned repIndex = 0; // 17.old + // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused + for (; repIndex < LZMA_NUM_REPS; repIndex++) + { + unsigned len; + UInt32 price; + const Byte *data2 = data - reps[repIndex]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + + // if (len < startLen) continue; // 18.new: speed optimization + + { + unsigned offset = cur + len; + if (last < offset) + last = offset; + } + { + unsigned len2 = len; + price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2); + COptimal *opt = &p->opt[cur + len2]; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->dist = (UInt32)repIndex; + opt->extra = 0; + } + } + while (--len2 >= 2); + } + + if (repIndex == 0) startLen = len + 1; // 17.old + // startLen = len + 1; // 18.new + + /* if (_maxMode) */ + { + // ---------- REP : LIT : REP_0 ---------- + // numFastBytes + 1 + numFastBytes + + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + unsigned state2 = kRepNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + price += GET_PRICE_LEN(&p->repLenEnc, posState, len) + + GET_PRICE_0(p->isMatch[state2][posState2]) + + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterRep; + posState2 = (posState2 + 1) & p->pbMask; + + + price += GetPrice_Rep_0(p, state2, posState2); + + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + // if (len2 >= 3) + { + { + unsigned offset = cur + len + len2; + + if (last < offset) + last = offset; + // do + { + UInt32 price2; + COptimal *opt; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); + + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = (UInt32)repIndex; + } + } + // while (len2 >= 3); + } + } + } + } + } + } + + + // ---------- MATCH ---------- + /* for (unsigned len = 2; len <= newLen; len++) */ + if (newLen > numAvail) + { + newLen = numAvail; + for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); + matches[numPairs] = (UInt32)newLen; + numPairs += 2; + } + + // startLen = 2; /* speed optimization */ + + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 dist; + unsigned offs, posSlot, len; + + { + unsigned offset = cur + newLen; + if (last < offset) + last = offset; + } + + offs = 0; + while (startLen > matches[offs]) + offs += 2; + dist = matches[(size_t)offs + 1]; + + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot); + + for (len = /*2*/ startLen; ; len++) + { + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + { + COptimal *opt; + unsigned lenNorm = len - 2; + lenNorm = GetLenToPosState2(lenNorm); + if (dist < kNumFullDistances) + price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)]; + else + price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask]; + + opt = &p->opt[cur + len]; + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + } + + if (len == matches[offs]) + { + // if (p->_maxMode) { + // MATCH : LIT : REP_0 + + const Byte *data2 = data - dist - 1; + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + + // if (len2 >= 3) + { + unsigned state2 = kMatchNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + unsigned offset; + price += GET_PRICE_0(p->isMatch[state2][posState2]); + price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterMatch; + + posState2 = (posState2 + 1) & p->pbMask; + price += GetPrice_Rep_0(p, state2, posState2); + + offset = cur + len + len2; + + if (last < offset) + last = offset; + // do + { + UInt32 price2; + COptimal *opt; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = dist + LZMA_NUM_REPS; + } + } + // while (len2 >= 3); + } + + } + + offs += 2; + if (offs == numPairs) + break; + dist = matches[(size_t)offs + 1]; + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot); + } + } + } + } + + do + p->opt[last].price = kInfinityPrice; + while (--last); + + return Backward(p, cur); +} + + + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + + + +static unsigned GetOptimumFast(CLzmaEnc *p) +{ + UInt32 numAvail, mainDist; + unsigned mainLen, numPairs, repIndex, repLen, i; + const Byte *data; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLen; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + p->backRes = MARK_LIT; + if (numAvail < 2) + return 1; + // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repLen = repIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + if (len >= p->numFastBytes) + { + p->backRes = (UInt32)i; + MOVE_POS(p, len - 1) + return len; + } + if (len > repLen) + { + repIndex = i; + repLen = len; + } + } + + if (mainLen >= p->numFastBytes) + { + p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) + return mainLen; + } + + mainDist = 0; /* for GCC */ + + if (mainLen >= 2) + { + mainDist = p->matches[(size_t)numPairs - 1]; + while (numPairs > 2) + { + UInt32 dist2; + if (mainLen != p->matches[(size_t)numPairs - 4] + 1) + break; + dist2 = p->matches[(size_t)numPairs - 3]; + if (!ChangePair(dist2, mainDist)) + break; + numPairs -= 2; + mainLen--; + mainDist = dist2; + } + if (mainLen == 2 && mainDist >= 0x80) + mainLen = 1; + } + + if (repLen >= 2) + if ( repLen + 1 >= mainLen + || (repLen + 2 >= mainLen && mainDist >= (1 << 9)) + || (repLen + 3 >= mainLen && mainDist >= (1 << 15))) + { + p->backRes = (UInt32)repIndex; + MOVE_POS(p, repLen - 1) + return repLen; + } + + if (mainLen < 2 || numAvail <= 2) + return 1; + + { + unsigned len1 = ReadMatchDistances(p, &p->numPairs); + p->longestMatchLen = len1; + + if (len1 >= 2) + { + UInt32 newDist = p->matches[(size_t)p->numPairs - 1]; + if ( (len1 >= mainLen && newDist < mainDist) + || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist)) + || (len1 > mainLen + 1) + || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist))) + return 1; + } + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len, limit; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + limit = mainLen - 1; + for (len = 2;; len++) + { + if (len >= limit) + return 1; + if (data[len] != data2[len]) + break; + } + } + + p->backRes = mainDist + LZMA_NUM_REPS; + if (mainLen != 2) + { + MOVE_POS(p, mainLen - 2) + } + return mainLen; +} + + + + +static void WriteEndMarker(CLzmaEnc *p, unsigned posState) +{ + UInt32 range; + range = p->rc.range; + { + UInt32 ttt, newBound; + CLzmaProb *prob = &p->isMatch[p->state][posState]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_1(&p->rc, prob) + prob = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_0(&p->rc, prob) + } + p->state = kMatchNextStates[p->state]; + + p->rc.range = range; + LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState); + range = p->rc.range; + + { + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1); + CLzmaProb *probs = p->posSlotEncoder[0]; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m); + m = (m << 1) + 1; + } + while (m < (1 << kNumPosSlotBits)); + } + { + // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range; + unsigned numBits = 30 - kNumAlignBits; + do + { + range >>= 1; + p->rc.low += range; + RC_NORM(&p->rc) + } + while (--numBits); + } + + { + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); + CLzmaProb *probs = p->posAlignEncoder; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m); + m = (m << 1) + 1; + } + while (m < kAlignTableSize); + } + p->rc.range = range; +} + + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + + +MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + + +MY_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) +{ + unsigned i; + const CProbPrice *ProbPrices = p->ProbPrices; + const CLzmaProb *probs = p->posAlignEncoder; + // p->alignPriceCount = 0; + for (i = 0; i < kAlignTableSize / 2; i++) + { + UInt32 price = 0; + unsigned sym = i; + unsigned m = 1; + unsigned bit; + UInt32 prob; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + prob = probs[m]; + p->alignPrices[i ] = price + GET_PRICEa_0(prob); + p->alignPrices[i + 8] = price + GET_PRICEa_1(prob); + // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + } +} + + +MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) +{ + // int y; for (y = 0; y < 100; y++) { + + UInt32 tempPrices[kNumFullDistances]; + unsigned i, lps; + + const CProbPrice *ProbPrices = p->ProbPrices; + p->matchPriceCount = 0; + + for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++) + { + unsigned posSlot = GetPosSlot1(i); + unsigned footerBits = (posSlot >> 1) - 1; + unsigned base = ((2 | (posSlot & 1)) << footerBits); + const CLzmaProb *probs = p->posEncoders + (size_t)base * 2; + // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices); + UInt32 price = 0; + unsigned m = 1; + unsigned sym = i; + unsigned offset = (unsigned)1 << footerBits; + base += i; + + if (footerBits) + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) + bit; + } + while (--footerBits); + + { + unsigned prob = probs[m]; + tempPrices[base ] = price + GET_PRICEa_0(prob); + tempPrices[base + offset] = price + GET_PRICEa_1(prob); + } + } + + for (lps = 0; lps < kNumLenToPosStates; lps++) + { + unsigned slot; + unsigned distTableSize2 = (p->distTableSize + 1) >> 1; + UInt32 *posSlotPrices = p->posSlotPrices[lps]; + const CLzmaProb *probs = p->posSlotEncoder[lps]; + + for (slot = 0; slot < distTableSize2; slot++) + { + // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); + UInt32 price; + unsigned bit; + unsigned sym = slot + (1 << (kNumPosSlotBits - 1)); + unsigned prob; + bit = sym & 1; sym >>= 1; price = GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))]; + posSlotPrices[(size_t)slot * 2 ] = price + GET_PRICEa_0(prob); + posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob); + } + + { + UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++) + { + posSlotPrices[(size_t)slot * 2 ] += delta; + posSlotPrices[(size_t)slot * 2 + 1] += delta; + delta += ((UInt32)1 << kNumBitPriceShiftBits); + } + } + + { + UInt32 *dp = p->distancesPrices[lps]; + + dp[0] = posSlotPrices[0]; + dp[1] = posSlotPrices[1]; + dp[2] = posSlotPrices[2]; + dp[3] = posSlotPrices[3]; + + for (i = 4; i < kNumFullDistances; i += 2) + { + UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)]; + dp[i ] = slotPrice + tempPrices[i]; + dp[i + 1] = slotPrice + tempPrices[i + 1]; + } + } + } + // } +} + + + +void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + + #ifndef _7ZIP_ST + MatchFinderMt_Construct(&p->matchFinderMt); + p->matchFinderMt.MatchFinder = &p->matchFinderBase; + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = NULL; + p->saveState.litProbs = NULL; + +} + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc) +{ + void *p; + p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc)); + if (p) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->litProbs); + ISzAlloc_Free(alloc, p->saveState.litProbs); + p->litProbs = NULL; + p->saveState.litProbs = NULL; +} + +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + #ifndef _7ZIP_ST + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + ISzAlloc_Free(alloc, p); +} + + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->needInit) + { + p->matchFinder.Init(p->matchFinderObj); + p->needInit = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + unsigned numPairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numPairs); + RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]); + // p->state = kLiteralNextStates[p->state]; + curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + + for (;;) + { + UInt32 dist; + unsigned len, posState; + UInt32 range, ttt, newBound; + CLzmaProb *probs; + + if (p->fastMode) + len = GetOptimumFast(p); + else + { + unsigned oci = p->optCur; + if (p->optEnd == oci) + len = GetOptimum(p, nowPos32); + else + { + const COptimal *opt = &p->opt[oci]; + len = opt->len; + p->backRes = opt->dist; + p->optCur = oci + 1; + } + } + + posState = (unsigned)nowPos32 & p->pbMask; + range = p->rc.range; + probs = &p->isMatch[p->state][posState]; + + RC_BIT_PRE(&p->rc, probs) + + dist = p->backRes; + + #ifdef SHOW_STAT2 + printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist); + #endif + + if (dist == MARK_LIT) + { + Byte curByte; + const Byte *data; + unsigned state; + + RC_BIT_0(&p->rc, probs); + p->rc.range = range; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + probs = LIT_PROBS(nowPos32, *(data - 1)); + curByte = *data; + state = p->state; + p->state = kLiteralNextStates[state]; + if (IsLitState(state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0])); + } + else + { + RC_BIT_1(&p->rc, probs); + probs = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, probs) + + if (dist < LZMA_NUM_REPS) + { + RC_BIT_1(&p->rc, probs); + probs = &p->isRepG0[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 0) + { + RC_BIT_0(&p->rc, probs); + probs = &p->isRep0Long[p->state][posState]; + RC_BIT_PRE(&p->rc, probs) + if (len != 1) + { + RC_BIT_1_BASE(&p->rc, probs); + } + else + { + RC_BIT_0_BASE(&p->rc, probs); + p->state = kShortRepNextStates[p->state]; + } + } + else + { + RC_BIT_1(&p->rc, probs); + probs = &p->isRepG1[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 1) + { + RC_BIT_0_BASE(&p->rc, probs); + dist = p->reps[1]; + } + else + { + RC_BIT_1(&p->rc, probs); + probs = &p->isRepG2[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 2) + { + RC_BIT_0_BASE(&p->rc, probs); + dist = p->reps[2]; + } + else + { + RC_BIT_1_BASE(&p->rc, probs); + dist = p->reps[3]; + p->reps[3] = p->reps[2]; + } + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = dist; + } + + RC_NORM(&p->rc) + + p->rc.range = range; + + if (len != 1) + { + LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + --p->repLenEncCounter; + p->state = kRepNextStates[p->state]; + } + } + else + { + unsigned posSlot; + RC_BIT_0(&p->rc, probs); + p->rc.range = range; + p->state = kMatchNextStates[p->state]; + + LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + // --p->lenEnc.counter; + + dist -= LZMA_NUM_REPS; + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = dist + 1; + + p->matchPriceCount++; + GetPosSlot(dist, posSlot); + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot); + { + UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits); + range = p->rc.range; + probs = p->posSlotEncoder[GetLenToPosState(len)]; + do + { + CLzmaProb *prob = probs + (sym >> kNumPosSlotBits); + UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1; + sym <<= 1; + RC_BIT(&p->rc, prob, bit); + } + while (sym < (1 << kNumPosSlotBits * 2)); + p->rc.range = range; + } + + if (dist >= kStartPosModelIndex) + { + unsigned footerBits = ((posSlot >> 1) - 1); + + if (dist < kNumFullDistances) + { + unsigned base = ((2 | (posSlot & 1)) << footerBits); + RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */)); + } + else + { + UInt32 pos2 = (dist | 0xF) << (32 - footerBits); + range = p->rc.range; + // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + /* + do + { + range >>= 1; + p->rc.low += range & (0 - ((dist >> --footerBits) & 1)); + RC_NORM(&p->rc) + } + while (footerBits > kNumAlignBits); + */ + do + { + range >>= 1; + p->rc.low += range & (0 - (pos2 >> 31)); + pos2 += pos2; + RC_NORM(&p->rc) + } + while (pos2 != 0xF0000000); + + + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + + { + unsigned m = 1; + unsigned bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); + p->rc.range = range; + // p->alignPriceCount++; + } + } + } + } + } + + nowPos32 += (UInt32)len; + p->additionalOffset -= len; + + if (p->additionalOffset == 0) + { + UInt32 processed; + + if (!p->fastMode) + { + /* + if (p->alignPriceCount >= 16) // kAlignTableSize + FillAlignPrices(p); + if (p->matchPriceCount >= 128) + FillDistancesPrices(p); + if (p->lenEnc.counter <= 0) + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices); + */ + if (p->matchPriceCount >= 64) + { + FillAlignPrices(p); + // { int y; for (y = 0; y < 100; y++) { + FillDistancesPrices(p); + // }} + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices); + } + if (p->repLenEncCounter <= 0) + { + p->repLenEncCounter = REP_LEN_COUNT; + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices); + } + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + + if (maxPackSize) + { + if (processed + kNumOpts + 300 >= maxUnpackSize + || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize) + break; + } + else if (processed >= (1 << 17)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + + + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + UInt32 beforeSize = kNumOpts; + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + + #ifndef _7ZIP_ST + p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); + #endif + + { + unsigned lclp = p->lc + p->lp; + if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); + if (!p->litProbs || !p->saveState.litProbs) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + #ifndef _7ZIP_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, + LZMA_MATCH_LEN_MAX + + 1 /* 18.04 */ + , allocBig)); + p->matchFinderObj = &p->matchFinderMt; + p->matchFinderBase.bigHash = (Byte)( + (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0); + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + + return SZ_OK; +} + +void LzmaEnc_Init(CLzmaEnc *p) +{ + unsigned i; + p->state = 0; + p->reps[0] = + p->reps[1] = + p->reps[2] = + p->reps[3] = 1; + + RangeEnc_Init(&p->rc); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + for (i = 0; i < kNumStates; i++) + { + unsigned j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + unsigned j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for (i = 0; i < kNumFullDistances; i++) + p->posEncoders[i] = kProbInitValue; + } + + { + UInt32 num = (UInt32)0x300 << (p->lp + p->lc); + UInt32 k; + CLzmaProb *probs = p->litProbs; + for (k = 0; k < num; k++) + probs[k] = kProbInitValue; + } + + + LenEnc_Init(&p->lenProbs); + LenEnc_Init(&p->repLenProbs); + + p->optEnd = 0; + p->optCur = 0; + + { + for (i = 0; i < kNumOpts; i++) + p->opt[i].price = kInfinityPrice; + } + + p->additionalOffset = 0; + + p->pbMask = (1 << p->pb) - 1; + p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc); +} + + +void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + + p->repLenEncCounter = REP_LEN_COUNT; + + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + unsigned i; + for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.stream = inStream; + p->needInit = 1; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.stream = inStream; + p->needInit = 1; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->matchFinderBase.directInput = 1; + p->matchFinderBase.bufferBase = (Byte *)src; + p->matchFinderBase.directInputRem = srcLen; +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->needInit = 1; + + LzmaEnc_SetDataSize(pp, srcLen); + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifndef _7ZIP_ST + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + UNUSED_VAR(pp); + #endif +} + + +typedef struct +{ + ISeqOutStream vt; + Byte *data; + SizeT rem; + BoolInt overflow; +} CLzmaEnc_SeqOutStreamBuf; + +static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size) +{ + CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt); + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + + +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + + +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CLzmaEnc_SeqOutStreamBuf outStream; + + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.vt; + + if (desiredPackSize == 0) + return SZ_ERROR_OUTPUT_EOF; + + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + + +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) +{ + SRes res = SZ_OK; + + #ifndef _7ZIP_ST + Byte allocaDummy[0x300]; + allocaDummy[0] = 0; + allocaDummy[1] = allocaDummy[0]; + #endif + + for (;;) + { + res = LzmaEnc_CodeOneBlock(p, 0, 0); + if (res != SZ_OK || p->finished) + break; + if (progress) + { + res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + + LzmaEnc_Finish(p); + + /* + if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) + res = SZ_ERROR_FAIL; + } + */ + + return res; +} + + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); + return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); +} + + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + unsigned i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + if (dictSize >= ((UInt32)1 << 22)) + { + UInt32 kDictMask = ((UInt32)1 << 20) - 1; + if (dictSize < (UInt32)0xFFFFFFFF - kDictMask) + dictSize = (dictSize + kDictMask) & ~kDictMask; + } + else for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; } + if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + + +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp) +{ + return ((CLzmaEnc *)pp)->writeEndMark; +} + + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CLzmaEnc_SeqOutStreamBuf outStream; + + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + p->rc.outStream = &outStream.vt; + + res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); + + if (res == SZ_OK) + { + res = LzmaEnc_Encode2(p, progress); + if (res == SZ_OK && p->nowPos64 != srcLen) + res = SZ_ERROR_FAIL; + } + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (!p) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} diff --git a/components/ota/common/lzma/3rdparty/LzmaEnc.h b/components/ota/common/lzma/3rdparty/LzmaEnc.h new file mode 100644 index 00000000..9194ee57 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaEnc.h @@ -0,0 +1,76 @@ +/* LzmaEnc.h -- LZMA Encoder +2017-07-27 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_ENC_H +#define __LZMA_ENC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (3 << 29) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ + + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. + Encoder uses this value to reduce dictionary size */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc* functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); + +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); + +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + + +/* ---------- One Call Interface ---------- */ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/LzmaLib.c b/components/ota/common/lzma/3rdparty/LzmaLib.c new file mode 100644 index 00000000..706e9e58 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaLib.c @@ -0,0 +1,40 @@ +/* LzmaLib.c -- LZMA library wrapper +2015-06-13 : Igor Pavlov : Public domain */ + +#include "Alloc.h" +#include "LzmaDec.h" +#include "LzmaEnc.h" +#include "LzmaLib.h" + +MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ +) +{ + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + props.lc = lc; + props.lp = lp; + props.pb = pb; + props.fb = fb; + props.numThreads = numThreads; + + return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); +} + + +MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, + const unsigned char *props, size_t propsSize) +{ + ELzmaStatus status; + return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); +} diff --git a/components/ota/common/lzma/3rdparty/LzmaLib.h b/components/ota/common/lzma/3rdparty/LzmaLib.h new file mode 100644 index 00000000..88fa87d3 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/LzmaLib.h @@ -0,0 +1,131 @@ +/* LzmaLib.h -- LZMA library interface +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_LIB_H +#define __LZMA_LIB_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define MY_STDAPI int MY_STD_CALL + +#define LZMA_PROPS_SIZE 5 + +/* +RAM requirements for LZMA: + for compression: (dictSize * 11.5 + 6 MB) + state_size + for decompression: dictSize + state_size + state_size = (4 + (1.5 << (lc + lp))) KB + by default (lc=3, lp=0), state_size = 16 KB. + +LZMA properties (5 bytes) format + Offset Size Description + 0 1 lc, lp and pb in encoded form. + 1 4 dictSize (little endian). +*/ + +/* +LzmaCompress +------------ + +outPropsSize - + In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + + LZMA Encoder will use defult values for any parameter, if it is + -1 for any from: level, loc, lp, pb, fb, numThreads + 0 for dictSize + +level - compression level: 0 <= level <= 9; + + level dictSize algo fb + 0: 16 KB 0 32 + 1: 64 KB 0 32 + 2: 256 KB 0 32 + 3: 1 MB 0 32 + 4: 4 MB 0 32 + 5: 16 MB 1 32 + 6: 32 MB 1 32 + 7+: 64 MB 1 64 + + The default value for "level" is 5. + + algo = 0 means fast method + algo = 1 means normal method + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + +lc - The number of literal context bits (high bits of previous literal). + It can be in the range from 0 to 8. The default value is 3. + Sometimes lc=4 gives the gain for big files. + +lp - The number of literal pos bits (low bits of current position for literals). + It can be in the range from 0 to 4. The default value is 0. + The lp switch is intended for periodical data when the period is equal to 2^lp. + For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's + better to set lc=0, if you change lp switch. + +pb - The number of pos bits (low bits of current position). + It can be in the range from 0 to 4. The default value is 2. + The pb switch is intended for periodical data when the period is equal 2^pb. + +fb - Word size (the number of fast bytes). + It can be in the range from 5 to 273. The default value is 32. + Usually, a big number gives a little bit better compression ratio and + slower compression process. + +numThreads - The number of thereads. 1 or 2. The default value is 2. + Fast mode (algo = 0) can use only 1 thread. + +Out: + destLen - processed output size +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* default = (1 << 24) */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ + ); + +/* +LzmaUncompress +-------------- +In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size +Out: + destLen - processed output size + srcLen - processed input size +Returns: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation arror + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) +*/ + +MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, + const unsigned char *props, size_t propsSize); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Ppmd.h b/components/ota/common/lzma/3rdparty/Ppmd.h new file mode 100644 index 00000000..a5c1e3ef --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Ppmd.h @@ -0,0 +1,85 @@ +/* Ppmd.h -- PPMD codec common code +2017-04-03 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#ifndef __PPMD_H +#define __PPMD_H + +#include "CpuArch.h" + +EXTERN_C_BEGIN + +#ifdef MY_CPU_32BIT + #define PPMD_32BIT +#endif + +#define PPMD_INT_BITS 7 +#define PPMD_PERIOD_BITS 7 +#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) + +#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) +#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) +#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) +#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) + +#define PPMD_N1 4 +#define PPMD_N2 4 +#define PPMD_N3 4 +#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) +#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) + +#pragma pack(push, 1) +/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */ + +/* SEE-contexts for PPM-contexts with masked symbols */ +typedef struct +{ + UInt16 Summ; /* Freq */ + Byte Shift; /* Speed of Freq change; low Shift is for fast change */ + Byte Count; /* Count to next change of Shift */ +} CPpmd_See; + +#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ + { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } + +typedef struct +{ + Byte Symbol; + Byte Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; +} CPpmd_State; + +#pragma pack(pop) + +typedef + #ifdef PPMD_32BIT + CPpmd_State * + #else + UInt32 + #endif + CPpmd_State_Ref; + +typedef + #ifdef PPMD_32BIT + void * + #else + UInt32 + #endif + CPpmd_Void_Ref; + +typedef + #ifdef PPMD_32BIT + Byte * + #else + UInt32 + #endif + CPpmd_Byte_Ref; + +#define PPMD_SetAllBitsIn256Bytes(p) \ + { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \ + p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }} + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Ppmd7.c b/components/ota/common/lzma/3rdparty/Ppmd7.c new file mode 100644 index 00000000..470aadcc --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Ppmd7.c @@ -0,0 +1,712 @@ +/* Ppmd7.c -- PPMdH codec +2018-07-04 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include "Precomp.h" + +#include + +#include "Ppmd7.h" + +const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +#define MAX_FREQ 124 +#define UNIT_SIZE 12 + +#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) +#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1]) +#define I2U(indx) (p->Indx2Units[indx]) + +#ifdef PPMD_32BIT + #define REF(ptr) (ptr) +#else + #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) +#endif + +#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +#define STATS(ctx) Ppmd7_GetStats(p, ctx) +#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) +#define SUFFIX(ctx) CTX((ctx)->Suffix) + +typedef CPpmd7_Context * CTX_PTR; + +struct CPpmd7_Node_; + +typedef + #ifdef PPMD_32BIT + struct CPpmd7_Node_ * + #else + UInt32 + #endif + CPpmd7_Node_Ref; + +typedef struct CPpmd7_Node_ +{ + UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ + UInt16 NU; + CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ + CPpmd7_Node_Ref Prev; +} CPpmd7_Node; + +#ifdef PPMD_32BIT + #define NODE(ptr) (ptr) +#else + #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) +#endif + +void Ppmd7_Construct(CPpmd7 *p) +{ + unsigned i, k, m; + + p->Base = 0; + + for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) + { + unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); + do { p->Units2Indx[k++] = (Byte)i; } while (--step); + p->Indx2Units[i] = (Byte)k; + } + + p->NS2BSIndx[0] = (0 << 1); + p->NS2BSIndx[1] = (1 << 1); + memset(p->NS2BSIndx + 2, (2 << 1), 9); + memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); + + for (i = 0; i < 3; i++) + p->NS2Indx[i] = (Byte)i; + for (m = i, k = 1; i < 256; i++) + { + p->NS2Indx[i] = (Byte)m; + if (--k == 0) + k = (++m) - 2; + } + + memset(p->HB2Flag, 0, 0x40); + memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); +} + +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Base); + p->Size = 0; + p->Base = 0; +} + +BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc) +{ + if (!p->Base || p->Size != size) + { + size_t size2; + Ppmd7_Free(p, alloc); + size2 = 0 + #ifndef PPMD_32BIT + + UNIT_SIZE + #endif + ; + p->AlignOffset = + #ifdef PPMD_32BIT + (4 - size) & 3; + #else + 4 - (size & 3); + #endif + if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0) + return False; + p->Size = size; + } + return True; +} + +static void InsertNode(CPpmd7 *p, void *node, unsigned indx) +{ + *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; + p->FreeList[indx] = REF(node); +} + +static void *RemoveNode(CPpmd7 *p, unsigned indx) +{ + CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); + p->FreeList[indx] = *node; + return node; +} + +static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +{ + unsigned i, nu = I2U(oldIndx) - I2U(newIndx); + ptr = (Byte *)ptr + U2B(I2U(newIndx)); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + } + InsertNode(p, ptr, i); +} + +static void GlueFreeBlocks(CPpmd7 *p) +{ + #ifdef PPMD_32BIT + CPpmd7_Node headItem; + CPpmd7_Node_Ref head = &headItem; + #else + CPpmd7_Node_Ref head = p->AlignOffset + p->Size; + #endif + + CPpmd7_Node_Ref n = head; + unsigned i; + + p->GlueCount = 255; + + /* create doubly-linked list of free blocks */ + for (i = 0; i < PPMD_NUM_INDEXES; i++) + { + UInt16 nu = I2U(i); + CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; + p->FreeList[i] = 0; + while (next != 0) + { + CPpmd7_Node *node = NODE(next); + node->Next = n; + n = NODE(n)->Prev = next; + next = *(const CPpmd7_Node_Ref *)node; + node->Stamp = 0; + node->NU = (UInt16)nu; + } + } + NODE(head)->Stamp = 1; + NODE(head)->Next = n; + NODE(n)->Prev = head; + if (p->LoUnit != p->HiUnit) + ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; + + /* Glue free blocks */ + while (n != head) + { + CPpmd7_Node *node = NODE(n); + UInt32 nu = (UInt32)node->NU; + for (;;) + { + CPpmd7_Node *node2 = NODE(n) + nu; + nu += node2->NU; + if (node2->Stamp != 0 || nu >= 0x10000) + break; + NODE(node2->Prev)->Next = node2->Next; + NODE(node2->Next)->Prev = node2->Prev; + node->NU = (UInt16)nu; + } + n = node->Next; + } + + /* Fill lists of free blocks */ + for (n = NODE(head)->Next; n != head;) + { + CPpmd7_Node *node = NODE(n); + unsigned nu; + CPpmd7_Node_Ref next = node->Next; + for (nu = node->NU; nu > 128; nu -= 128, node += 128) + InsertNode(p, node, PPMD_NUM_INDEXES - 1); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + InsertNode(p, node + k, nu - k - 1); + } + InsertNode(p, node, i); + n = next; + } +} + +static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) +{ + unsigned i; + void *retVal; + if (p->GlueCount == 0) + { + GlueFreeBlocks(p); + if (p->FreeList[indx] != 0) + return RemoveNode(p, indx); + } + i = indx; + do + { + if (++i == PPMD_NUM_INDEXES) + { + UInt32 numBytes = U2B(I2U(indx)); + p->GlueCount--; + return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); + } + } + while (p->FreeList[i] == 0); + retVal = RemoveNode(p, i); + SplitBlock(p, retVal, i, indx); + return retVal; +} + +static void *AllocUnits(CPpmd7 *p, unsigned indx) +{ + UInt32 numBytes; + if (p->FreeList[indx] != 0) + return RemoveNode(p, indx); + numBytes = U2B(I2U(indx)); + if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) + { + void *retVal = p->LoUnit; + p->LoUnit += numBytes; + return retVal; + } + return AllocUnitsRare(p, indx); +} + +#define MyMem12Cpy(dest, src, num) \ + { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ + do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); } + +static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) +{ + unsigned i0 = U2I(oldNU); + unsigned i1 = U2I(newNU); + if (i0 == i1) + return oldPtr; + if (p->FreeList[i1] != 0) + { + void *ptr = RemoveNode(p, i1); + MyMem12Cpy(ptr, oldPtr, newNU); + InsertNode(p, oldPtr, i0); + return ptr; + } + SplitBlock(p, oldPtr, i0, i1); + return oldPtr; +} + +#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) + +static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) +{ + (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); + (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); +} + +static void RestartModel(CPpmd7 *p) +{ + unsigned i, k, m; + + memset(p->FreeList, 0, sizeof(p->FreeList)); + p->Text = p->Base + p->AlignOffset; + p->HiUnit = p->Text + p->Size; + p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; + p->GlueCount = 0; + + p->OrderFall = p->MaxOrder; + p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; + p->PrevSuccess = 0; + + p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + p->MinContext->Suffix = 0; + p->MinContext->NumStats = 256; + p->MinContext->SummFreq = 256 + 1; + p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + p->LoUnit += U2B(256 / 2); + p->MinContext->Stats = REF(p->FoundState); + for (i = 0; i < 256; i++) + { + CPpmd_State *s = &p->FoundState[i]; + s->Symbol = (Byte)i; + s->Freq = 1; + SetSuccessor(s, 0); + } + + for (i = 0; i < 128; i++) + for (k = 0; k < 8; k++) + { + UInt16 *dest = p->BinSumm[i] + k; + UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); + for (m = 0; m < 64; m += 8) + dest[m] = val; + } + + for (i = 0; i < 25; i++) + for (k = 0; k < 16; k++) + { + CPpmd_See *s = &p->See[i][k]; + s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); + s->Count = 4; + } +} + +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) +{ + p->MaxOrder = maxOrder; + RestartModel(p); + p->DummySee.Shift = PPMD_PERIOD_BITS; + p->DummySee.Summ = 0; /* unused */ + p->DummySee.Count = 64; /* unused */ +} + +static CTX_PTR CreateSuccessors(CPpmd7 *p, BoolInt skip) +{ + CPpmd_State upState; + CTX_PTR c = p->MinContext; + CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); + CPpmd_State *ps[PPMD7_MAX_ORDER]; + unsigned numPs = 0; + + if (!skip) + ps[numPs++] = p->FoundState; + + while (c->Suffix) + { + CPpmd_Void_Ref successor; + CPpmd_State *s; + c = SUFFIX(c); + if (c->NumStats != 1) + { + for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); + } + else + s = ONE_STATE(c); + successor = SUCCESSOR(s); + if (successor != upBranch) + { + c = CTX(successor); + if (numPs == 0) + return c; + break; + } + ps[numPs++] = s; + } + + upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); + SetSuccessor(&upState, upBranch + 1); + + if (c->NumStats == 1) + upState.Freq = ONE_STATE(c)->Freq; + else + { + UInt32 cf, s0; + CPpmd_State *s; + for (s = STATS(c); s->Symbol != upState.Symbol; s++); + cf = s->Freq - 1; + s0 = c->SummFreq - c->NumStats - cf; + upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); + } + + do + { + /* Create Child */ + CTX_PTR c1; /* = AllocContext(p); */ + if (p->HiUnit != p->LoUnit) + c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); + else if (p->FreeList[0] != 0) + c1 = (CTX_PTR)RemoveNode(p, 0); + else + { + c1 = (CTX_PTR)AllocUnitsRare(p, 0); + if (!c1) + return NULL; + } + c1->NumStats = 1; + *ONE_STATE(c1) = upState; + c1->Suffix = REF(c); + SetSuccessor(ps[--numPs], REF(c1)); + c = c1; + } + while (numPs != 0); + + return c; +} + +static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) +{ + CPpmd_State tmp = *t1; + *t1 = *t2; + *t2 = tmp; +} + +static void UpdateModel(CPpmd7 *p) +{ + CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); + CTX_PTR c; + unsigned s0, ns; + + if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) + { + c = SUFFIX(p->MinContext); + + if (c->NumStats == 1) + { + CPpmd_State *s = ONE_STATE(c); + if (s->Freq < 32) + s->Freq++; + } + else + { + CPpmd_State *s = STATS(c); + if (s->Symbol != p->FoundState->Symbol) + { + do { s++; } while (s->Symbol != p->FoundState->Symbol); + if (s[0].Freq >= s[-1].Freq) + { + SwapStates(&s[0], &s[-1]); + s--; + } + } + if (s->Freq < MAX_FREQ - 9) + { + s->Freq += 2; + c->SummFreq += 2; + } + } + } + + if (p->OrderFall == 0) + { + p->MinContext = p->MaxContext = CreateSuccessors(p, True); + if (p->MinContext == 0) + { + RestartModel(p); + return; + } + SetSuccessor(p->FoundState, REF(p->MinContext)); + return; + } + + *p->Text++ = p->FoundState->Symbol; + successor = REF(p->Text); + if (p->Text >= p->UnitsStart) + { + RestartModel(p); + return; + } + + if (fSuccessor) + { + if (fSuccessor <= successor) + { + CTX_PTR cs = CreateSuccessors(p, False); + if (cs == NULL) + { + RestartModel(p); + return; + } + fSuccessor = REF(cs); + } + if (--p->OrderFall == 0) + { + successor = fSuccessor; + p->Text -= (p->MaxContext != p->MinContext); + } + } + else + { + SetSuccessor(p->FoundState, successor); + fSuccessor = REF(p->MinContext); + } + + s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); + + for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) + { + unsigned ns1; + UInt32 cf, sf; + if ((ns1 = c->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + /* Expand for one UNIT */ + unsigned oldNU = ns1 >> 1; + unsigned i = U2I(oldNU); + if (i != U2I((size_t)oldNU + 1)) + { + void *ptr = AllocUnits(p, i + 1); + void *oldPtr; + if (!ptr) + { + RestartModel(p); + return; + } + oldPtr = STATS(c); + MyMem12Cpy(ptr, oldPtr, oldNU); + InsertNode(p, oldPtr, i); + c->Stats = STATS_REF(ptr); + } + } + c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); + } + else + { + CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); + if (!s) + { + RestartModel(p); + return; + } + *s = *ONE_STATE(c); + c->Stats = REF(s); + if (s->Freq < MAX_FREQ / 4 - 1) + s->Freq <<= 1; + else + s->Freq = MAX_FREQ - 4; + c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); + } + cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); + sf = (UInt32)s0 + c->SummFreq; + if (cf < 6 * sf) + { + cf = 1 + (cf > sf) + (cf >= 4 * sf); + c->SummFreq += 3; + } + else + { + cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); + c->SummFreq = (UInt16)(c->SummFreq + cf); + } + { + CPpmd_State *s = STATS(c) + ns1; + SetSuccessor(s, successor); + s->Symbol = p->FoundState->Symbol; + s->Freq = (Byte)cf; + c->NumStats = (UInt16)(ns1 + 1); + } + } + p->MaxContext = p->MinContext = CTX(fSuccessor); +} + +static void Rescale(CPpmd7 *p) +{ + unsigned i, adder, sumFreq, escFreq; + CPpmd_State *stats = STATS(p->MinContext); + CPpmd_State *s = p->FoundState; + { + CPpmd_State tmp = *s; + for (; s != stats; s--) + s[0] = s[-1]; + *s = tmp; + } + escFreq = p->MinContext->SummFreq - s->Freq; + s->Freq += 4; + adder = (p->OrderFall != 0); + s->Freq = (Byte)((s->Freq + adder) >> 1); + sumFreq = s->Freq; + + i = p->MinContext->NumStats - 1; + do + { + escFreq -= (++s)->Freq; + s->Freq = (Byte)((s->Freq + adder) >> 1); + sumFreq += s->Freq; + if (s[0].Freq > s[-1].Freq) + { + CPpmd_State *s1 = s; + CPpmd_State tmp = *s1; + do + s1[0] = s1[-1]; + while (--s1 != stats && tmp.Freq > s1[-1].Freq); + *s1 = tmp; + } + } + while (--i); + + if (s->Freq == 0) + { + unsigned numStats = p->MinContext->NumStats; + unsigned n0, n1; + do { i++; } while ((--s)->Freq == 0); + escFreq += i; + p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); + if (p->MinContext->NumStats == 1) + { + CPpmd_State tmp = *stats; + do + { + tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); + escFreq >>= 1; + } + while (escFreq > 1); + InsertNode(p, stats, U2I(((numStats + 1) >> 1))); + *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; + return; + } + n0 = (numStats + 1) >> 1; + n1 = (p->MinContext->NumStats + 1) >> 1; + if (n0 != n1) + p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); + } + p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); + p->FoundState = STATS(p->MinContext); +} + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) +{ + CPpmd_See *see; + unsigned nonMasked = p->MinContext->NumStats - numMasked; + if (p->MinContext->NumStats != 256) + { + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] + + (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + + 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + + 4 * (unsigned)(numMasked > nonMasked) + + p->HiBitsFlag; + { + unsigned r = (see->Summ >> see->Shift); + see->Summ = (UInt16)(see->Summ - r); + *escFreq = r + (r == 0); + } + } + else + { + see = &p->DummySee; + *escFreq = 1; + } + return see; +} + +static void NextContext(CPpmd7 *p) +{ + CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + if (p->OrderFall == 0 && (Byte *)c > p->Text) + p->MinContext = p->MaxContext = c; + else + UpdateModel(p); +} + +void Ppmd7_Update1(CPpmd7 *p) +{ + CPpmd_State *s = p->FoundState; + s->Freq += 4; + p->MinContext->SummFreq += 4; + if (s[0].Freq > s[-1].Freq) + { + SwapStates(&s[0], &s[-1]); + p->FoundState = --s; + if (s->Freq > MAX_FREQ) + Rescale(p); + } + NextContext(p); +} + +void Ppmd7_Update1_0(CPpmd7 *p) +{ + p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); + p->RunLength += p->PrevSuccess; + p->MinContext->SummFreq += 4; + if ((p->FoundState->Freq += 4) > MAX_FREQ) + Rescale(p); + NextContext(p); +} + +void Ppmd7_UpdateBin(CPpmd7 *p) +{ + p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); + p->PrevSuccess = 1; + p->RunLength++; + NextContext(p); +} + +void Ppmd7_Update2(CPpmd7 *p) +{ + p->MinContext->SummFreq += 4; + if ((p->FoundState->Freq += 4) > MAX_FREQ) + Rescale(p); + p->RunLength = p->InitRL; + UpdateModel(p); +} diff --git a/components/ota/common/lzma/3rdparty/Ppmd7.h b/components/ota/common/lzma/3rdparty/Ppmd7.h new file mode 100644 index 00000000..610539a0 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Ppmd7.h @@ -0,0 +1,142 @@ +/* Ppmd7.h -- PPMdH compression codec +2018-07-04 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +/* This code supports virtual RangeDecoder and includes the implementation +of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. +If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ + +#ifndef __PPMD7_H +#define __PPMD7_H + +#include "Ppmd.h" + +EXTERN_C_BEGIN + +#define PPMD7_MIN_ORDER 2 +#define PPMD7_MAX_ORDER 64 + +#define PPMD7_MIN_MEM_SIZE (1 << 11) +#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) + +struct CPpmd7_Context_; + +typedef + #ifdef PPMD_32BIT + struct CPpmd7_Context_ * + #else + UInt32 + #endif + CPpmd7_Context_Ref; + +typedef struct CPpmd7_Context_ +{ + UInt16 NumStats; + UInt16 SummFreq; + CPpmd_State_Ref Stats; + CPpmd7_Context_Ref Suffix; +} CPpmd7_Context; + +#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) + +typedef struct +{ + CPpmd7_Context *MinContext, *MaxContext; + CPpmd_State *FoundState; + unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; + Int32 RunLength, InitRL; /* must be 32-bit at least */ + + UInt32 Size; + UInt32 GlueCount; + Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; + UInt32 AlignOffset; + + Byte Indx2Units[PPMD_NUM_INDEXES]; + Byte Units2Indx[128]; + CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; + Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + CPpmd_See DummySee, See[25][16]; + UInt16 BinSumm[128][64]; +} CPpmd7; + +void Ppmd7_Construct(CPpmd7 *p); +BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc); +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc); +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); +#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) + + +/* ---------- Internal Functions ---------- */ + +extern const Byte PPMD7_kExpEscape[16]; + +#ifdef PPMD_32BIT + #define Ppmd7_GetPtr(p, ptr) (ptr) + #define Ppmd7_GetContext(p, ptr) (ptr) + #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) +#else + #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) + #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) + #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) +#endif + +void Ppmd7_Update1(CPpmd7 *p); +void Ppmd7_Update1_0(CPpmd7 *p); +void Ppmd7_Update2(CPpmd7 *p); +void Ppmd7_UpdateBin(CPpmd7 *p); + +#define Ppmd7_GetBinSumm(p) \ + &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ + p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ + (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ + 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \ + ((p->RunLength >> 26) & 0x20)] + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); + + +/* ---------- Decode ---------- */ + +typedef struct IPpmd7_RangeDec IPpmd7_RangeDec; + +struct IPpmd7_RangeDec +{ + UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total); + void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size); + UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0); +}; + +typedef struct +{ + IPpmd7_RangeDec vt; + UInt32 Range; + UInt32 Code; + IByteIn *Stream; +} CPpmd7z_RangeDec; + +void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); +BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); +#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) + +int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc); + + +/* ---------- Encode ---------- */ + +typedef struct +{ + UInt64 Low; + UInt32 Range; + Byte Cache; + UInt64 CacheSize; + IByteOut *Stream; +} CPpmd7z_RangeEnc; + +void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); +void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); + +void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Ppmd7Dec.c b/components/ota/common/lzma/3rdparty/Ppmd7Dec.c new file mode 100644 index 00000000..311e9f9d --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Ppmd7Dec.c @@ -0,0 +1,191 @@ +/* Ppmd7Dec.c -- PPMdH Decoder +2018-07-04 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTopValue (1 << 24) + +BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) +{ + unsigned i; + p->Code = 0; + p->Range = 0xFFFFFFFF; + if (IByteIn_Read(p->Stream) != 0) + return False; + for (i = 0; i < 4; i++) + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); + return (p->Code < 0xFFFFFFFF); +} + +#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt); + +static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total) +{ + GET_Ppmd7z_RangeDec + return p->Code / (p->Range /= total); +} + +static void Range_Normalize(CPpmd7z_RangeDec *p) +{ + if (p->Range < kTopValue) + { + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); + p->Range <<= 8; + if (p->Range < kTopValue) + { + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); + p->Range <<= 8; + } + } +} + +static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size) +{ + GET_Ppmd7z_RangeDec + p->Code -= start * p->Range; + p->Range *= size; + Range_Normalize(p); +} + +static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0) +{ + GET_Ppmd7z_RangeDec + UInt32 newBound = (p->Range >> 14) * size0; + UInt32 symbol; + if (p->Code < newBound) + { + symbol = 0; + p->Range = newBound; + } + else + { + symbol = 1; + p->Code -= newBound; + p->Range -= newBound; + } + Range_Normalize(p); + return symbol; +} + +void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) +{ + p->vt.GetThreshold = Range_GetThreshold; + p->vt.Decode = Range_Decode; + p->vt.DecodeBit = Range_DecodeBit; +} + + +#define MASK(sym) ((signed char *)charMask)[sym] + +int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc) +{ + size_t charMask[256 / sizeof(size_t)]; + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + unsigned i; + UInt32 count, hiCnt; + if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) + { + Byte symbol; + rc->Decode(rc, 0, s->Freq); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update1_0(p); + return symbol; + } + p->PrevSuccess = 0; + i = p->MinContext->NumStats - 1; + do + { + if ((hiCnt += (++s)->Freq) > count) + { + Byte symbol; + rc->Decode(rc, hiCnt - s->Freq, s->Freq); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update1(p); + return symbol; + } + } + while (--i); + if (count >= p->MinContext->SummFreq) + return -2; + p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; + rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(s->Symbol) = 0; + i = p->MinContext->NumStats - 1; + do { MASK((--s)->Symbol) = 0; } while (--i); + } + else + { + UInt16 *prob = Ppmd7_GetBinSumm(p); + if (rc->DecodeBit(rc, *prob) == 0) + { + Byte symbol; + *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); + symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; + Ppmd7_UpdateBin(p); + return symbol; + } + *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); + p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; + p->PrevSuccess = 0; + } + for (;;) + { + CPpmd_State *ps[256], *s; + UInt32 freqSum, count, hiCnt; + CPpmd_See *see; + unsigned i, num, numMasked = p->MinContext->NumStats; + do + { + p->OrderFall++; + if (!p->MinContext->Suffix) + return -1; + p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); + } + while (p->MinContext->NumStats == numMasked); + hiCnt = 0; + s = Ppmd7_GetStats(p, p->MinContext); + i = 0; + num = p->MinContext->NumStats - numMasked; + do + { + int k = (int)(MASK(s->Symbol)); + hiCnt += (s->Freq & k); + ps[i] = s++; + i -= k; + } + while (i != num); + + see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); + freqSum += hiCnt; + count = rc->GetThreshold(rc, freqSum); + + if (count < hiCnt) + { + Byte symbol; + CPpmd_State **pps = ps; + for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); + s = *pps; + rc->Decode(rc, hiCnt - s->Freq, s->Freq); + Ppmd_See_Update(see); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update2(p); + return symbol; + } + if (count >= freqSum) + return -2; + rc->Decode(rc, hiCnt, freqSum - hiCnt); + see->Summ = (UInt16)(see->Summ + freqSum); + do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); + } +} diff --git a/components/ota/common/lzma/3rdparty/Ppmd7Enc.c b/components/ota/common/lzma/3rdparty/Ppmd7Enc.c new file mode 100644 index 00000000..286b8712 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Ppmd7Enc.c @@ -0,0 +1,187 @@ +/* Ppmd7Enc.c -- PPMdH Encoder +2017-04-03 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTopValue (1 << 24) + +void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p) +{ + p->Low = 0; + p->Range = 0xFFFFFFFF; + p->Cache = 0; + p->CacheSize = 1; +} + +static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) +{ + if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0) + { + Byte temp = p->Cache; + do + { + IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); + temp = 0xFF; + } + while (--p->CacheSize != 0); + p->Cache = (Byte)((UInt32)p->Low >> 24); + } + p->CacheSize++; + p->Low = (UInt32)p->Low << 8; +} + +static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) +{ + p->Low += start * (p->Range /= total); + p->Range *= size; + while (p->Range < kTopValue) + { + p->Range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0) +{ + p->Range = (p->Range >> 14) * size0; + while (p->Range < kTopValue) + { + p->Range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0) +{ + UInt32 newBound = (p->Range >> 14) * size0; + p->Low += newBound; + p->Range -= newBound; + while (p->Range < kTopValue) + { + p->Range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p) +{ + unsigned i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + + +#define MASK(sym) ((signed char *)charMask)[sym] + +void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol) +{ + size_t charMask[256 / sizeof(size_t)]; + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + UInt32 sum; + unsigned i; + if (s->Symbol == symbol) + { + RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq); + p->FoundState = s; + Ppmd7_Update1_0(p); + return; + } + p->PrevSuccess = 0; + sum = s->Freq; + i = p->MinContext->NumStats - 1; + do + { + if ((++s)->Symbol == symbol) + { + RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq); + p->FoundState = s; + Ppmd7_Update1(p); + return; + } + sum += s->Freq; + } + while (--i); + + p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(s->Symbol) = 0; + i = p->MinContext->NumStats - 1; + do { MASK((--s)->Symbol) = 0; } while (--i); + RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); + } + else + { + UInt16 *prob = Ppmd7_GetBinSumm(p); + CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); + if (s->Symbol == symbol) + { + RangeEnc_EncodeBit_0(rc, *prob); + *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); + p->FoundState = s; + Ppmd7_UpdateBin(p); + return; + } + else + { + RangeEnc_EncodeBit_1(rc, *prob); + *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); + p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(s->Symbol) = 0; + p->PrevSuccess = 0; + } + } + for (;;) + { + UInt32 escFreq; + CPpmd_See *see; + CPpmd_State *s; + UInt32 sum; + unsigned i, numMasked = p->MinContext->NumStats; + do + { + p->OrderFall++; + if (!p->MinContext->Suffix) + return; /* EndMarker (symbol = -1) */ + p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); + } + while (p->MinContext->NumStats == numMasked); + + see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); + s = Ppmd7_GetStats(p, p->MinContext); + sum = 0; + i = p->MinContext->NumStats; + do + { + int cur = s->Symbol; + if (cur == symbol) + { + UInt32 low = sum; + CPpmd_State *s1 = s; + do + { + sum += (s->Freq & (int)(MASK(s->Symbol))); + s++; + } + while (--i); + RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq); + Ppmd_See_Update(see); + p->FoundState = s1; + Ppmd7_Update2(p); + return; + } + sum += (s->Freq & (int)(MASK(cur))); + MASK(cur) = 0; + s++; + } + while (--i); + + RangeEnc_Encode(rc, sum, escFreq, sum + escFreq); + see->Summ = (UInt16)(see->Summ + sum + escFreq); + } +} diff --git a/components/ota/common/lzma/3rdparty/Precomp.h b/components/ota/common/lzma/3rdparty/Precomp.h new file mode 100644 index 00000000..e8ff8b40 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Precomp.h @@ -0,0 +1,10 @@ +/* Precomp.h -- StdAfx +2013-11-12 : Igor Pavlov : Public domain */ + +#ifndef __7Z_PRECOMP_H +#define __7Z_PRECOMP_H + +#include "Compiler.h" +/* #include "7zTypes.h" */ + +#endif diff --git a/components/ota/common/lzma/3rdparty/RotateDefs.h b/components/ota/common/lzma/3rdparty/RotateDefs.h new file mode 100644 index 00000000..8f01d1a6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/RotateDefs.h @@ -0,0 +1,30 @@ +/* RotateDefs.h -- Rotate functions +2015-03-25 : Igor Pavlov : Public domain */ + +#ifndef __ROTATE_DEFS_H +#define __ROTATE_DEFS_H + +#ifdef _MSC_VER + +#include + +/* don't use _rotl with MINGW. It can insert slow call to function. */ + +/* #if (_MSC_VER >= 1200) */ +#pragma intrinsic(_rotl) +#pragma intrinsic(_rotr) +/* #endif */ + +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#else + +/* new compilers can translate these macros to fast commands. */ + +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) + +#endif + +#endif diff --git a/components/ota/common/lzma/3rdparty/Sha256.c b/components/ota/common/lzma/3rdparty/Sha256.c new file mode 100644 index 00000000..04b688c6 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Sha256.c @@ -0,0 +1,248 @@ +/* Crypto/Sha256.c -- SHA-256 Hash +2017-04-03 : Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "CpuArch.h" +#include "RotateDefs.h" +#include "Sha256.h" + +/* define it for speed optimization */ +#ifndef _SFX +#define _SHA256_UNROLL +#define _SHA256_UNROLL2 +#endif + +/* #define _SHA256_UNROLL2 */ + +void Sha256_Init(CSha256 *p) +{ + p->state[0] = 0x6a09e667; + p->state[1] = 0xbb67ae85; + p->state[2] = 0x3c6ef372; + p->state[3] = 0xa54ff53a; + p->state[4] = 0x510e527f; + p->state[5] = 0x9b05688c; + p->state[6] = 0x1f83d9ab; + p->state[7] = 0x5be0cd19; + p->count = 0; +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) + +#define blk0(i) (W[i]) +#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#ifdef _SHA256_UNROLL2 + +#define R(a,b,c,d,e,f,g,h, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \ + d += h; \ + h += S0(a) + Maj(a, b, c) + +#define RX_8(i) \ + R(a,b,c,d,e,f,g,h, i); \ + R(h,a,b,c,d,e,f,g, i+1); \ + R(g,h,a,b,c,d,e,f, i+2); \ + R(f,g,h,a,b,c,d,e, i+3); \ + R(e,f,g,h,a,b,c,d, i+4); \ + R(d,e,f,g,h,a,b,c, i+5); \ + R(c,d,e,f,g,h,a,b, i+6); \ + R(b,c,d,e,f,g,h,a, i+7) + +#define RX_16 RX_8(0); RX_8(8); + +#else + +#define a(i) T[(0-(i))&7] +#define b(i) T[(1-(i))&7] +#define c(i) T[(2-(i))&7] +#define d(i) T[(3-(i))&7] +#define e(i) T[(4-(i))&7] +#define f(i) T[(5-(i))&7] +#define g(i) T[(6-(i))&7] +#define h(i) T[(7-(i))&7] + +#define R(i) \ + h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \ + d(i) += h(i); \ + h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \ + +#ifdef _SHA256_UNROLL + +#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); +#define RX_16 RX_8(0); RX_8(8); + +#else + +#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); } + +#endif + +#endif + +static const UInt32 K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void Sha256_WriteByteBlock(CSha256 *p) +{ + UInt32 W[16]; + unsigned j; + UInt32 *state; + + #ifdef _SHA256_UNROLL2 + UInt32 a,b,c,d,e,f,g,h; + #else + UInt32 T[8]; + #endif + + for (j = 0; j < 16; j += 4) + { + const Byte *ccc = p->buffer + j * 4; + W[j ] = GetBe32(ccc); + W[j + 1] = GetBe32(ccc + 4); + W[j + 2] = GetBe32(ccc + 8); + W[j + 3] = GetBe32(ccc + 12); + } + + state = p->state; + + #ifdef _SHA256_UNROLL2 + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + #else + for (j = 0; j < 8; j++) + T[j] = state[j]; + #endif + + for (j = 0; j < 64; j += 16) + { + RX_16 + } + + #ifdef _SHA256_UNROLL2 + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + #else + for (j = 0; j < 8; j++) + state[j] += T[j]; + #endif + + /* Wipe variables */ + /* memset(W, 0, sizeof(W)); */ + /* memset(T, 0, sizeof(T)); */ +} + +#undef S0 +#undef S1 +#undef s0 +#undef s1 + +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + + { + unsigned pos = (unsigned)p->count & 0x3F; + unsigned num; + + p->count += size; + + num = 64 - pos; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + } + + for (;;) + { + Sha256_WriteByteBlock(p); + if (size < 64) + break; + size -= 64; + memcpy(p->buffer, data, 64); + data += 64; + } + + if (size != 0) + memcpy(p->buffer, data, size); +} + +void Sha256_Final(CSha256 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->count & 0x3F; + unsigned i; + + p->buffer[pos++] = 0x80; + + while (pos != (64 - 8)) + { + pos &= 0x3F; + if (pos == 0) + Sha256_WriteByteBlock(p); + p->buffer[pos++] = 0; + } + + { + UInt64 numBits = (p->count << 3); + SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); + SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); + } + + Sha256_WriteByteBlock(p); + + for (i = 0; i < 8; i += 2) + { + UInt32 v0 = p->state[i]; + UInt32 v1 = p->state[i + 1]; + SetBe32(digest , v0); + SetBe32(digest + 4, v1); + digest += 8; + } + + Sha256_Init(p); +} diff --git a/components/ota/common/lzma/3rdparty/Sha256.h b/components/ota/common/lzma/3rdparty/Sha256.h new file mode 100644 index 00000000..3f455dbc --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Sha256.h @@ -0,0 +1,26 @@ +/* Sha256.h -- SHA-256 Hash +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __CRYPTO_SHA256_H +#define __CRYPTO_SHA256_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA256_DIGEST_SIZE 32 + +typedef struct +{ + UInt32 state[8]; + UInt64 count; + Byte buffer[64]; +} CSha256; + +void Sha256_Init(CSha256 *p); +void Sha256_Update(CSha256 *p, const Byte *data, size_t size); +void Sha256_Final(CSha256 *p, Byte *digest); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Sort.c b/components/ota/common/lzma/3rdparty/Sort.c new file mode 100644 index 00000000..e1097e38 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Sort.c @@ -0,0 +1,141 @@ +/* Sort.c -- Sort functions +2014-04-05 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Sort.h" + +#define HeapSortDown(p, k, size, temp) \ + { for (;;) { \ + size_t s = (k << 1); \ + if (s > size) break; \ + if (s < size && p[s + 1] > p[s]) s++; \ + if (temp >= p[s]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSort(UInt32 *p, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp) + } + while (--i != 0); + } + /* + do + { + size_t k = 1; + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortDown(p, k, size, temp) + } + while (size > 1); + */ + while (size > 3) + { + UInt32 temp = p[size]; + size_t k = (p[3] > p[2]) ? 3 : 2; + p[size--] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp) + } + { + UInt32 temp = p[size]; + p[size] = p[1]; + if (size > 2 && p[2] < temp) + { + p[1] = p[2]; + p[2] = temp; + } + else + p[1] = temp; + } +} + +void HeapSort64(UInt64 *p, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt64 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp) + } + while (--i != 0); + } + /* + do + { + size_t k = 1; + UInt64 temp = p[size]; + p[size--] = p[1]; + HeapSortDown(p, k, size, temp) + } + while (size > 1); + */ + while (size > 3) + { + UInt64 temp = p[size]; + size_t k = (p[3] > p[2]) ? 3 : 2; + p[size--] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp) + } + { + UInt64 temp = p[size]; + p[size] = p[1]; + if (size > 2 && p[2] < temp) + { + p[1] = p[2]; + p[2] = temp; + } + else + p[1] = temp; + } +} + +/* +#define HeapSortRefDown(p, vals, n, size, temp) \ + { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ + size_t s = (k << 1); \ + if (s > size) break; \ + if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ + if (val >= vals[p[s]]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + HeapSortRefDown(p, vals, i, size, temp); + } + while (--i != 0); + } + do + { + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortRefDown(p, vals, 1, size, temp); + } + while (size > 1); +} +*/ diff --git a/components/ota/common/lzma/3rdparty/Sort.h b/components/ota/common/lzma/3rdparty/Sort.h new file mode 100644 index 00000000..2e2963a2 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Sort.h @@ -0,0 +1,18 @@ +/* Sort.h -- Sort functions +2014-04-05 : Igor Pavlov : Public domain */ + +#ifndef __7Z_SORT_H +#define __7Z_SORT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void HeapSort(UInt32 *p, size_t size); +void HeapSort64(UInt64 *p, size_t size); + +/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/Xz.c b/components/ota/common/lzma/3rdparty/Xz.c new file mode 100644 index 00000000..d9f83df1 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Xz.c @@ -0,0 +1,90 @@ +/* Xz.c - Xz +2017-05-12 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zCrc.h" +#include "CpuArch.h" +#include "Xz.h" +#include "XzCrc64.h" + +const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 }; +/* const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; */ + +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v) +{ + unsigned i = 0; + do + { + buf[i++] = (Byte)((v & 0x7F) | 0x80); + v >>= 7; + } + while (v != 0); + buf[(size_t)i - 1] &= 0x7F; + return i; +} + +void Xz_Construct(CXzStream *p) +{ + p->numBlocks = 0; + p->blocks = NULL; + p->flags = 0; +} + +void Xz_Free(CXzStream *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->blocks); + p->numBlocks = 0; + p->blocks = NULL; +} + +unsigned XzFlags_GetCheckSize(CXzStreamFlags f) +{ + unsigned t = XzFlags_GetCheckType(f); + return (t == 0) ? 0 : (4 << ((t - 1) / 3)); +} + +void XzCheck_Init(CXzCheck *p, unsigned mode) +{ + p->mode = mode; + switch (mode) + { + case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; + case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; + case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; + } +} + +void XzCheck_Update(CXzCheck *p, const void *data, size_t size) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; + case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; + case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; + } +} + +int XzCheck_Final(CXzCheck *p, Byte *digest) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: + SetUi32(digest, CRC_GET_DIGEST(p->crc)); + break; + case XZ_CHECK_CRC64: + { + int i; + UInt64 v = CRC64_GET_DIGEST(p->crc64); + for (i = 0; i < 8; i++, v >>= 8) + digest[i] = (Byte)(v & 0xFF); + break; + } + case XZ_CHECK_SHA256: + Sha256_Final(&p->sha, digest); + break; + default: + return 0; + } + return 1; +} diff --git a/components/ota/common/lzma/3rdparty/Xz.h b/components/ota/common/lzma/3rdparty/Xz.h new file mode 100644 index 00000000..544ee18f --- /dev/null +++ b/components/ota/common/lzma/3rdparty/Xz.h @@ -0,0 +1,460 @@ +/* Xz.h - Xz interface +2018-07-04 : Igor Pavlov : Public domain */ + +#ifndef __XZ_H +#define __XZ_H + +#include "Sha256.h" + +EXTERN_C_BEGIN + +#define XZ_ID_Subblock 1 +#define XZ_ID_Delta 3 +#define XZ_ID_X86 4 +#define XZ_ID_PPC 5 +#define XZ_ID_IA64 6 +#define XZ_ID_ARM 7 +#define XZ_ID_ARMT 8 +#define XZ_ID_SPARC 9 +#define XZ_ID_LZMA2 0x21 + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); + +/* ---------- xz block ---------- */ + +#define XZ_BLOCK_HEADER_SIZE_MAX 1024 + +#define XZ_NUM_FILTERS_MAX 4 +#define XZ_BF_NUM_FILTERS_MASK 3 +#define XZ_BF_PACK_SIZE (1 << 6) +#define XZ_BF_UNPACK_SIZE (1 << 7) + +#define XZ_FILTER_PROPS_SIZE_MAX 20 + +typedef struct +{ + UInt64 id; + UInt32 propsSize; + Byte props[XZ_FILTER_PROPS_SIZE_MAX]; +} CXzFilter; + +typedef struct +{ + UInt64 packSize; + UInt64 unpackSize; + Byte flags; + CXzFilter filters[XZ_NUM_FILTERS_MAX]; +} CXzBlock; + +#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) +#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) +#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) +#define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0) + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header); +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes); + +/* ---------- xz stream ---------- */ + +#define XZ_SIG_SIZE 6 +#define XZ_FOOTER_SIG_SIZE 2 + +extern const Byte XZ_SIG[XZ_SIG_SIZE]; + +/* +extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; +*/ + +#define XZ_FOOTER_SIG_0 'Y' +#define XZ_FOOTER_SIG_1 'Z' + +#define XZ_STREAM_FLAGS_SIZE 2 +#define XZ_STREAM_CRC_SIZE 4 + +#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) +#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) + +#define XZ_CHECK_MASK 0xF +#define XZ_CHECK_NO 0 +#define XZ_CHECK_CRC32 1 +#define XZ_CHECK_CRC64 4 +#define XZ_CHECK_SHA256 10 + +typedef struct +{ + unsigned mode; + UInt32 crc; + UInt64 crc64; + CSha256 sha; +} CXzCheck; + +void XzCheck_Init(CXzCheck *p, unsigned mode); +void XzCheck_Update(CXzCheck *p, const void *data, size_t size); +int XzCheck_Final(CXzCheck *p, Byte *digest); + +typedef UInt16 CXzStreamFlags; + +#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) +#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) +#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) +unsigned XzFlags_GetCheckSize(CXzStreamFlags f); + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; +} CXzBlockSizes; + +typedef struct +{ + CXzStreamFlags flags; + size_t numBlocks; + CXzBlockSizes *blocks; + UInt64 startOffset; +} CXzStream; + +void Xz_Construct(CXzStream *p); +void Xz_Free(CXzStream *p, ISzAllocPtr alloc); + +#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) + +UInt64 Xz_GetUnpackSize(const CXzStream *p); +UInt64 Xz_GetPackSize(const CXzStream *p); + +typedef struct +{ + size_t num; + size_t numAllocated; + CXzStream *streams; +} CXzs; + +void Xzs_Construct(CXzs *p); +void Xzs_Free(CXzs *p, ISzAllocPtr alloc); +SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc); + +UInt64 Xzs_GetNumBlocks(const CXzs *p); +UInt64 Xzs_GetUnpackSize(const CXzs *p); + + +// ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + +typedef enum +{ + CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ + CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + CODER_STATUS_NOT_FINISHED, /* stream was not finished */ + CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ +} ECoderStatus; + + +// ECoderFinishMode values are identical to ELzmaFinishMode + +typedef enum +{ + CODER_FINISH_ANY, /* finish at any point */ + CODER_FINISH_END /* block must be finished at the end */ +} ECoderFinishMode; + + +typedef struct _IStateCoder +{ + void *p; + void (*Free)(void *p, ISzAllocPtr alloc); + SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); + void (*Init)(void *p); + SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status); + SizeT (*Filter)(void *p, Byte *data, SizeT size); +} IStateCoder; + + + +#define MIXCODER_NUM_FILTERS_MAX 4 + +typedef struct +{ + ISzAllocPtr alloc; + Byte *buf; + unsigned numCoders; + + Byte *outBuf; + size_t outBufSize; + size_t outWritten; // is equal to lzmaDecoder.dicPos (in outBuf mode) + BoolInt wasFinished; + SRes res; + ECoderStatus status; + // BoolInt SingleBufMode; + + int finished[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; + UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; + SRes results[MIXCODER_NUM_FILTERS_MAX]; + IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; +} CMixCoder; + + +typedef enum +{ + XZ_STATE_STREAM_HEADER, + XZ_STATE_STREAM_INDEX, + XZ_STATE_STREAM_INDEX_CRC, + XZ_STATE_STREAM_FOOTER, + XZ_STATE_STREAM_PADDING, + XZ_STATE_BLOCK_HEADER, + XZ_STATE_BLOCK, + XZ_STATE_BLOCK_FOOTER +} EXzState; + + +typedef struct +{ + EXzState state; + UInt32 pos; + unsigned alignPos; + unsigned indexPreSize; + + CXzStreamFlags streamFlags; + + UInt32 blockHeaderSize; + UInt64 packSize; + UInt64 unpackSize; + + UInt64 numBlocks; // number of finished blocks in current stream + UInt64 indexSize; + UInt64 indexPos; + UInt64 padSize; + + UInt64 numStartedStreams; + UInt64 numFinishedStreams; + UInt64 numTotalBlocks; + + UInt32 crc; + CMixCoder decoder; + CXzBlock block; + CXzCheck check; + CSha256 sha; + + BoolInt parseMode; + BoolInt headerParsedOk; + BoolInt decodeToStreamSignature; + unsigned decodeOnlyOneBlock; + + Byte *outBuf; + size_t outBufSize; + size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked + + Byte shaDigest[SHA256_DIGEST_SIZE]; + Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; +} CXzUnpacker; + +/* alloc : aligned for cache line allocation is better */ +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc); +void XzUnpacker_Init(CXzUnpacker *p); +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize); +void XzUnpacker_Free(CXzUnpacker *p); + +/* + XzUnpacker + The sequence for decoding functions: + { + XzUnpacker_Construct() + [Decoding_Calls] + XzUnpacker_Free() + } + + [Decoding_Calls] + + There are 3 types of interfaces for [Decoding_Calls] calls: + + Interface-1 : Partial output buffers: + { + XzUnpacker_Init() + for() + XzUnpacker_Code(); + } + + Interface-2 : Direct output buffer: + Use it, if you know exact size of decoded data, and you need + whole xz unpacked data in one output buffer. + xz unpacker doesn't allocate additional buffer for lzma2 dictionary in that mode. + { + XzUnpacker_Init() + XzUnpacker_SetOutBufMode(); // to set output buffer and size + for() + XzUnpacker_Code(); // (dest = NULL) in XzUnpacker_Code() + } + + Interface-3 : Direct output buffer : One call full decoding + It unpacks whole input buffer to output buffer in one call. + It uses Interface-2 internally. + { + XzUnpacker_CodeFull() + } +*/ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + CODER_FINISH_ANY - use smallest number of input bytes + CODER_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + CODER_STATUS_NOT_FINISHED, + CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams, + call XzUnpacker_IsStreamWasFinished to check that current stream was finished + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_DATA - Data error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC error + // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + + SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: + - xz Stream Signature failure + - CRC32 of xz Stream Header is failed + - The size of Stream padding is not multiple of four bytes. + It's possible to get that error, if xz stream was finished and the stream + contains some another data. In that case you can call XzUnpacker_GetExtraSize() + function to get real size of xz stream. +*/ + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status); + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status); + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p); + +/* +XzUnpacker_GetExtraSize() returns then number of uncofirmed bytes, + if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state. +These bytes can be some bytes after xz archive, or +it can be start of new xz stream. + +Call XzUnpacker_GetExtraSize() after XzUnpacker_Code() function to detect real size of +xz stream in two cases, if XzUnpacker_Code() returns: + res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT + res == SZ_ERROR_NO_ARCHIVE +*/ + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p); + + +/* + for random block decoding: + XzUnpacker_Init(); + set CXzUnpacker::streamFlags + XzUnpacker_PrepareToRandomBlockDecoding() + loop + { + XzUnpacker_Code() + XzUnpacker_IsBlockFinished() + } +*/ + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p); +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p); + +#define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags)) + + + +/* ---------- Multi Threading Decoding ---------- */ + + +typedef struct +{ + size_t inBufSize_ST; + size_t outStep_ST; + BoolInt ignoreErrors; + + #ifndef _7ZIP_ST + unsigned numThreads; + size_t inBufSize_MT; + size_t memUseMax; + #endif +} CXzDecMtProps; + +void XzDecMtProps_Init(CXzDecMtProps *p); + + +typedef void * CXzDecMtHandle; + +/* + alloc : XzDecMt uses CAlignOffsetAlloc for addresses allocated by (alloc). + allocMid : for big allocations, aligned allocation is better +*/ + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); +void XzDecMt_Destroy(CXzDecMtHandle p); + + +typedef struct +{ + Byte UnpackSize_Defined; + Byte NumStreams_Defined; + Byte NumBlocks_Defined; + + Byte DataAfterEnd; + Byte DecodingTruncated; // Decoding was Truncated, we need only partial output data + + UInt64 InSize; // pack size processed + UInt64 OutSize; + + UInt64 NumStreams; + UInt64 NumBlocks; + + SRes DecodeRes; + SRes ReadRes; + SRes ProgressRes; + SRes CombinedRes; + SRes CombinedRes_Type; + +} CXzStatInfo; + +void XzStatInfo_Clear(CXzStatInfo *p); + +/* +XzDecMt_Decode() +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_NO_ARCHIVE - is not xz archive + SZ_ERROR_ARCHIVE - Headers error + SZ_ERROR_DATA - Data Error + SZ_ERROR_CRC - CRC Error + SZ_ERROR_INPUT_EOF - it needs more input data + SZ_ERROR_WRITE - ISeqOutStream error + (SZ_ERROR_READ) - ISeqInStream errors + (SZ_ERROR_PROGRESS) - ICompressProgress errors + // SZ_ERROR_THREAD - error in multi-threading functions + MY_SRes_HRESULT_FROM_WRes(WRes_error) - error in multi-threading function +*/ + +SRes XzDecMt_Decode(CXzDecMtHandle p, + const CXzDecMtProps *props, + const UInt64 *outDataSize, // NULL means undefined + int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished + ISeqOutStream *outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStream *inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, + int *isMT, // 0 means that ST (Single-Thread) version was used + ICompressProgress *progress); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/XzCrc64.c b/components/ota/common/lzma/3rdparty/XzCrc64.c new file mode 100644 index 00000000..b6d02cbe --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzCrc64.c @@ -0,0 +1,86 @@ +/* XzCrc64.c -- CRC64 calculation +2017-05-23 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "XzCrc64.h" +#include "CpuArch.h" + +#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) + +#ifdef MY_CPU_LE + #define CRC64_NUM_TABLES 4 +#else + #define CRC64_NUM_TABLES 5 + #define CRC_UINT64_SWAP(v) \ + ((v >> 56) \ + | ((v >> 40) & ((UInt64)0xFF << 8)) \ + | ((v >> 24) & ((UInt64)0xFF << 16)) \ + | ((v >> 8) & ((UInt64)0xFF << 24)) \ + | ((v << 8) & ((UInt64)0xFF << 32)) \ + | ((v << 24) & ((UInt64)0xFF << 40)) \ + | ((v << 40) & ((UInt64)0xFF << 48)) \ + | ((v << 56))) + + UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#ifndef MY_CPU_BE + UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +typedef UInt64 (MY_FAST_CALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); + +static CRC64_FUNC g_Crc64Update; +UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES]; + +UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) +{ + return g_Crc64Update(v, data, size, g_Crc64Table); +} + +UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) +{ + return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; +} + +void MY_FAST_CALL Crc64GenerateTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt64 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); + g_Crc64Table[i] = r; + } + for (i = 256; i < 256 * CRC64_NUM_TABLES; i++) + { + UInt64 r = g_Crc64Table[(size_t)i - 256]; + g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); + } + + #ifdef MY_CPU_LE + + g_Crc64Update = XzCrc64UpdateT4; + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + g_Crc64Update = XzCrc64UpdateT4; + else + #endif + { + for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--) + { + UInt64 x = g_Crc64Table[(size_t)i - 256]; + g_Crc64Table[i] = CRC_UINT64_SWAP(x); + } + g_Crc64Update = XzCrc64UpdateT1_BeT4; + } + } + #endif +} diff --git a/components/ota/common/lzma/3rdparty/XzCrc64.h b/components/ota/common/lzma/3rdparty/XzCrc64.h new file mode 100644 index 00000000..08dbc330 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzCrc64.h @@ -0,0 +1,26 @@ +/* XzCrc64.h -- CRC64 calculation +2013-01-18 : Igor Pavlov : Public domain */ + +#ifndef __XZ_CRC64_H +#define __XZ_CRC64_H + +#include + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +extern UInt64 g_Crc64Table[]; + +void MY_FAST_CALL Crc64GenerateTable(void); + +#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) +#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) +#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size); +UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/XzCrc64Opt.c b/components/ota/common/lzma/3rdparty/XzCrc64Opt.c new file mode 100644 index 00000000..b2852de4 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzCrc64Opt.c @@ -0,0 +1,69 @@ +/* XzCrc64Opt.c -- CRC64 calculation +2017-06-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#ifndef MY_CPU_BE + +#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + UInt32 d = (UInt32)v ^ *(const UInt32 *)p; + v = (v >> 32) + ^ (table + 0x300)[((d ) & 0xFF)] + ^ (table + 0x200)[((d >> 8) & 0xFF)] + ^ (table + 0x100)[((d >> 16) & 0xFF)] + ^ (table + 0x000)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif + + +#ifndef MY_CPU_LE + +#define CRC_UINT64_SWAP(v) \ + ((v >> 56) \ + | ((v >> 40) & ((UInt64)0xFF << 8)) \ + | ((v >> 24) & ((UInt64)0xFF << 16)) \ + | ((v >> 8) & ((UInt64)0xFF << 24)) \ + | ((v << 8) & ((UInt64)0xFF << 32)) \ + | ((v << 24) & ((UInt64)0xFF << 40)) \ + | ((v << 40) & ((UInt64)0xFF << 48)) \ + | ((v << 56))) + +#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8)) + +UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + table += 0x100; + v = CRC_UINT64_SWAP(v); + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p; + v = (v << 32) + ^ (table + 0x000)[((d ) & 0xFF)] + ^ (table + 0x100)[((d >> 8) & 0xFF)] + ^ (table + 0x200)[((d >> 16) & 0xFF)] + ^ (table + 0x300)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + return CRC_UINT64_SWAP(v); +} + +#endif diff --git a/components/ota/common/lzma/3rdparty/XzDec.c b/components/ota/common/lzma/3rdparty/XzDec.c new file mode 100644 index 00000000..bd31cfca --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzDec.c @@ -0,0 +1,2768 @@ +/* XzDec.c -- Xz Decode +2019-02-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +// #define XZ_DUMP + +/* #define XZ_DUMP */ + +#define _7ZIP_ST + +#ifdef XZ_DUMP +#include +#endif + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define PRF_STR(s) PRF(printf("\n" s "\n")) +#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) + +#include +#include + +#include "7zCrc.h" +#include "Alloc.h" +#include "Bra.h" +#include "CpuArch.h" +#include "Delta.h" +#include "Lzma2Dec.h" + +// #define USE_SUBBLOCK + +#ifdef USE_SUBBLOCK +#include "Bcj3Dec.c" +#include "SbDec.h" +#endif + +#include "Xz.h" + +#define XZ_CHECK_SIZE_MAX 64 + +#define CODER_BUF_SIZE ((size_t)1 << 17) + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) +{ + unsigned i, limit; + *value = 0; + limit = (maxSize > 9) ? 9 : (unsigned)maxSize; + + for (i = 0; i < limit;) + { + Byte b = p[i]; + *value |= (UInt64)(b & 0x7F) << (7 * i++); + if ((b & 0x80) == 0) + return (b == 0 && i != 1) ? 0 : i; + } + return 0; +} + +/* ---------- BraState ---------- */ + +#define BRA_BUF_SIZE (1 << 14) + +typedef struct +{ + size_t bufPos; + size_t bufConv; + size_t bufTotal; + + int encodeMode; + + UInt32 methodId; + UInt32 delta; + UInt32 ip; + UInt32 x86State; + Byte deltaState[DELTA_STATE_SIZE]; + + Byte buf[BRA_BUF_SIZE]; +} CBraState; + +static void BraState_Free(void *pp, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, pp); +} + +static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + CBraState *p = ((CBraState *)pp); + UNUSED_VAR(alloc); + p->ip = 0; + if (p->methodId == XZ_ID_Delta) + { + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + p->delta = (unsigned)props[0] + 1; + } + else + { + if (propSize == 4) + { + UInt32 v = GetUi32(props); + switch (p->methodId) + { + case XZ_ID_PPC: + case XZ_ID_ARM: + case XZ_ID_SPARC: + if ((v & 3) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_ARMT: + if ((v & 1) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_IA64: + if ((v & 0xF) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + } + p->ip = v; + } + else if (propSize != 0) + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; +} + +static void BraState_Init(void *pp) +{ + CBraState *p = ((CBraState *)pp); + p->bufPos = p->bufConv = p->bufTotal = 0; + x86_Convert_Init(p->x86State); + if (p->methodId == XZ_ID_Delta) + Delta_Init(p->deltaState); +} + + +#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: size = isa ## _Convert(data, size, p->ip, p->encodeMode); break; + +static SizeT BraState_Filter(void *pp, Byte *data, SizeT size) +{ + CBraState *p = ((CBraState *)pp); + switch (p->methodId) + { + case XZ_ID_Delta: + if (p->encodeMode) + Delta_Encode(p->deltaState, p->delta, data, size); + else + Delta_Decode(p->deltaState, p->delta, data, size); + break; + case XZ_ID_X86: + size = x86_Convert(data, size, p->ip, &p->x86State, p->encodeMode); + break; + CASE_BRA_CONV(PPC) + CASE_BRA_CONV(IA64) + CASE_BRA_CONV(ARM) + CASE_BRA_CONV(ARMT) + CASE_BRA_CONV(SPARC) + } + p->ip += (UInt32)size; + return size; +} + + +static SRes BraState_Code2(void *pp, + Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CBraState *p = ((CBraState *)pp); + SizeT destRem = *destLen; + SizeT srcRem = *srcLen; + UNUSED_VAR(finishMode); + + *destLen = 0; + *srcLen = 0; + // *wasFinished = False; + *status = CODER_STATUS_NOT_FINISHED; + + while (destRem > 0) + { + if (p->bufPos != p->bufConv) + { + size_t size = p->bufConv - p->bufPos; + if (size > destRem) + size = destRem; + memcpy(dest, p->buf + p->bufPos, size); + p->bufPos += size; + *destLen += size; + dest += size; + destRem -= size; + continue; + } + + p->bufTotal -= p->bufPos; + memmove(p->buf, p->buf + p->bufPos, p->bufTotal); + p->bufPos = 0; + p->bufConv = 0; + { + size_t size = BRA_BUF_SIZE - p->bufTotal; + if (size > srcRem) + size = srcRem; + memcpy(p->buf + p->bufTotal, src, size); + *srcLen += size; + src += size; + srcRem -= size; + p->bufTotal += size; + } + if (p->bufTotal == 0) + break; + + p->bufConv = BraState_Filter(pp, p->buf, p->bufTotal); + + if (p->bufConv == 0) + { + if (!srcWasFinished) + break; + p->bufConv = p->bufTotal; + } + } + + if (p->bufTotal == p->bufPos && srcRem == 0 && srcWasFinished) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + // *wasFinished = 1; + } + + return SZ_OK; +} + + +SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc) +{ + CBraState *decoder; + if (id < XZ_ID_Delta || id > XZ_ID_SPARC) + return SZ_ERROR_UNSUPPORTED; + decoder = (CBraState *)p->p; + if (!decoder) + { + decoder = (CBraState *)ISzAlloc_Alloc(alloc, sizeof(CBraState)); + if (!decoder) + return SZ_ERROR_MEM; + p->p = decoder; + p->Free = BraState_Free; + p->SetProps = BraState_SetProps; + p->Init = BraState_Init; + p->Code2 = BraState_Code2; + p->Filter = BraState_Filter; + } + decoder->methodId = (UInt32)id; + decoder->encodeMode = encodeMode; + return SZ_OK; +} + + + +/* ---------- SbState ---------- */ + +#ifdef USE_SUBBLOCK + +static void SbState_Free(void *pp, ISzAllocPtr alloc) +{ + CSbDec *p = (CSbDec *)pp; + SbDec_Free(p); + ISzAlloc_Free(alloc, pp); +} + +static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + UNUSED_VAR(pp); + UNUSED_VAR(props); + UNUSED_VAR(alloc); + return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static void SbState_Init(void *pp) +{ + SbDec_Init((CSbDec *)pp); +} + +static SRes SbState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CSbDec *p = (CSbDec *)pp; + SRes res; + UNUSED_VAR(srcWasFinished); + p->dest = dest; + p->destLen = *destLen; + p->src = src; + p->srcLen = *srcLen; + p->finish = finishMode; /* change it */ + res = SbDec_Decode((CSbDec *)pp); + *destLen -= p->destLen; + *srcLen -= p->srcLen; + // *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ + *status = (*destLen == 0 && *srcLen == 0) ? + CODER_STATUS_FINISHED_WITH_MARK : + CODER_STATUS_NOT_FINISHED; + return res; +} + +static SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc) +{ + CSbDec *decoder = (CSbDec *)p->p; + if (!decoder) + { + decoder = (CSbDec *)ISzAlloc_Alloc(alloc, sizeof(CSbDec)); + if (!decoder) + return SZ_ERROR_MEM; + p->p = decoder; + p->Free = SbState_Free; + p->SetProps = SbState_SetProps; + p->Init = SbState_Init; + p->Code2 = SbState_Code2; + p->Filter = NULL; + } + SbDec_Construct(decoder); + SbDec_SetAlloc(decoder, alloc); + return SZ_OK; +} + +#endif + + + +/* ---------- Lzma2 ---------- */ + +typedef struct +{ + CLzma2Dec decoder; + BoolInt outBufMode; +} CLzma2Dec_Spec; + + +static void Lzma2State_Free(void *pp, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + Lzma2Dec_FreeProbs(&p->decoder, alloc); + else + Lzma2Dec_Free(&p->decoder, alloc); + ISzAlloc_Free(alloc, pp); +} + +static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + { + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + return Lzma2Dec_AllocateProbs(&p->decoder, props[0], alloc); + else + return Lzma2Dec_Allocate(&p->decoder, props[0], alloc); + } +} + +static void Lzma2State_Init(void *pp) +{ + Lzma2Dec_Init(&((CLzma2Dec_Spec *)pp)->decoder); +} + + +/* + if (outBufMode), then (dest) is not used. Use NULL. + Data is unpacked to (spec->decoder.decoder.dic) output buffer. +*/ + +static SRes Lzma2State_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)pp; + ELzmaStatus status2; + /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ + SRes res; + UNUSED_VAR(srcWasFinished); + if (spec->outBufMode) + { + SizeT dicPos = spec->decoder.decoder.dicPos; + SizeT dicLimit = dicPos + *destLen; + res = Lzma2Dec_DecodeToDic(&spec->decoder, dicLimit, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + *destLen = spec->decoder.decoder.dicPos - dicPos; + } + else + res = Lzma2Dec_DecodeToBuf(&spec->decoder, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + // *wasFinished = (status2 == LZMA_STATUS_FINISHED_WITH_MARK); + // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + *status = (ECoderStatus)status2; + return res; +} + + +static SRes Lzma2State_SetFromMethod(IStateCoder *p, Byte *outBuf, size_t outBufSize, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if (!spec) + { + spec = (CLzma2Dec_Spec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec_Spec)); + if (!spec) + return SZ_ERROR_MEM; + p->p = spec; + p->Free = Lzma2State_Free; + p->SetProps = Lzma2State_SetProps; + p->Init = Lzma2State_Init; + p->Code2 = Lzma2State_Code2; + p->Filter = NULL; + Lzma2Dec_Construct(&spec->decoder); + } + spec->outBufMode = False; + if (outBuf) + { + spec->outBufMode = True; + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + +static SRes Lzma2State_ResetOutBuf(IStateCoder *p, Byte *outBuf, size_t outBufSize) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if ((spec->outBufMode && !outBuf) || (!spec->outBufMode && outBuf)) + return SZ_ERROR_FAIL; + if (outBuf) + { + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + + +static void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc) +{ + unsigned i; + p->alloc = alloc; + p->buf = NULL; + p->numCoders = 0; + + p->outBufSize = 0; + p->outBuf = NULL; + // p->SingleBufMode = False; + + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + p->coders[i].p = NULL; +} + + +static void MixCoder_Free(CMixCoder *p) +{ + unsigned i; + p->numCoders = 0; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + { + IStateCoder *sc = &p->coders[i]; + if (sc->p) + { + sc->Free(sc->p, p->alloc); + sc->p = NULL; + } + } + if (p->buf) + { + ISzAlloc_Free(p->alloc, p->buf); + p->buf = NULL; /* 9.31: the BUG was fixed */ + } +} + +static void MixCoder_Init(CMixCoder *p) +{ + unsigned i; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++) + { + p->size[i] = 0; + p->pos[i] = 0; + p->finished[i] = 0; + } + for (i = 0; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + coder->Init(coder->p); + p->results[i] = SZ_OK; + } + p->outWritten = 0; + p->wasFinished = False; + p->res = SZ_OK; + p->status = CODER_STATUS_NOT_SPECIFIED; +} + + +static SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + p->ids[coderIndex] = methodId; + switch (methodId) + { + case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); + #ifdef USE_SUBBLOCK + case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); + #endif + } + if (coderIndex == 0) + return SZ_ERROR_UNSUPPORTED; + return BraState_SetFromMethod(sc, methodId, 0, p->alloc); +} + + +static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + switch (methodId) + { + case XZ_ID_LZMA2: return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); + } + return SZ_ERROR_UNSUPPORTED; +} + + + +/* + if (destFinish) - then unpack data block is finished at (*destLen) position, + and we can return data that were not processed by filter + +output (status) can be : + CODER_STATUS_NOT_FINISHED + CODER_STATUS_FINISHED_WITH_MARK + CODER_STATUS_NEEDS_MORE_INPUT - not implemented still +*/ + +static SRes MixCoder_Code(CMixCoder *p, + Byte *dest, SizeT *destLen, int destFinish, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + + *destLen = 0; + *srcLen = 0; + + if (p->wasFinished) + return p->res; + + p->status = CODER_STATUS_NOT_FINISHED; + + // if (p->SingleBufMode) + if (p->outBuf) + { + SRes res; + SizeT destLen2, srcLen2; + int wasFinished; + + PRF_STR("------- MixCoder Single ----------"); + + srcLen2 = srcLenOrig; + destLen2 = destLenOrig; + + { + IStateCoder *coder = &p->coders[0]; + res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode, + // &wasFinished, + &p->status); + wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK); + } + + p->res = res; + + /* + if (wasFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + else + { + if (res == SZ_OK) + if (destLen2 != destLenOrig) + p->status = CODER_STATUS_NEEDS_MORE_INPUT; + } + */ + + + *srcLen = srcLen2; + src += srcLen2; + p->outWritten += destLen2; + + if (res != SZ_OK || srcWasFinished || wasFinished) + p->wasFinished = True; + + if (p->numCoders == 1) + *destLen = destLen2; + else if (p->wasFinished) + { + unsigned i; + size_t processed = p->outWritten; + + for (i = 1; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + processed = coder->Filter(coder->p, p->outBuf, processed); + if (wasFinished || (destFinish && p->outWritten == destLenOrig)) + processed = p->outWritten; + PRF_STR_INT("filter", i); + } + *destLen = processed; + } + return res; + } + + PRF_STR("standard mix"); + + if (p->numCoders != 1) + { + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); + if (!p->buf) + return SZ_ERROR_MEM; + } + + finishMode = CODER_FINISH_ANY; + } + + for (;;) + { + BoolInt processed = False; + BoolInt allFinished = True; + SRes resMain = SZ_OK; + unsigned i; + + p->status = CODER_STATUS_NOT_FINISHED; + /* + if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) + break; + */ + + for (i = 0; i < p->numCoders; i++) + { + SRes res; + IStateCoder *coder = &p->coders[i]; + Byte *dest2; + SizeT destLen2, srcLen2; // destLen2_Orig; + const Byte *src2; + int srcFinished2; + int encodingWasFinished; + ECoderStatus status2; + + if (i == 0) + { + src2 = src; + srcLen2 = srcLenOrig - *srcLen; + srcFinished2 = srcWasFinished; + } + else + { + size_t k = i - 1; + src2 = p->buf + (CODER_BUF_SIZE * k) + p->pos[k]; + srcLen2 = p->size[k] - p->pos[k]; + srcFinished2 = p->finished[k]; + } + + if (i == p->numCoders - 1) + { + dest2 = dest; + destLen2 = destLenOrig - *destLen; + } + else + { + if (p->pos[i] != p->size[i]) + continue; + dest2 = p->buf + (CODER_BUF_SIZE * i); + destLen2 = CODER_BUF_SIZE; + } + + // destLen2_Orig = destLen2; + + if (p->results[i] != SZ_OK) + { + if (resMain == SZ_OK) + resMain = p->results[i]; + continue; + } + + res = coder->Code2(coder->p, + dest2, &destLen2, + src2, &srcLen2, srcFinished2, + finishMode, + // &encodingWasFinished, + &status2); + + if (res != SZ_OK) + { + p->results[i] = res; + if (resMain == SZ_OK) + resMain = res; + } + + encodingWasFinished = (status2 == CODER_STATUS_FINISHED_WITH_MARK); + + if (!encodingWasFinished) + { + allFinished = False; + if (p->numCoders == 1 && res == SZ_OK) + p->status = status2; + } + + if (i == 0) + { + *srcLen += srcLen2; + src += srcLen2; + } + else + p->pos[(size_t)i - 1] += srcLen2; + + if (i == p->numCoders - 1) + { + *destLen += destLen2; + dest += destLen2; + } + else + { + p->size[i] = destLen2; + p->pos[i] = 0; + p->finished[i] = encodingWasFinished; + } + + if (destLen2 != 0 || srcLen2 != 0) + processed = True; + } + + if (!processed) + { + if (allFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + return resMain; + } + } +} + + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) +{ + *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); + if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != + GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) + return SZ_ERROR_NO_ARCHIVE; + return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) +{ + return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) + && GetUi32(buf) == CrcCalc(buf + 4, 6) + && flags == GetBe16(buf + 8) + && buf[10] == XZ_FOOTER_SIG_0 + && buf[11] == XZ_FOOTER_SIG_1; +} + +#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ + { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } + + +static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p) +{ + unsigned numFilters = XzBlock_GetNumFilters(p) - 1; + unsigned i; + { + const CXzFilter *f = &p->filters[numFilters]; + if (f->id != XZ_ID_LZMA2 || f->propsSize != 1 || f->props[0] > 40) + return False; + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + if (f->id == XZ_ID_Delta) + { + if (f->propsSize != 1) + return False; + } + else if (f->id < XZ_ID_Delta + || f->id > XZ_ID_SPARC + || (f->propsSize != 0 && f->propsSize != 4)) + return False; + } + return True; +} + + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header) +{ + unsigned pos; + unsigned numFilters, i; + unsigned headerSize = (unsigned)header[0] << 2; + + /* (headerSize != 0) : another code checks */ + + if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) + return SZ_ERROR_ARCHIVE; + + pos = 1; + p->flags = header[pos++]; + + p->packSize = (UInt64)(Int64)-1; + if (XzBlock_HasPackSize(p)) + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize); + if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) + return SZ_ERROR_ARCHIVE; + } + + p->unpackSize = (UInt64)(Int64)-1; + if (XzBlock_HasUnpackSize(p)) + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize); + + numFilters = XzBlock_GetNumFilters(p); + for (i = 0; i < numFilters; i++) + { + CXzFilter *filter = p->filters + i; + UInt64 size; + READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id); + READ_VARINT_AND_CHECK(header, pos, headerSize, &size); + if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) + return SZ_ERROR_ARCHIVE; + filter->propsSize = (UInt32)size; + memcpy(filter->props, header + pos, (size_t)size); + pos += (unsigned)size; + + #ifdef XZ_DUMP + printf("\nf[%u] = %2X: ", i, (unsigned)filter->id); + { + unsigned i; + for (i = 0; i < size; i++) + printf(" %2X", filter->props[i]); + } + #endif + } + + if (XzBlock_HasUnsupportedFlags(p)) + return SZ_ERROR_UNSUPPORTED; + + while (pos < headerSize) + if (header[pos++] != 0) + return SZ_ERROR_ARCHIVE; + return SZ_OK; +} + + + + +static SRes XzDecMix_Init(CMixCoder *p, const CXzBlock *block, Byte *outBuf, size_t outBufSize) +{ + unsigned i; + BoolInt needReInit = True; + unsigned numFilters = XzBlock_GetNumFilters(block); + + if (numFilters == p->numCoders && ((p->outBuf && outBuf) || (!p->outBuf && !outBuf))) + { + needReInit = False; + for (i = 0; i < numFilters; i++) + if (p->ids[i] != block->filters[numFilters - 1 - i].id) + { + needReInit = True; + break; + } + } + + // p->SingleBufMode = (outBuf != NULL); + p->outBuf = outBuf; + p->outBufSize = outBufSize; + + // p->SingleBufMode = False; + // outBuf = NULL; + + if (needReInit) + { + MixCoder_Free(p); + for (i = 0; i < numFilters; i++) + { + RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)); + } + p->numCoders = numFilters; + } + else + { + RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)); + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &block->filters[numFilters - 1 - i]; + IStateCoder *sc = &p->coders[i]; + RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)); + } + + MixCoder_Init(p); + return SZ_OK; +} + + + +void XzUnpacker_Init(CXzUnpacker *p) +{ + p->state = XZ_STATE_STREAM_HEADER; + p->pos = 0; + p->numStartedStreams = 0; + p->numFinishedStreams = 0; + p->numTotalBlocks = 0; + p->padSize = 0; + p->decodeOnlyOneBlock = 0; + + p->parseMode = False; + p->decodeToStreamSignature = False; + + // p->outBuf = NULL; + // p->outBufSize = 0; + p->outDataWritten = 0; +} + + +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize) +{ + p->outBuf = outBuf; + p->outBufSize = outBufSize; +} + + +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc) +{ + MixCoder_Construct(&p->decoder, alloc); + p->outBuf = NULL; + p->outBufSize = 0; + XzUnpacker_Init(p); +} + + +void XzUnpacker_Free(CXzUnpacker *p) +{ + MixCoder_Free(&p->decoder); +} + + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p) +{ + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + p->decodeOnlyOneBlock = 1; +} + + +static void XzUnpacker_UpdateIndex(CXzUnpacker *p, UInt64 packSize, UInt64 unpackSize) +{ + Byte temp[32]; + unsigned num = Xz_WriteVarInt(temp, packSize); + num += Xz_WriteVarInt(temp + num, unpackSize); + Sha256_Update(&p->sha, temp, num); + p->indexSize += num; + p->numBlocks++; +} + + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + *destLen = 0; + *srcLen = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + for (;;) + { + SizeT srcRem; + + if (p->state == XZ_STATE_BLOCK) + { + SizeT destLen2 = destLenOrig - *destLen; + SizeT srcLen2 = srcLenOrig - *srcLen; + SRes res; + + ECoderFinishMode finishMode2 = finishMode; + BoolInt srcFinished2 = srcFinished; + BoolInt destFinish = False; + + if (p->block.packSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.packSize - p->packSize; + if (srcLen2 >= rem) + { + srcFinished2 = True; + srcLen2 = (SizeT)rem; + } + if (rem == 0 && p->block.unpackSize == p->unpackSize) + return SZ_ERROR_DATA; + } + + if (p->block.unpackSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.unpackSize - p->unpackSize; + if (destLen2 >= rem) + { + destFinish = True; + finishMode2 = CODER_FINISH_END; + destLen2 = (SizeT)rem; + } + } + + /* + if (srcLen2 == 0 && destLen2 == 0) + { + *status = CODER_STATUS_NOT_FINISHED; + return SZ_OK; + } + */ + + { + res = MixCoder_Code(&p->decoder, + (p->outBuf ? NULL : dest), &destLen2, destFinish, + src, &srcLen2, srcFinished2, + finishMode2); + + *status = p->decoder.status; + XzCheck_Update(&p->check, (p->outBuf ? p->outBuf + p->outDataWritten : dest), destLen2); + if (!p->outBuf) + dest += destLen2; + p->outDataWritten += destLen2; + } + + (*srcLen) += srcLen2; + src += srcLen2; + p->packSize += srcLen2; + (*destLen) += destLen2; + p->unpackSize += destLen2; + + RINOK(res); + + if (*status != CODER_STATUS_FINISHED_WITH_MARK) + { + if (p->block.packSize == p->packSize + && *status == CODER_STATUS_NEEDS_MORE_INPUT) + { + PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT"); + *status = CODER_STATUS_NOT_SPECIFIED; + return SZ_ERROR_DATA; + } + + return SZ_OK; + } + { + XzUnpacker_UpdateIndex(p, XzUnpacker_GetPackSizeForIndex(p), p->unpackSize); + p->state = XZ_STATE_BLOCK_FOOTER; + p->pos = 0; + p->alignPos = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize) + || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize)) + { + PRF_STR("ERROR: block.size mismatch"); + return SZ_ERROR_DATA; + } + } + // continue; + } + + srcRem = srcLenOrig - *srcLen; + + // XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes + if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + switch (p->state) + { + case XZ_STATE_STREAM_HEADER: + { + if (p->pos < XZ_STREAM_HEADER_SIZE) + { + if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) + return SZ_ERROR_NO_ARCHIVE; + if (p->decodeToStreamSignature) + return SZ_OK; + p->buf[p->pos++] = *src++; + (*srcLen)++; + } + else + { + RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); + p->numStartedStreams++; + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + } + break; + } + + case XZ_STATE_BLOCK_HEADER: + { + if (p->pos == 0) + { + p->buf[p->pos++] = *src++; + (*srcLen)++; + if (p->buf[0] == 0) + { + if (p->decodeOnlyOneBlock) + return SZ_ERROR_DATA; + p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); + p->indexPos = p->indexPreSize; + p->indexSize += p->indexPreSize; + Sha256_Final(&p->sha, p->shaDigest); + Sha256_Init(&p->sha); + p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); + p->state = XZ_STATE_STREAM_INDEX; + break; + } + p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; + break; + } + + if (p->pos != p->blockHeaderSize) + { + UInt32 cur = p->blockHeaderSize - p->pos; + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + } + else + { + RINOK(XzBlock_Parse(&p->block, p->buf)); + if (!XzBlock_AreSupportedFilters(&p->block)) + return SZ_ERROR_UNSUPPORTED; + p->numTotalBlocks++; + p->state = XZ_STATE_BLOCK; + p->packSize = 0; + p->unpackSize = 0; + XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); + if (p->parseMode) + { + p->headerParsedOk = True; + return SZ_OK; + } + RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)); + } + break; + } + + case XZ_STATE_BLOCK_FOOTER: + { + if ((((unsigned)p->packSize + p->alignPos) & 3) != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->alignPos++; + if (*src++ != 0) + return SZ_ERROR_CRC; + } + else + { + UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); + UInt32 cur = checkSize - p->pos; + if (cur != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (checkSize != p->pos) + break; + } + { + Byte digest[XZ_CHECK_SIZE_MAX]; + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) + return SZ_ERROR_CRC; + if (p->decodeOnlyOneBlock) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + } + } + break; + } + + case XZ_STATE_STREAM_INDEX: + { + if (p->pos < p->indexPreSize) + { + (*srcLen)++; + if (*src++ != p->buf[p->pos++]) + return SZ_ERROR_CRC; + } + else + { + if (p->indexPos < p->indexSize) + { + UInt64 cur = p->indexSize - p->indexPos; + if (srcRem > cur) + srcRem = (SizeT)cur; + p->crc = CrcUpdate(p->crc, src, srcRem); + Sha256_Update(&p->sha, src, srcRem); + (*srcLen) += srcRem; + src += srcRem; + p->indexPos += srcRem; + } + else if ((p->indexPos & 3) != 0) + { + Byte b = *src++; + p->crc = CRC_UPDATE_BYTE(p->crc, b); + (*srcLen)++; + p->indexPos++; + p->indexSize++; + if (b != 0) + return SZ_ERROR_CRC; + } + else + { + Byte digest[SHA256_DIGEST_SIZE]; + p->state = XZ_STATE_STREAM_INDEX_CRC; + p->indexSize += 4; + p->pos = 0; + Sha256_Final(&p->sha, digest); + if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) + return SZ_ERROR_CRC; + } + } + break; + } + + case XZ_STATE_STREAM_INDEX_CRC: + { + if (p->pos < 4) + { + (*srcLen)++; + p->buf[p->pos++] = *src++; + } + else + { + p->state = XZ_STATE_STREAM_FOOTER; + p->pos = 0; + if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_FOOTER: + { + UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (p->pos == XZ_STREAM_FOOTER_SIZE) + { + p->state = XZ_STATE_STREAM_PADDING; + p->numFinishedStreams++; + p->padSize = 0; + if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_PADDING: + { + if (*src != 0) + { + if (((UInt32)p->padSize & 3) != 0) + return SZ_ERROR_NO_ARCHIVE; + p->pos = 0; + p->state = XZ_STATE_STREAM_HEADER; + } + else + { + (*srcLen)++; + src++; + p->padSize++; + } + break; + } + + case XZ_STATE_BLOCK: break; /* to disable GCC warning */ + } + } + /* + if (p->state == XZ_STATE_FINISHED) + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + */ +} + + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + XzUnpacker_Init(p); + XzUnpacker_SetOutBuf(p, dest, *destLen); + + return XzUnpacker_Code(p, + NULL, destLen, + src, srcLen, True, + finishMode, status); +} + + +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0); +} + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); +} + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p) +{ + UInt64 num = 0; + if (p->state == XZ_STATE_STREAM_PADDING) + num = p->padSize; + else if (p->state == XZ_STATE_STREAM_HEADER) + num = p->padSize + p->pos; + return num; +} + + + + + + + + + + + + + + + + + + + + + +#ifndef _7ZIP_ST +#include "MtDec.h" +#endif + + +void XzDecMtProps_Init(CXzDecMtProps *p) +{ + p->inBufSize_ST = 1 << 18; + p->outStep_ST = 1 << 20; + p->ignoreErrors = False; + + #ifndef _7ZIP_ST + p->numThreads = 1; + p->inBufSize_MT = 1 << 18; + p->memUseMax = sizeof(size_t) << 28; + #endif +} + + + +#ifndef _7ZIP_ST + +/* ---------- CXzDecMtThread ---------- */ + +typedef struct +{ + Byte *outBuf; + size_t outBufSize; + size_t outPreSize; + size_t inPreSize; + size_t inPreHeaderSize; + size_t blockPackSize_for_Index; // including block header and checksum. + size_t blockPackTotal; // including stream header, block header and checksum. + size_t inCodeSize; + size_t outCodeSize; + ECoderStatus status; + SRes codeRes; + BoolInt skipMode; + // BoolInt finishedWithMark; + EMtDecParseState parseState; + BoolInt parsing_Truncated; + BoolInt atBlockHeader; + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + BoolInt dec_created; + CXzUnpacker dec; + + Byte mtPad[1 << 7]; +} CXzDecMtThread; + +#endif + + +/* ---------- CXzDecMt ---------- */ + +typedef struct +{ + CAlignOffsetAlloc alignOffsetAlloc; + ISzAllocPtr allocMid; + + CXzDecMtProps props; + size_t unpackBlockMaxSize; + + ISeqInStream *inStream; + ISeqOutStream *outStream; + ICompressProgress *progress; + // CXzStatInfo *stat; + + BoolInt finishMode; + BoolInt outSize_Defined; + UInt64 outSize; + + UInt64 outProcessed; + UInt64 inProcessed; + UInt64 readProcessed; + BoolInt readWasFinished; + SRes readRes; + SRes writeRes; + + Byte *outBuf; + size_t outBufSize; + Byte *inBuf; + size_t inBufSize; + + CXzUnpacker dec; + + ECoderStatus status; + SRes codeRes; + + #ifndef _7ZIP_ST + BoolInt mainDecoderWasCalled; + // int statErrorDefined; + int finishedDecoderIndex; + + // global values that are used in Parse stage + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + // UInt64 numBadBlocks; + SRes mainErrorCode; + + BoolInt isBlockHeaderState_Parse; + BoolInt isBlockHeaderState_Write; + UInt64 outProcessed_Parse; + BoolInt parsing_Truncated; + + BoolInt mtc_WasConstructed; + CMtDec mtc; + CXzDecMtThread coders[MTDEC__THREADS_MAX]; + #endif + +} CXzDecMt; + + + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) +{ + CXzDecMt *p = (CXzDecMt *)ISzAlloc_Alloc(alloc, sizeof(CXzDecMt)); + if (!p) + return NULL; + + AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); + p->alignOffsetAlloc.baseAlloc = alloc; + p->alignOffsetAlloc.numAlignBits = 7; + p->alignOffsetAlloc.offset = 0; + + p->allocMid = allocMid; + + p->outBuf = NULL; + p->outBufSize = 0; + p->inBuf = NULL; + p->inBufSize = 0; + + XzUnpacker_Construct(&p->dec, &p->alignOffsetAlloc.vt); + + p->unpackBlockMaxSize = 0; + + XzDecMtProps_Init(&p->props); + + #ifndef _7ZIP_ST + p->mtc_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTDEC__THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + coder->dec_created = False; + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + #endif + + return p; +} + + +#ifndef _7ZIP_ST + +static void XzDecMt_FreeOutBufs(CXzDecMt *p) +{ + unsigned i; + for (i = 0; i < MTDEC__THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + if (coder->outBuf) + { + ISzAlloc_Free(p->allocMid, coder->outBuf); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + p->unpackBlockMaxSize = 0; +} + +#endif + + + +static void XzDecMt_FreeSt(CXzDecMt *p) +{ + XzUnpacker_Free(&p->dec); + + if (p->outBuf) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBuf = NULL; + } + p->outBufSize = 0; + + if (p->inBuf) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBuf = NULL; + } + p->inBufSize = 0; +} + + +void XzDecMt_Destroy(CXzDecMtHandle pp) +{ + CXzDecMt *p = (CXzDecMt *)pp; + + XzDecMt_FreeSt(p); + + #ifndef _7ZIP_ST + + if (p->mtc_WasConstructed) + { + MtDec_Destruct(&p->mtc); + p->mtc_WasConstructed = False; + } + { + unsigned i; + for (i = 0; i < MTDEC__THREADS_MAX; i++) + { + CXzDecMtThread *t = &p->coders[i]; + if (t->dec_created) + { + // we don't need to free dict here + XzUnpacker_Free(&t->dec); + t->dec_created = False; + } + } + } + XzDecMt_FreeOutBufs(p); + + #endif + + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, pp); +} + + + +#ifndef _7ZIP_ST + +static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) +{ + CXzDecMt *me = (CXzDecMt *)obj; + CXzDecMtThread *coder = &me->coders[coderIndex]; + size_t srcSize = cc->srcSize; + + cc->srcSize = 0; + cc->outPos = 0; + cc->state = MTDEC_PARSE_CONTINUE; + + cc->canCreateNewThread = True; + + if (cc->startCall) + { + coder->outPreSize = 0; + coder->inPreSize = 0; + coder->inPreHeaderSize = 0; + coder->parseState = MTDEC_PARSE_CONTINUE; + coder->parsing_Truncated = False; + coder->skipMode = False; + coder->codeRes = SZ_OK; + coder->status = CODER_STATUS_NOT_SPECIFIED; + coder->inCodeSize = 0; + coder->outCodeSize = 0; + + coder->numStreams = me->numStreams; + coder->numTotalBlocks = me->numTotalBlocks; + coder->numBlocks = me->numBlocks; + + if (!coder->dec_created) + { + XzUnpacker_Construct(&coder->dec, &me->alignOffsetAlloc.vt); + coder->dec_created = True; + } + + XzUnpacker_Init(&coder->dec); + + if (me->isBlockHeaderState_Parse) + { + coder->dec.streamFlags = me->streamFlags; + coder->atBlockHeader = True; + XzUnpacker_PrepareToRandomBlockDecoding(&coder->dec); + } + else + { + coder->atBlockHeader = False; + me->isBlockHeaderState_Parse = True; + } + + coder->dec.numStartedStreams = me->numStreams; + coder->dec.numTotalBlocks = me->numTotalBlocks; + coder->dec.numBlocks = me->numBlocks; + } + + while (!coder->skipMode) + { + ECoderStatus status; + SRes res; + size_t srcSize2 = srcSize; + size_t destSize = (size_t)0 - 1; + + coder->dec.parseMode = True; + coder->dec.headerParsedOk = False; + + PRF_STR_INT("Parse", srcSize2); + + res = XzUnpacker_Code(&coder->dec, + NULL, &destSize, + cc->src, &srcSize2, cc->srcFinished, + CODER_FINISH_END, &status); + + // PRF(printf(" res = %d, srcSize2 = %d", res, (unsigned)srcSize2)); + + coder->codeRes = res; + coder->status = status; + cc->srcSize += srcSize2; + srcSize -= srcSize2; + coder->inPreHeaderSize += srcSize2; + coder->inPreSize = coder->inPreHeaderSize; + + if (res != SZ_OK) + { + cc->state = + coder->parseState = MTDEC_PARSE_END; + /* + if (res == SZ_ERROR_MEM) + return res; + return SZ_OK; + */ + return; // res; + } + + if (coder->dec.headerParsedOk) + { + const CXzBlock *block = &coder->dec.block; + if (XzBlock_HasUnpackSize(block) + // && block->unpackSize <= me->props.outBlockMax + && XzBlock_HasPackSize(block)) + { + { + if (block->unpackSize * 2 * me->mtc.numStartedThreads > me->props.memUseMax) + { + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + } + { + UInt64 packSize = block->packSize; + UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + UInt32 checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); + UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; + // if (blockPackSum <= me->props.inBlockMax) + // unpackBlockMaxSize + { + coder->blockPackSize_for_Index = (size_t)(coder->dec.blockHeaderSize + packSize + checkSize); + coder->blockPackTotal = (size_t)blockPackSum; + coder->outPreSize = (size_t)block->unpackSize; + coder->streamFlags = coder->dec.streamFlags; + me->streamFlags = coder->dec.streamFlags; + coder->skipMode = True; + break; + } + } + } + } + else + // if (coder->inPreSize <= me->props.inBlockMax) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = + coder->parseState = MTDEC_PARSE_END; + return; // SZ_OK; + } + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + + // ---------- skipMode ---------- + { + UInt64 rem = coder->blockPackTotal - coder->inPreSize; + size_t cur = srcSize; + if (cur > rem) + cur = (size_t)rem; + cc->srcSize += cur; + coder->inPreSize += cur; + srcSize -= cur; + + if (coder->inPreSize == coder->blockPackTotal) + { + if (srcSize == 0) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = MTDEC_PARSE_END; + } + else if ((cc->src)[cc->srcSize] == 0) // we check control byte of next block + cc->state = MTDEC_PARSE_END; + else + { + cc->state = MTDEC_PARSE_NEW; + + { + size_t blockMax = me->unpackBlockMaxSize; + if (blockMax < coder->outPreSize) + blockMax = coder->outPreSize; + { + UInt64 required = (UInt64)blockMax * (me->mtc.numStartedThreads + 1) * 2; + if (me->props.memUseMax < required) + cc->canCreateNewThread = False; + } + } + + if (me->outSize_Defined) + { + // next block can be zero size + const UInt64 rem2 = me->outSize - me->outProcessed_Parse; + if (rem2 < coder->outPreSize) + { + coder->parsing_Truncated = True; + cc->state = MTDEC_PARSE_END; + } + me->outProcessed_Parse += coder->outPreSize; + } + } + } + else if (cc->srcFinished) + cc->state = MTDEC_PARSE_END; + else + return; // SZ_OK; + + coder->parseState = cc->state; + cc->outPos = coder->outPreSize; + + me->numStreams = coder->dec.numStartedStreams; + me->numTotalBlocks = coder->dec.numTotalBlocks; + me->numBlocks = coder->dec.numBlocks + 1; + return; // SZ_OK; + } +} + + +static SRes XzDecMt_Callback_PreCode(void *pp, unsigned coderIndex) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + Byte *dest; + + if (!coder->dec.headerParsedOk) + return SZ_OK; + + dest = coder->outBuf; + + if (!dest || coder->outBufSize < coder->outPreSize) + { + if (dest) + { + ISzAlloc_Free(me->allocMid, dest); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + { + size_t outPreSize = coder->outPreSize; + if (outPreSize == 0) + outPreSize = 1; + dest = (Byte *)ISzAlloc_Alloc(me->allocMid, outPreSize); + } + if (!dest) + return SZ_ERROR_MEM; + coder->outBuf = dest; + coder->outBufSize = coder->outPreSize; + + if (coder->outBufSize > me->unpackBlockMaxSize) + me->unpackBlockMaxSize = coder->outBufSize; + } + + // return SZ_ERROR_MEM; + + XzUnpacker_SetOutBuf(&coder->dec, coder->outBuf, coder->outBufSize); + + { + SRes res = XzDecMix_Init(&coder->dec.decoder, &coder->dec.block, coder->outBuf, coder->outBufSize); + // res = SZ_ERROR_UNSUPPORTED; // to test + coder->codeRes = res; + if (res != SZ_OK) + { + // if (res == SZ_ERROR_MEM) return res; + if (me->props.ignoreErrors && res != SZ_ERROR_MEM) + return S_OK; + return res; + } + } + + return SZ_OK; +} + + +static SRes XzDecMt_Callback_Code(void *pp, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + // int finished, int blockFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + *stop = True; + + if (coder->inCodeSize < coder->inPreHeaderSize) + { + UInt64 rem = coder->inPreHeaderSize - coder->inCodeSize; + size_t step = srcSize; + if (step > rem) + step = (size_t)rem; + src += step; + srcSize -= step; + coder->inCodeSize += step; + if (coder->inCodeSize < coder->inPreHeaderSize) + { + *stop = False; + return SZ_OK; + } + } + + if (!coder->dec.headerParsedOk) + return SZ_OK; + if (!coder->outBuf) + return SZ_OK; + + if (coder->codeRes == SZ_OK) + { + ECoderStatus status; + SRes res; + size_t srcProcessed = srcSize; + size_t outSizeCur = coder->outPreSize - coder->dec.outDataWritten; + + // PRF(printf("\nCallback_Code: Code %d %d\n", (unsigned)srcSize, (unsigned)outSizeCur)); + + res = XzUnpacker_Code(&coder->dec, + NULL, &outSizeCur, + src, &srcProcessed, srcFinished, + // coder->finishedWithMark ? CODER_FINISH_END : CODER_FINISH_ANY, + CODER_FINISH_END, + &status); + + // PRF(printf(" res = %d, srcSize2 = %d, outSizeCur = %d", res, (unsigned)srcProcessed, (unsigned)outSizeCur)); + + coder->codeRes = res; + coder->status = status; + coder->inCodeSize += srcProcessed; + coder->outCodeSize = coder->dec.outDataWritten; + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + + if (res == SZ_OK) + { + if (srcProcessed == srcSize) + *stop = False; + return SZ_OK; + } + } + + if (me->props.ignoreErrors && coder->codeRes != SZ_ERROR_MEM) + { + *inCodePos = coder->inPreSize; + *outCodePos = coder->outPreSize; + return S_OK; + } + return coder->codeRes; +} + + +#define XZDECMT_STREAM_WRITE_STEP (1 << 24) + +static SRes XzDecMt_Callback_Write(void *pp, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, + // int srcFinished, + BoolInt *needContinue, + BoolInt *canRecode) +{ + CXzDecMt *me = (CXzDecMt *)pp; + const CXzDecMtThread *coder = &me->coders[coderIndex]; + + // PRF(printf("\nWrite processed = %d srcSize = %d\n", (unsigned)me->mtc.inProcessed, (unsigned)srcSize)); + + *needContinue = False; + *canRecode = True; + + if (!needWriteToStream) + return SZ_OK; + + if (!coder->dec.headerParsedOk || !coder->outBuf) + { + if (me->finishedDecoderIndex < 0) + me->finishedDecoderIndex = coderIndex; + return SZ_OK; + } + + if (me->finishedDecoderIndex >= 0) + return SZ_OK; + + me->mtc.inProcessed += coder->inCodeSize; + + *canRecode = False; + + { + SRes res; + size_t size = coder->outCodeSize; + Byte *data = coder->outBuf; + + // we use in me->dec: sha, numBlocks, indexSize + + if (!me->isBlockHeaderState_Write) + { + XzUnpacker_PrepareToRandomBlockDecoding(&me->dec); + me->dec.decodeOnlyOneBlock = False; + me->dec.numStartedStreams = coder->dec.numStartedStreams; + me->dec.streamFlags = coder->streamFlags; + + me->isBlockHeaderState_Write = True; + } + + me->dec.numTotalBlocks = coder->dec.numTotalBlocks; + XzUnpacker_UpdateIndex(&me->dec, coder->blockPackSize_for_Index, coder->outPreSize); + + if (coder->outPreSize != size) + { + if (me->props.ignoreErrors) + { + memset(data + size, 0, coder->outPreSize - size); + size = coder->outPreSize; + } + // me->numBadBlocks++; + if (me->mainErrorCode == SZ_OK) + { + if ((int)coder->status == LZMA_STATUS_NEEDS_MORE_INPUT) + me->mainErrorCode = SZ_ERROR_INPUT_EOF; + else + me->mainErrorCode = SZ_ERROR_DATA; + } + } + + if (me->writeRes != SZ_OK) + return me->writeRes; + + res = SZ_OK; + { + if (me->outSize_Defined) + { + const UInt64 rem = me->outSize - me->outProcessed; + if (size > rem) + size = (SizeT)rem; + } + + for (;;) + { + size_t cur = size; + size_t written; + if (cur > XZDECMT_STREAM_WRITE_STEP) + cur = XZDECMT_STREAM_WRITE_STEP; + + written = ISeqOutStream_Write(me->outStream, data, cur); + + // PRF(printf("\nWritten ask = %d written = %d\n", (unsigned)cur, (unsigned)written)); + + me->outProcessed += written; + if (written != cur) + { + me->writeRes = SZ_ERROR_WRITE; + res = me->writeRes; + break; + } + data += cur; + size -= cur; + // PRF_STR_INT("Written size =", size); + if (size == 0) + break; + res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0); + if (res != SZ_OK) + break; + } + } + + if (coder->codeRes != SZ_OK) + if (!me->props.ignoreErrors) + { + me->finishedDecoderIndex = coderIndex; + return res; + } + + RINOK(res); + + if (coder->inPreSize != coder->inCodeSize + || coder->blockPackTotal != coder->inCodeSize) + { + me->finishedDecoderIndex = coderIndex; + return SZ_OK; + } + + if (coder->parseState != MTDEC_PARSE_END) + { + *needContinue = True; + return SZ_OK; + } + } + + // (coder->state == MTDEC_PARSE_END) means that there are no other working threads + // so we can use mtc variables without lock + + PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed); + + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + { + CXzUnpacker *dec = &me->dec; + + PRF_STR_INT("PostSingle", srcSize); + + { + size_t srcProcessed = srcSize; + ECoderStatus status; + size_t outSizeCur = 0; + SRes res; + + // dec->decodeOnlyOneBlock = False; + dec->decodeToStreamSignature = True; + + me->mainDecoderWasCalled = True; + + if (coder->parsing_Truncated) + { + me->parsing_Truncated = True; + return SZ_OK; + } + + res = XzUnpacker_Code(dec, + NULL, &outSizeCur, + src, &srcProcessed, + me->mtc.readWasFinished, // srcFinished + CODER_FINISH_END, // CODER_FINISH_ANY, + &status); + + me->status = status; + me->codeRes = res; + + me->mtc.inProcessed += srcProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + if (res != SZ_OK) + { + return S_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + { + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + memcpy(crossBuf, src + srcProcessed, srcSize - srcProcessed); + } + me->mtc.crossStart = 0; + me->mtc.crossEnd = srcSize - srcProcessed; + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT) + { + return E_FAIL; + } + + if (me->mtc.readWasFinished) + { + return SZ_OK; + } + } + + { + size_t inPos; + size_t inLim; + const Byte *inData; + UInt64 inProgressPrev = me->mtc.inProcessed; + + // XzDecMt_Prepare_InBuf_ST(p); + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + + inPos = 0; + inLim = 0; + // outProcessed = 0; + + inData = crossBuf; + + for (;;) + { + SizeT inProcessed; + SizeT outProcessed; + ECoderStatus status; + SRes res; + + if (inPos == inLim) + { + if (!me->mtc.readWasFinished) + { + inPos = 0; + inLim = me->mtc.inBufSize; + me->mtc.readRes = ISeqInStream_Read(me->inStream, (void *)inData, &inLim); + me->mtc.readProcessed += inLim; + if (inLim == 0 || me->mtc.readRes != SZ_OK) + me->mtc.readWasFinished = True; + } + } + + inProcessed = inLim - inPos; + outProcessed = 0; + + res = XzUnpacker_Code(dec, + NULL, &outProcessed, + inData + inPos, &inProcessed, + (inProcessed == 0), // srcFinished + CODER_FINISH_END, &status); + + me->codeRes = res; + me->status = status; + inPos += inProcessed; + me->mtc.inProcessed += inProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + if (res != SZ_OK) + { + return S_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->mtc.crossStart = inPos; + me->mtc.crossEnd = inLim; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT) + return E_FAIL; + + if (me->mtc.progress) + { + UInt64 inDelta = me->mtc.inProcessed - inProgressPrev; + if (inDelta >= (1 << 22)) + { + RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)); + inProgressPrev = me->mtc.inProcessed; + } + } + if (me->mtc.readWasFinished) + return SZ_OK; + } + } + } +} + + +#endif + + + +void XzStatInfo_Clear(CXzStatInfo *p) +{ + p->InSize = 0; + p->OutSize = 0; + + p->NumStreams = 0; + p->NumBlocks = 0; + + p->UnpackSize_Defined = False; + + p->NumStreams_Defined = False; + p->NumBlocks_Defined = False; + + // p->IsArc = False; + // p->UnexpectedEnd = False; + // p->Unsupported = False; + // p->HeadersError = False; + // p->DataError = False; + // p->CrcError = False; + + p->DataAfterEnd = False; + p->DecodingTruncated = False; + + p->DecodeRes = SZ_OK; + p->ReadRes = SZ_OK; + p->ProgressRes = SZ_OK; + + p->CombinedRes = SZ_OK; + p->CombinedRes_Type = SZ_OK; +} + + + + +static SRes XzDecMt_Decode_ST(CXzDecMt *p + #ifndef _7ZIP_ST + , BoolInt tMode + #endif + , CXzStatInfo *stat) +{ + size_t outPos; + size_t inPos, inLim; + const Byte *inData; + UInt64 inPrev, outPrev; + + CXzUnpacker *dec; + + #ifndef _7ZIP_ST + if (tMode) + { + XzDecMt_FreeOutBufs(p); + tMode = MtDec_PrepareRead(&p->mtc); + } + #endif + + if (!p->outBuf || p->outBufSize != p->props.outStep_ST) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBufSize = 0; + p->outBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.outStep_ST); + if (!p->outBuf) + return SZ_ERROR_MEM; + p->outBufSize = p->props.outStep_ST; + } + + if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBufSize = 0; + p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); + if (!p->inBuf) + return SZ_ERROR_MEM; + p->inBufSize = p->props.inBufSize_ST; + } + + dec = &p->dec; + dec->decodeToStreamSignature = False; + // dec->decodeOnlyOneBlock = False; + + XzUnpacker_SetOutBuf(dec, NULL, 0); + + inPrev = p->inProcessed; + outPrev = p->outProcessed; + + inPos = 0; + inLim = 0; + inData = NULL; + outPos = 0; + + for (;;) + { + SizeT outSize; + BoolInt finished; + ECoderFinishMode finishMode; + SizeT inProcessed; + ECoderStatus status; + SRes res; + + SizeT outProcessed; + + + + if (inPos == inLim) + { + #ifndef _7ZIP_ST + if (tMode) + { + inData = MtDec_Read(&p->mtc, &inLim); + inPos = 0; + if (inData) + continue; + tMode = False; + inLim = 0; + } + #endif + + if (!p->readWasFinished) + { + inPos = 0; + inLim = p->inBufSize; + inData = p->inBuf; + p->readRes = ISeqInStream_Read(p->inStream, (void *)inData, &inLim); + p->readProcessed += inLim; + if (inLim == 0 || p->readRes != SZ_OK) + p->readWasFinished = True; + } + } + + outSize = p->props.outStep_ST - outPos; + + finishMode = CODER_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (outSize >= rem) + { + outSize = (SizeT)rem; + if (p->finishMode) + finishMode = CODER_FINISH_END; + } + } + + inProcessed = inLim - inPos; + outProcessed = outSize; + + res = XzUnpacker_Code(dec, p->outBuf + outPos, &outProcessed, + inData + inPos, &inProcessed, + (inPos == inLim), // srcFinished + finishMode, &status); + + p->codeRes = res; + p->status = status; + + inPos += inProcessed; + outPos += outProcessed; + p->inProcessed += inProcessed; + p->outProcessed += outProcessed; + + finished = ((inProcessed == 0 && outProcessed == 0) || res != SZ_OK); + + if (finished || outProcessed >= outSize) + if (outPos != 0) + { + size_t written = ISeqOutStream_Write(p->outStream, p->outBuf, outPos); + p->outProcessed += written; + if (written != outPos) + { + stat->CombinedRes_Type = SZ_ERROR_WRITE; + return SZ_ERROR_WRITE; + } + outPos = 0; + } + + if (p->progress && res == SZ_OK) + { + UInt64 inDelta = p->inProcessed - inPrev; + UInt64 outDelta = p->outProcessed - outPrev; + if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) + { + res = ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed); + if (res != SZ_OK) + { + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + stat->ProgressRes = res; + return res; + } + inPrev = p->inProcessed; + outPrev = p->outProcessed; + } + } + + if (finished) + return res; + } +} + +static SRes XzStatInfo_SetStat(const CXzUnpacker *dec, + int finishMode, + UInt64 readProcessed, UInt64 inProcessed, + SRes res, ECoderStatus status, + BoolInt decodingTruncated, + CXzStatInfo *stat) +{ + UInt64 extraSize; + + stat->DecodingTruncated = (Byte)(decodingTruncated ? 1 : 0); + stat->InSize = inProcessed; + stat->NumStreams = dec->numStartedStreams; + stat->NumBlocks = dec->numTotalBlocks; + + stat->UnpackSize_Defined = True; + stat->NumStreams_Defined = True; + stat->NumBlocks_Defined = True; + + extraSize = XzUnpacker_GetExtraSize(dec); + + if (res == SZ_OK) + { + if (status == CODER_STATUS_NEEDS_MORE_INPUT) + { + // CODER_STATUS_NEEDS_MORE_INPUT is expected status for correct xz streams + extraSize = 0; + if (!XzUnpacker_IsStreamWasFinished(dec)) + res = SZ_ERROR_INPUT_EOF; + } + else if (!decodingTruncated || finishMode) // (status == CODER_STATUS_NOT_FINISHED) + res = SZ_ERROR_DATA; + } + else if (res == SZ_ERROR_NO_ARCHIVE) + { + /* + SZ_ERROR_NO_ARCHIVE is possible for 2 states: + XZ_STATE_STREAM_HEADER - if bad signature or bad CRC + XZ_STATE_STREAM_PADDING - if non-zero padding data + extraSize / inProcessed don't include "bad" byte + */ + if (inProcessed != extraSize) // if good streams before error + if (extraSize != 0 || readProcessed != inProcessed) + { + stat->DataAfterEnd = True; + // there is some good xz stream before. So we set SZ_OK + res = SZ_OK; + } + } + + stat->DecodeRes = res; + + stat->InSize -= extraSize; + return res; +} + + +SRes XzDecMt_Decode(CXzDecMtHandle pp, + const CXzDecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqOutStream *outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStream *inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, + int *isMT, + ICompressProgress *progress) +{ + CXzDecMt *p = (CXzDecMt *)pp; + #ifndef _7ZIP_ST + BoolInt tMode; + #endif + + XzStatInfo_Clear(stat); + + p->props = *props; + + p->inStream = inStream; + p->outStream = outStream; + p->progress = progress; + // p->stat = stat; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + + p->finishMode = finishMode; + + // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test + + p->writeRes = SZ_OK; + p->outProcessed = 0; + p->inProcessed = 0; + p->readProcessed = 0; + p->readWasFinished = False; + + p->codeRes = 0; + p->status = CODER_STATUS_NOT_SPECIFIED; + + XzUnpacker_Init(&p->dec); + + *isMT = False; + + /* + p->outBuf = NULL; + p->outBufSize = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBufSize = *outBufSize; + *outBufSize = 0; + } + */ + + + #ifndef _7ZIP_ST + + p->isBlockHeaderState_Parse = False; + p->isBlockHeaderState_Write = False; + // p->numBadBlocks = 0; + p->mainErrorCode = SZ_OK; + p->mainDecoderWasCalled = False; + + tMode = False; + + if (p->props.numThreads > 1) + { + IMtDecCallback vt; + + // we just free ST buffers here + // but we still keep state variables, that was set in XzUnpacker_Init() + XzDecMt_FreeSt(p); + + p->outProcessed_Parse = 0; + p->parsing_Truncated = False; + + p->numStreams = 0; + p->numTotalBlocks = 0; + p->numBlocks = 0; + p->finishedDecoderIndex = -1; + + if (!p->mtc_WasConstructed) + { + p->mtc_WasConstructed = True; + MtDec_Construct(&p->mtc); + } + + p->mtc.mtCallback = &vt; + p->mtc.mtCallbackObject = p; + + p->mtc.progress = progress; + p->mtc.inStream = inStream; + p->mtc.alloc = &p->alignOffsetAlloc.vt; + // p->mtc.inData = inData; + // p->mtc.inDataSize = inDataSize; + p->mtc.inBufSize = p->props.inBufSize_MT; + // p->mtc.inBlockMax = p->props.inBlockMax; + p->mtc.numThreadsMax = p->props.numThreads; + + *isMT = True; + + vt.Parse = XzDecMt_Callback_Parse; + vt.PreCode = XzDecMt_Callback_PreCode; + vt.Code = XzDecMt_Callback_Code; + vt.Write = XzDecMt_Callback_Write; + + { + BoolInt needContinue; + + SRes res = MtDec_Code(&p->mtc); + + stat->InSize = p->mtc.inProcessed; + + p->inProcessed = p->mtc.inProcessed; + p->readRes = p->mtc.readRes; + p->readWasFinished = p->mtc.readWasFinished; + p->readProcessed = p->mtc.readProcessed; + + tMode = True; + needContinue = False; + + if (res == SZ_OK) + { + if (p->mtc.mtProgress.res != SZ_OK) + { + res = p->mtc.mtProgress.res; + stat->ProgressRes = res; + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + } + else + needContinue = p->mtc.needContinue; + } + + if (!needContinue) + { + SRes codeRes; + BoolInt truncated = False; + ECoderStatus status; + CXzUnpacker *dec; + + stat->OutSize = p->outProcessed; + + if (p->finishedDecoderIndex >= 0) + { + CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex]; + codeRes = coder->codeRes; + dec = &coder->dec; + status = coder->status; + } + else if (p->mainDecoderWasCalled) + { + codeRes = p->codeRes; + dec = &p->dec; + status = p->status; + truncated = p->parsing_Truncated; + } + else + return E_FAIL; + + XzStatInfo_SetStat(dec, p->finishMode, + p->mtc.readProcessed, p->mtc.inProcessed, + codeRes, status, + truncated, + stat); + + if (res == SZ_OK) + { + if (p->writeRes != SZ_OK) + { + res = p->writeRes; + stat->CombinedRes_Type = SZ_ERROR_WRITE; + } + else if (p->mtc.readRes != SZ_OK && p->mtc.inProcessed == p->mtc.readProcessed) + { + res = p->mtc.readRes; + stat->ReadRes = res; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + else if (p->mainErrorCode != SZ_OK) + { + res = p->mainErrorCode; + } + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } + + PRF_STR("----- decoding ST -----"); + } + } + + #endif + + + *isMT = False; + + { + SRes res = XzDecMt_Decode_ST(p + #ifndef _7ZIP_ST + , tMode + #endif + , stat + ); + + XzStatInfo_SetStat(&p->dec, + p->finishMode, + p->readProcessed, p->inProcessed, + p->codeRes, p->status, + False, // truncated + stat); + + if (res == SZ_OK) + { + /* + if (p->writeRes != SZ_OK) + { + res = p->writeRes; + stat->CombinedRes_Type = SZ_ERROR_WRITE; + } + else + */ + if (p->readRes != SZ_OK && p->inProcessed == p->readProcessed) + { + res = p->readRes; + stat->ReadRes = res; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + #ifndef _7ZIP_ST + else if (p->mainErrorCode != SZ_OK) + res = p->mainErrorCode; + #endif + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } +} diff --git a/components/ota/common/lzma/3rdparty/XzEnc.c b/components/ota/common/lzma/3rdparty/XzEnc.c new file mode 100644 index 00000000..de747457 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzEnc.c @@ -0,0 +1,1329 @@ +/* XzEnc.c -- Xz Encode +2019-02-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +#include + +#include "7zCrc.h" +#include "Bra.h" +#include "CpuArch.h" + +#ifdef USE_SUBBLOCK +#include "Bcj3Enc.c" +#include "SbFind.c" +#include "SbEnc.c" +#endif + +#include "XzEnc.h" + +#define _7ZIP_ST + +#ifndef _7ZIP_ST +#include "MtCoder.h" +#else +#define MTCODER__THREADS_MAX 1 +#define MTCODER__BLOCKS_MAX 1 +#endif + +#define XZ_GET_PAD_SIZE(dataSize) ((4 - ((unsigned)(dataSize) & 3)) & 3) + +/* max pack size for LZMA2 block + check-64bytrs: */ +#define XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize) ((unpackSize) + ((unpackSize) >> 10) + 16 + 64) + +#define XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(unpackSize) (XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize)) + + +#define XzBlock_ClearFlags(p) (p)->flags = 0; +#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1); +#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; +#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; + + +static SRes WriteBytes(ISeqOutStream *s, const void *buf, size_t size) +{ + return (ISeqOutStream_Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; +} + +static SRes WriteBytesUpdateCrc(ISeqOutStream *s, const void *buf, size_t size, UInt32 *crc) +{ + *crc = CrcUpdate(*crc, buf, size); + return WriteBytes(s, buf, size); +} + + +static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s) +{ + UInt32 crc; + Byte header[XZ_STREAM_HEADER_SIZE]; + memcpy(header, XZ_SIG, XZ_SIG_SIZE); + header[XZ_SIG_SIZE] = (Byte)(f >> 8); + header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); + crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); + SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc); + return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); +} + + +static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s) +{ + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + + unsigned pos = 1; + unsigned numFilters, i; + header[pos++] = p->flags; + + if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); + if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); + numFilters = XzBlock_GetNumFilters(p); + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + pos += Xz_WriteVarInt(header + pos, f->id); + pos += Xz_WriteVarInt(header + pos, f->propsSize); + memcpy(header + pos, f->props, f->propsSize); + pos += f->propsSize; + } + + while ((pos & 3) != 0) + header[pos++] = 0; + + header[0] = (Byte)(pos >> 2); + SetUi32(header + pos, CrcCalc(header, pos)); + return WriteBytes(s, header, pos + 4); +} + + + + +typedef struct +{ + size_t numBlocks; + size_t size; + size_t allocated; + Byte *blocks; +} CXzEncIndex; + + +static void XzEncIndex_Construct(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; + p->blocks = NULL; +} + +static void XzEncIndex_Init(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; +} + +static void XzEncIndex_Free(CXzEncIndex *p, ISzAllocPtr alloc) +{ + if (p->blocks) + { + ISzAlloc_Free(alloc, p->blocks); + p->blocks = NULL; + } + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; +} + + +static SRes XzEncIndex_ReAlloc(CXzEncIndex *p, size_t newSize, ISzAllocPtr alloc) +{ + Byte *blocks = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!blocks) + return SZ_ERROR_MEM; + if (p->size != 0) + memcpy(blocks, p->blocks, p->size); + if (p->blocks) + ISzAlloc_Free(alloc, p->blocks); + p->blocks = blocks; + p->allocated = newSize; + return SZ_OK; +} + + +static SRes XzEncIndex_PreAlloc(CXzEncIndex *p, UInt64 numBlocks, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + UInt64 pos; + { + Byte buf[32]; + unsigned pos2 = Xz_WriteVarInt(buf, totalSize); + pos2 += Xz_WriteVarInt(buf + pos2, unpackSize); + pos = numBlocks * pos2; + } + + if (pos <= p->allocated - p->size) + return SZ_OK; + { + UInt64 newSize64 = p->size + pos; + size_t newSize = (size_t)newSize64; + if (newSize != newSize64) + return SZ_ERROR_MEM; + return XzEncIndex_ReAlloc(p, newSize, alloc); + } +} + + +static SRes XzEncIndex_AddIndexRecord(CXzEncIndex *p, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + Byte buf[32]; + unsigned pos = Xz_WriteVarInt(buf, totalSize); + pos += Xz_WriteVarInt(buf + pos, unpackSize); + + if (pos > p->allocated - p->size) + { + size_t newSize = p->allocated * 2 + 16 * 2; + if (newSize < p->size + pos) + return SZ_ERROR_MEM; + RINOK(XzEncIndex_ReAlloc(p, newSize, alloc)); + } + memcpy(p->blocks + p->size, buf, pos); + p->size += pos; + p->numBlocks++; + return SZ_OK; +} + + +static SRes XzEncIndex_WriteFooter(const CXzEncIndex *p, CXzStreamFlags flags, ISeqOutStream *s) +{ + Byte buf[32]; + UInt64 globalPos; + UInt32 crc = CRC_INIT_VAL; + unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); + + globalPos = pos; + buf[0] = 0; + RINOK(WriteBytesUpdateCrc(s, buf, pos, &crc)); + RINOK(WriteBytesUpdateCrc(s, p->blocks, p->size, &crc)); + globalPos += p->size; + + pos = XZ_GET_PAD_SIZE(globalPos); + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + globalPos += pos; + + crc = CrcUpdate(crc, buf + 4 - pos, pos); + SetUi32(buf + 4, CRC_GET_DIGEST(crc)); + + SetUi32(buf + 8 + 4, (UInt32)(globalPos >> 2)); + buf[8 + 8] = (Byte)(flags >> 8); + buf[8 + 9] = (Byte)(flags & 0xFF); + SetUi32(buf + 8, CrcCalc(buf + 8 + 4, 6)); + buf[8 + 10] = XZ_FOOTER_SIG_0; + buf[8 + 11] = XZ_FOOTER_SIG_1; + + return WriteBytes(s, buf + 4 - pos, pos + 4 + 12); +} + + + +/* ---------- CSeqCheckInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStream *realStream; + const Byte *data; + UInt64 limit; + UInt64 processed; + int realStreamFinished; + CXzCheck check; +} CSeqCheckInStream; + +static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned checkMode) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->realStreamFinished = 0; + XzCheck_Init(&p->check, checkMode); +} + +static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest) +{ + XzCheck_Final(&p->check, digest); +} + +static SRes SeqCheckInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +{ + CSeqCheckInStream *p = CONTAINER_FROM_VTBL(pp, CSeqCheckInStream, vt); + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + if (p->realStream) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->realStreamFinished = (size2 == 0) ? 1 : 0; + } + else + memcpy(data, p->data + (size_t)p->processed, size2); + XzCheck_Update(&p->check, data, size2); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CSeqSizeOutStream ---------- */ + +typedef struct +{ + ISeqOutStream vt; + ISeqOutStream *realStream; + Byte *outBuf; + size_t outBufLimit; + UInt64 processed; +} CSeqSizeOutStream; + +static size_t SeqSizeOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size) +{ + CSeqSizeOutStream *p = CONTAINER_FROM_VTBL(pp, CSeqSizeOutStream, vt); + if (p->realStream) + size = ISeqOutStream_Write(p->realStream, data, size); + else + { + if (size > p->outBufLimit - (size_t)p->processed) + return 0; + memcpy(p->outBuf + (size_t)p->processed, data, size); + } + p->processed += size; + return size; +} + + +/* ---------- CSeqInFilter ---------- */ + +#define FILTER_BUF_SIZE (1 << 20) + +typedef struct +{ + ISeqInStream p; + ISeqInStream *realStream; + IStateCoder StateCoder; + Byte *buf; + size_t curPos; + size_t endPos; + int srcWasFinished; +} CSeqInFilter; + + +SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc); + +static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props, ISzAllocPtr alloc) +{ + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(alloc, FILTER_BUF_SIZE); + if (!p->buf) + return SZ_ERROR_MEM; + } + p->curPos = p->endPos = 0; + p->srcWasFinished = 0; + RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, alloc)); + RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, alloc)); + p->StateCoder.Init(p->StateCoder.p); + return SZ_OK; +} + + +static SRes SeqInFilter_Read(const ISeqInStream *pp, void *data, size_t *size) +{ + CSeqInFilter *p = CONTAINER_FROM_VTBL(pp, CSeqInFilter, p); + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + *size = 0; + + for (;;) + { + if (!p->srcWasFinished && p->curPos == p->endPos) + { + p->curPos = 0; + p->endPos = FILTER_BUF_SIZE; + RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos)); + if (p->endPos == 0) + p->srcWasFinished = 1; + } + { + SizeT srcLen = p->endPos - p->curPos; + ECoderStatus status; + SRes res; + *size = sizeOriginal; + res = p->StateCoder.Code2(p->StateCoder.p, + (Byte *)data, size, + p->buf + p->curPos, &srcLen, + p->srcWasFinished, CODER_FINISH_ANY, + &status); + p->curPos += srcLen; + if (*size != 0 || srcLen == 0 || res != SZ_OK) + return res; + } + } +} + +static void SeqInFilter_Construct(CSeqInFilter *p) +{ + p->buf = NULL; + p->StateCoder.p = NULL; + p->p.Read = SeqInFilter_Read; +} + +static void SeqInFilter_Free(CSeqInFilter *p, ISzAllocPtr alloc) +{ + if (p->StateCoder.p) + { + p->StateCoder.Free(p->StateCoder.p, alloc); + p->StateCoder.p = NULL; + } + if (p->buf) + { + ISzAlloc_Free(alloc, p->buf); + p->buf = NULL; + } +} + + +/* ---------- CSbEncInStream ---------- */ + +#ifdef USE_SUBBLOCK + +typedef struct +{ + ISeqInStream vt; + ISeqInStream *inStream; + CSbEnc enc; +} CSbEncInStream; + +static SRes SbEncInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +{ + CSbEncInStream *p = CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt); + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + + for (;;) + { + if (p->enc.needRead && !p->enc.readWasFinished) + { + size_t processed = p->enc.needReadSizeMax; + RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)); + p->enc.readPos += processed; + if (processed == 0) + { + p->enc.readWasFinished = True; + p->enc.isFinalFinished = True; + } + p->enc.needRead = False; + } + + *size = sizeOriginal; + RINOK(SbEnc_Read(&p->enc, data, size)); + if (*size != 0 || !p->enc.needRead) + return SZ_OK; + } +} + +void SbEncInStream_Construct(CSbEncInStream *p, ISzAllocPtr alloc) +{ + SbEnc_Construct(&p->enc, alloc); + p->vt.Read = SbEncInStream_Read; +} + +SRes SbEncInStream_Init(CSbEncInStream *p) +{ + return SbEnc_Init(&p->enc); +} + +void SbEncInStream_Free(CSbEncInStream *p) +{ + SbEnc_Free(&p->enc); +} + +#endif + + + +/* ---------- CXzProps ---------- */ + + +void XzFilterProps_Init(CXzFilterProps *p) +{ + p->id = 0; + p->delta = 0; + p->ip = 0; + p->ipDefined = False; +} + +void XzProps_Init(CXzProps *p) +{ + p->checkId = XZ_CHECK_CRC32; + p->blockSize = XZ_PROPS__BLOCK_SIZE__AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; + p->reduceSize = (UInt64)(Int64)-1; + p->forceWriteSizesInHeader = 0; + // p->forceWriteSizesInHeader = 1; + + XzFilterProps_Init(&p->filterProps); + Lzma2EncProps_Init(&p->lzma2Props); +} + + +static void XzEncProps_Normalize_Fixed(CXzProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + Lzma2EncProps_Normalize(&tp); + t1n = tp.numTotalThreads; + } + + t1 = p->lzma2Props.numTotalThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER__THREADS_MAX) + t2 = MTCODER__THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER__THREADS_MAX) + t2 = MTCODER__THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzma2Props.numTotalThreads = t1; + + t2r = t2; + + fileSize = p->reduceSize; + + if ((p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzma2Props.lzmaProps.reduceSize = p->blockSize; + + Lzma2EncProps_Normalize(&p->lzma2Props); + + t1 = p->lzma2Props.numTotalThreads; + + { + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (unsigned)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static void XzProps_Normalize(CXzProps *p) +{ + /* we normalize xzProps properties, but we normalize only some of CXzProps::lzma2Props properties. + Lzma2Enc_SetProps() will normalize lzma2Props later. */ + + if (p->blockSize == XZ_PROPS__BLOCK_SIZE__SOLID) + { + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + return; + } + else + { + CLzma2EncProps *lzma2 = &p->lzma2Props; + if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + { + // xz-auto + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + + if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + { + // if (xz-auto && lzma2-solid) - we use solid for both + p->blockSize = XZ_PROPS__BLOCK_SIZE__SOLID; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + } + else + { + // if (xz-auto && (lzma2-auto || lzma2-fixed_) + // we calculate block size for lzma2 and use that block size for xz, lzma2 uses single-chunk per block + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + + Lzma2EncProps_Normalize(&tp); + + p->blockSize = tp.blockSize; // fixed or solid + p->numBlockThreads_Reduced = tp.numBlockThreads_Reduced; + p->numBlockThreads_Max = tp.numBlockThreads_Max; + if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + lzma2->blockSize = tp.blockSize; // fixed or solid, LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + if (lzma2->lzmaProps.reduceSize > tp.blockSize && tp.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + lzma2->lzmaProps.reduceSize = tp.blockSize; + lzma2->numBlockThreads_Reduced = 1; + lzma2->numBlockThreads_Max = 1; + return; + } + } + else + { + // xz-fixed + // we can use xz::reduceSize or xz::blockSize as base for lzmaProps::reduceSize + + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + { + UInt64 r = p->reduceSize; + if (r > p->blockSize || r == (UInt64)(Int64)-1) + r = p->blockSize; + lzma2->lzmaProps.reduceSize = r; + } + if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + lzma2->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID; + else if (lzma2->blockSize > p->blockSize && lzma2->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + lzma2->blockSize = p->blockSize; + + XzEncProps_Normalize_Fixed(p); + } + } +} + + +/* ---------- CLzma2WithFilters ---------- */ + +typedef struct +{ + CLzma2EncHandle lzma2; + CSeqInFilter filter; + + #ifdef USE_SUBBLOCK + CSbEncInStream sb; + #endif +} CLzma2WithFilters; + + +static void Lzma2WithFilters_Construct(CLzma2WithFilters *p) +{ + p->lzma2 = NULL; + SeqInFilter_Construct(&p->filter); + + #ifdef USE_SUBBLOCK + SbEncInStream_Construct(&p->sb, alloc); + #endif +} + + +static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p, ISzAllocPtr alloc, ISzAllocPtr bigAlloc) +{ + if (!p->lzma2) + { + p->lzma2 = Lzma2Enc_Create(alloc, bigAlloc); + if (!p->lzma2) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + + +static void Lzma2WithFilters_Free(CLzma2WithFilters *p, ISzAllocPtr alloc) +{ + #ifdef USE_SUBBLOCK + SbEncInStream_Free(&p->sb); + #endif + + SeqInFilter_Free(&p->filter, alloc); + if (p->lzma2) + { + Lzma2Enc_Destroy(p->lzma2); + p->lzma2 = NULL; + } +} + + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; + size_t headerSize; +} CXzEncBlockInfo; + + +static SRes Xz_CompressBlock( + CLzma2WithFilters *lzmaf, + + ISeqOutStream *outStream, + Byte *outBufHeader, + Byte *outBufData, size_t outBufDataLimit, + + ISeqInStream *inStream, + // UInt64 expectedSize, + const Byte *inBuf, // used if (!inStream) + size_t inBufSize, // used if (!inStream), it's block size, props->blockSize is ignored + + const CXzProps *props, + ICompressProgress *progress, + int *inStreamFinished, /* only for inStream version */ + CXzEncBlockInfo *blockSizes, + ISzAllocPtr alloc, + ISzAllocPtr allocBig) +{ + CSeqCheckInStream checkInStream; + CSeqSizeOutStream seqSizeOutStream; + CXzBlock block; + unsigned filterIndex = 0; + CXzFilter *filter = NULL; + const CXzFilterProps *fp = &props->filterProps; + if (fp->id == 0) + fp = NULL; + + *inStreamFinished = False; + + RINOK(Lzma2WithFilters_Create(lzmaf, alloc, allocBig)); + + RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, &props->lzma2Props)); + + XzBlock_ClearFlags(&block); + XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); + + if (fp) + { + filter = &block.filters[filterIndex++]; + filter->id = fp->id; + filter->propsSize = 0; + + if (fp->id == XZ_ID_Delta) + { + filter->props[0] = (Byte)(fp->delta - 1); + filter->propsSize = 1; + } + else if (fp->ipDefined) + { + SetUi32(filter->props, fp->ip); + filter->propsSize = 4; + } + } + + { + CXzFilter *f = &block.filters[filterIndex++]; + f->id = XZ_ID_LZMA2; + f->propsSize = 1; + f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); + } + + seqSizeOutStream.vt.Write = SeqSizeOutStream_Write; + seqSizeOutStream.realStream = outStream; + seqSizeOutStream.outBuf = outBufData; + seqSizeOutStream.outBufLimit = outBufDataLimit; + seqSizeOutStream.processed = 0; + + /* + if (expectedSize != (UInt64)(Int64)-1) + { + block.unpackSize = expectedSize; + if (props->blockSize != (UInt64)(Int64)-1) + if (expectedSize > props->blockSize) + block.unpackSize = props->blockSize; + XzBlock_SetHasUnpackSize(&block); + } + */ + + if (outStream) + { + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)); + } + + checkInStream.vt.Read = SeqCheckInStream_Read; + SeqCheckInStream_Init(&checkInStream, props->checkId); + + checkInStream.realStream = inStream; + checkInStream.data = inBuf; + checkInStream.limit = props->blockSize; + if (!inStream) + checkInStream.limit = inBufSize; + + if (fp) + { + #ifdef USE_SUBBLOCK + if (fp->id == XZ_ID_Subblock) + { + lzmaf->sb.inStream = &checkInStream.vt; + RINOK(SbEncInStream_Init(&lzmaf->sb)); + } + else + #endif + { + lzmaf->filter.realStream = &checkInStream.vt; + RINOK(SeqInFilter_Init(&lzmaf->filter, filter, alloc)); + } + } + + { + SRes res; + Byte *outBuf = NULL; + size_t outSize = 0; + BoolInt useStream = (fp || inStream); + // useStream = True; + + if (!useStream) + { + XzCheck_Update(&checkInStream.check, inBuf, inBufSize); + checkInStream.processed = inBufSize; + } + + if (!outStream) + { + outBuf = seqSizeOutStream.outBuf; // + (size_t)seqSizeOutStream.processed; + outSize = seqSizeOutStream.outBufLimit; // - (size_t)seqSizeOutStream.processed; + } + + res = Lzma2Enc_Encode2(lzmaf->lzma2, + outBuf ? NULL : &seqSizeOutStream.vt, + outBuf, + outBuf ? &outSize : NULL, + + useStream ? + (fp ? + ( + #ifdef USE_SUBBLOCK + (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.vt: + #endif + &lzmaf->filter.p) : + &checkInStream.vt) : NULL, + + useStream ? NULL : inBuf, + useStream ? 0 : inBufSize, + + progress); + + if (outBuf) + seqSizeOutStream.processed += outSize; + + RINOK(res); + blockSizes->unpackSize = checkInStream.processed; + } + { + Byte buf[4 + 64]; + unsigned padSize = XZ_GET_PAD_SIZE(seqSizeOutStream.processed); + UInt64 packSize = seqSizeOutStream.processed; + + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + + SeqCheckInStream_GetDigest(&checkInStream, buf + 4); + RINOK(WriteBytes(&seqSizeOutStream.vt, buf + (4 - padSize), padSize + XzFlags_GetCheckSize((CXzStreamFlags)props->checkId))); + + blockSizes->totalSize = seqSizeOutStream.processed - padSize; + + if (!outStream) + { + seqSizeOutStream.outBuf = outBufHeader; + seqSizeOutStream.outBufLimit = XZ_BLOCK_HEADER_SIZE_MAX; + seqSizeOutStream.processed = 0; + + block.unpackSize = blockSizes->unpackSize; + XzBlock_SetHasUnpackSize(&block); + + block.packSize = packSize; + XzBlock_SetHasPackSize(&block); + + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)); + + blockSizes->headerSize = (size_t)seqSizeOutStream.processed; + blockSizes->totalSize += seqSizeOutStream.processed; + } + } + + if (inStream) + *inStreamFinished = checkInStream.realStreamFinished; + else + { + *inStreamFinished = False; + if (checkInStream.processed != inBufSize) + return SZ_ERROR_FAIL; + } + + return SZ_OK; +} + + + +typedef struct +{ + ICompressProgress vt; + ICompressProgress *progress; + UInt64 inOffset; + UInt64 outOffset; +} CCompressProgress_XzEncOffset; + + +static SRes CompressProgress_XzEncOffset_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) +{ + const CCompressProgress_XzEncOffset *p = CONTAINER_FROM_VTBL(pp, CCompressProgress_XzEncOffset, vt); + inSize += p->inOffset; + outSize += p->outOffset; + return ICompressProgress_Progress(p->progress, inSize, outSize); +} + + + + +typedef struct +{ + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CXzProps xzProps; + UInt64 expectedDataSize; + + CXzEncIndex xzIndex; + + CLzma2WithFilters lzmaf_Items[MTCODER__THREADS_MAX]; + + size_t outBufSize; /* size of allocated outBufs[i] */ + Byte *outBufs[MTCODER__BLOCKS_MAX]; + + #ifndef _7ZIP_ST + unsigned checkType; + ISeqOutStream *outStream; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + CXzEncBlockInfo EncBlocks[MTCODER__BLOCKS_MAX]; + #endif + +} CXzEnc; + + +static void XzEnc_Construct(CXzEnc *p) +{ + unsigned i; + + XzEncIndex_Construct(&p->xzIndex); + + for (i = 0; i < MTCODER__THREADS_MAX; i++) + Lzma2WithFilters_Construct(&p->lzmaf_Items[i]); + + #ifndef _7ZIP_ST + p->mtCoder_WasConstructed = False; + { + for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif +} + + +static void XzEnc_FreeOutBufs(CXzEnc *p) +{ + unsigned i; + for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + + +static void XzEnc_Free(CXzEnc *p, ISzAllocPtr alloc) +{ + unsigned i; + + XzEncIndex_Free(&p->xzIndex, alloc); + + for (i = 0; i < MTCODER__THREADS_MAX; i++) + Lzma2WithFilters_Free(&p->lzmaf_Items[i], alloc); + + #ifndef _7ZIP_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + XzEnc_FreeOutBufs(p); + #endif +} + + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CXzEnc *p = (CXzEnc *)ISzAlloc_Alloc(alloc, sizeof(CXzEnc)); + if (!p) + return NULL; + XzEnc_Construct(p); + XzProps_Init(&p->xzProps); + XzProps_Normalize(&p->xzProps); + p->expectedDataSize = (UInt64)(Int64)-1; + p->alloc = alloc; + p->allocBig = allocBig; + return p; +} + + +void XzEnc_Destroy(CXzEncHandle pp) +{ + CXzEnc *p = (CXzEnc *)pp; + XzEnc_Free(p, p->alloc); + ISzAlloc_Free(p->alloc, p); +} + + +SRes XzEnc_SetProps(CXzEncHandle pp, const CXzProps *props) +{ + CXzEnc *p = (CXzEnc *)pp; + p->xzProps = *props; + XzProps_Normalize(&p->xzProps); + return SZ_OK; +} + + +void XzEnc_SetDataSize(CXzEncHandle pp, UInt64 expectedDataSiize) +{ + CXzEnc *p = (CXzEnc *)pp; + p->expectedDataSize = expectedDataSiize; +} + + + + +#ifndef _7ZIP_ST + +static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CXzEnc *me = (CXzEnc *)pp; + SRes res; + CMtProgressThunk progressThunk; + + Byte *dest = me->outBufs[outBufIndex]; + + UNUSED_VAR(finished) + + { + CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + bInfo->totalSize = 0; + bInfo->unpackSize = 0; + bInfo->headerSize = 0; + } + + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + MtProgressThunk_Init(&progressThunk); + + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + res = Xz_CompressBlock( + &me->lzmaf_Items[coderIndex], + + NULL, + dest, + dest + XZ_BLOCK_HEADER_SIZE_MAX, me->outBufSize - XZ_BLOCK_HEADER_SIZE_MAX, + + NULL, + // srcSize, // expectedSize + src, srcSize, + + &me->xzProps, + &progressThunk.vt, + &inStreamFinished, + &blockSizes, + me->alloc, + me->allocBig); + + if (res == SZ_OK) + me->EncBlocks[outBufIndex] = blockSizes; + + return res; + } +} + + +static SRes XzEnc_MtCallback_Write(void *pp, unsigned outBufIndex) +{ + CXzEnc *me = (CXzEnc *)pp; + + const CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + const Byte *data = me->outBufs[outBufIndex]; + + RINOK(WriteBytes(me->outStream, data, bInfo->headerSize)); + + { + UInt64 totalPackFull = bInfo->totalSize + XZ_GET_PAD_SIZE(bInfo->totalSize); + RINOK(WriteBytes(me->outStream, data + XZ_BLOCK_HEADER_SIZE_MAX, (size_t)totalPackFull - bInfo->headerSize)); + } + + return XzEncIndex_AddIndexRecord(&me->xzIndex, bInfo->unpackSize, bInfo->totalSize, me->alloc); +} + +#endif + + + +SRes XzEnc_Encode(CXzEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) +{ + CXzEnc *p = (CXzEnc *)pp; + + const CXzProps *props = &p->xzProps; + + XzEncIndex_Init(&p->xzIndex); + { + UInt64 numBlocks = 1; + UInt64 blockSize = props->blockSize; + + if (blockSize != XZ_PROPS__BLOCK_SIZE__SOLID + && props->reduceSize != (UInt64)(Int64)-1) + { + numBlocks = props->reduceSize / blockSize; + if (numBlocks * blockSize != props->reduceSize) + numBlocks++; + } + else + blockSize = (UInt64)1 << 62; + + RINOK(XzEncIndex_PreAlloc(&p->xzIndex, numBlocks, blockSize, XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(blockSize), p->alloc)); + } + + RINOK(Xz_WriteHeader((CXzStreamFlags)props->checkId, outStream)); + + + #ifndef _7ZIP_ST + if (props->numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = XzEnc_MtCallback_Code; + vt.Write = XzEnc_MtCallback_Write; + + p->checkType = props->checkId; + p->xzProps = *props; + + p->outStream = outStream; + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = NULL; + p->mtCoder.inDataSize = 0; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + if ( props->blockSize == XZ_PROPS__BLOCK_SIZE__SOLID + || props->blockSize == XZ_PROPS__BLOCK_SIZE__AUTO) + return SZ_ERROR_FAIL; + + p->mtCoder.blockSize = (size_t)props->blockSize; + if (p->mtCoder.blockSize != props->blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + size_t destBlockSize = XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(p->mtCoder.blockSize); + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + XzEnc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = props->numBlockThreads_Max; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + RINOK(MtCoder_Code(&p->mtCoder)); + } + else + #endif + { + int writeStartSizes; + CCompressProgress_XzEncOffset progress2; + Byte *bufData = NULL; + size_t bufSize = 0; + + progress2.vt.Progress = CompressProgress_XzEncOffset_Progress; + progress2.inOffset = 0; + progress2.outOffset = 0; + progress2.progress = progress; + + writeStartSizes = 0; + + if (props->blockSize != XZ_PROPS__BLOCK_SIZE__SOLID) + { + writeStartSizes = (props->forceWriteSizesInHeader > 0); + + if (writeStartSizes) + { + size_t t2; + size_t t = (size_t)props->blockSize; + if (t != props->blockSize) + return SZ_ERROR_PARAM; + t = XZ_GET_MAX_BLOCK_PACK_SIZE(t); + if (t < props->blockSize) + return SZ_ERROR_PARAM; + t2 = XZ_BLOCK_HEADER_SIZE_MAX + t; + if (!p->outBufs[0] || t2 != p->outBufSize) + { + XzEnc_FreeOutBufs(p); + p->outBufs[0] = (Byte *)ISzAlloc_Alloc(p->alloc, t2); + if (!p->outBufs[0]) + return SZ_ERROR_MEM; + p->outBufSize = t2; + } + bufData = p->outBufs[0] + XZ_BLOCK_HEADER_SIZE_MAX; + bufSize = t; + } + } + + for (;;) + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + /* + UInt64 rem = (UInt64)(Int64)-1; + if (props->reduceSize != (UInt64)(Int64)-1 + && props->reduceSize >= progress2.inOffset) + rem = props->reduceSize - progress2.inOffset; + */ + + blockSizes.headerSize = 0; // for GCC + + RINOK(Xz_CompressBlock( + &p->lzmaf_Items[0], + + writeStartSizes ? NULL : outStream, + writeStartSizes ? p->outBufs[0] : NULL, + bufData, bufSize, + + inStream, + // rem, + NULL, 0, + + props, + progress ? &progress2.vt : NULL, + &inStreamFinished, + &blockSizes, + p->alloc, + p->allocBig)); + + { + UInt64 totalPackFull = blockSizes.totalSize + XZ_GET_PAD_SIZE(blockSizes.totalSize); + + if (writeStartSizes) + { + RINOK(WriteBytes(outStream, p->outBufs[0], blockSizes.headerSize)); + RINOK(WriteBytes(outStream, bufData, (size_t)totalPackFull - blockSizes.headerSize)); + } + + RINOK(XzEncIndex_AddIndexRecord(&p->xzIndex, blockSizes.unpackSize, blockSizes.totalSize, p->alloc)); + + progress2.inOffset += blockSizes.unpackSize; + progress2.outOffset += totalPackFull; + } + + if (inStreamFinished) + break; + } + } + + return XzEncIndex_WriteFooter(&p->xzIndex, (CXzStreamFlags)props->checkId, outStream); +} + + +#include "Alloc.h" + +SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, + const CXzProps *props, ICompressProgress *progress) +{ + SRes res; + CXzEncHandle xz = XzEnc_Create(&g_Alloc, &g_BigAlloc); + if (!xz) + return SZ_ERROR_MEM; + res = XzEnc_SetProps(xz, props); + if (res == SZ_OK) + res = XzEnc_Encode(xz, outStream, inStream, progress); + XzEnc_Destroy(xz); + return res; +} + + +SRes Xz_EncodeEmpty(ISeqOutStream *outStream) +{ + SRes res; + CXzEncIndex xzIndex; + XzEncIndex_Construct(&xzIndex); + res = Xz_WriteHeader((CXzStreamFlags)0, outStream); + if (res == SZ_OK) + res = XzEncIndex_WriteFooter(&xzIndex, (CXzStreamFlags)0, outStream); + XzEncIndex_Free(&xzIndex, NULL); // g_Alloc + return res; +} diff --git a/components/ota/common/lzma/3rdparty/XzEnc.h b/components/ota/common/lzma/3rdparty/XzEnc.h new file mode 100644 index 00000000..0c29e7e1 --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzEnc.h @@ -0,0 +1,60 @@ +/* XzEnc.h -- Xz Encode +2017-06-27 : Igor Pavlov : Public domain */ + +#ifndef __XZ_ENC_H +#define __XZ_ENC_H + +#include "Lzma2Enc.h" + +#include "Xz.h" + +EXTERN_C_BEGIN + + +#define XZ_PROPS__BLOCK_SIZE__AUTO LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO +#define XZ_PROPS__BLOCK_SIZE__SOLID LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + + +typedef struct +{ + UInt32 id; + UInt32 delta; + UInt32 ip; + int ipDefined; +} CXzFilterProps; + +void XzFilterProps_Init(CXzFilterProps *p); + + +typedef struct +{ + CLzma2EncProps lzma2Props; + CXzFilterProps filterProps; + unsigned checkId; + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; + int forceWriteSizesInHeader; + UInt64 reduceSize; +} CXzProps; + +void XzProps_Init(CXzProps *p); + + +typedef void * CXzEncHandle; + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void XzEnc_Destroy(CXzEncHandle p); +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props); +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize); +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress); + +SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, + const CXzProps *props, ICompressProgress *progress); + +SRes Xz_EncodeEmpty(ISeqOutStream *outStream); + +EXTERN_C_END + +#endif diff --git a/components/ota/common/lzma/3rdparty/XzIn.c b/components/ota/common/lzma/3rdparty/XzIn.c new file mode 100644 index 00000000..ff48e2dd --- /dev/null +++ b/components/ota/common/lzma/3rdparty/XzIn.c @@ -0,0 +1,319 @@ +/* XzIn.c - Xz input +2018-07-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zCrc.h" +#include "CpuArch.h" +#include "Xz.h" + +/* +#define XZ_FOOTER_SIG_CHECK(p) (memcmp((p), XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0) +*/ +#define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1) + + +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) +{ + Byte sig[XZ_STREAM_HEADER_SIZE]; + RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE)); + if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) + return SZ_ERROR_NO_ARCHIVE; + return Xz_ParseHeader(p, sig); +} + +#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ + { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } + +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes) +{ + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + unsigned headerSize; + *headerSizeRes = 0; + RINOK(SeqInStream_ReadByte(inStream, &header[0])); + headerSize = (unsigned)header[0]; + if (headerSize == 0) + { + *headerSizeRes = 1; + *isIndex = True; + return SZ_OK; + } + + *isIndex = False; + headerSize = (headerSize << 2) + 4; + *headerSizeRes = headerSize; + RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1)); + return XzBlock_Parse(p, header); +} + +#define ADD_SIZE_CHECK(size, val) \ + { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; } + +UInt64 Xz_GetUnpackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + ADD_SIZE_CHECK(size, p->blocks[i].unpackSize); + return size; +} + +UInt64 Xz_GetPackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3); + return size; +} + +/* +SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) +{ + return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); +} +*/ + +static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + size_t numBlocks, pos = 1; + UInt32 crc; + + if (size < 5 || buf[0] != 0) + return SZ_ERROR_ARCHIVE; + + size -= 4; + crc = CrcCalc(buf, size); + if (crc != GetUi32(buf + size)) + return SZ_ERROR_ARCHIVE; + + { + UInt64 numBlocks64; + READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64); + numBlocks = (size_t)numBlocks64; + if (numBlocks != numBlocks64 || numBlocks * 2 > size) + return SZ_ERROR_ARCHIVE; + } + + Xz_Free(p, alloc); + if (numBlocks != 0) + { + size_t i; + p->numBlocks = numBlocks; + p->blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); + if (!p->blocks) + return SZ_ERROR_MEM; + for (i = 0; i < numBlocks; i++) + { + CXzBlockSizes *block = &p->blocks[i]; + READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize); + READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize); + if (block->totalSize == 0) + return SZ_ERROR_ARCHIVE; + } + } + while ((pos & 3) != 0) + if (buf[pos++] != 0) + return SZ_ERROR_ARCHIVE; + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAllocPtr alloc) +{ + SRes res; + size_t size; + Byte *buf; + if (indexSize > ((UInt32)1 << 31)) + return SZ_ERROR_UNSUPPORTED; + size = (size_t)indexSize; + if (size != indexSize) + return SZ_ERROR_UNSUPPORTED; + buf = (Byte *)ISzAlloc_Alloc(alloc, size); + if (!buf) + return SZ_ERROR_MEM; + res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); + if (res == SZ_OK) + res = Xz_ReadIndex2(p, buf, size, alloc); + ISzAlloc_Free(alloc, buf); + return res; +} + +static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size) +{ + RINOK(LookInStream_SeekTo(stream, offset)); + return LookInStream_Read(stream, buf, size); + /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ +} + +static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc) +{ + UInt64 indexSize; + Byte buf[XZ_STREAM_FOOTER_SIZE]; + UInt64 pos = *startOffset; + + if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); + + if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + { + UInt32 total = 0; + pos += XZ_STREAM_FOOTER_SIZE; + + for (;;) + { + size_t i; + #define TEMP_BUF_SIZE (1 << 10) + Byte temp[TEMP_BUF_SIZE]; + + i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; + pos -= i; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)); + total += (UInt32)i; + for (; i != 0; i--) + if (temp[i - 1] != 0) + break; + if (i != 0) + { + if ((i & 3) != 0) + return SZ_ERROR_NO_ARCHIVE; + pos += i; + break; + } + if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) + return SZ_ERROR_NO_ARCHIVE; + } + + if (pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); + if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + return SZ_ERROR_NO_ARCHIVE; + } + + p->flags = (CXzStreamFlags)GetBe16(buf + 8); + + if (!XzFlags_IsSupported(p->flags)) + return SZ_ERROR_UNSUPPORTED; + + if (GetUi32(buf) != CrcCalc(buf + 4, 6)) + return SZ_ERROR_ARCHIVE; + + indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; + + if (pos < indexSize) + return SZ_ERROR_ARCHIVE; + + pos -= indexSize; + RINOK(LookInStream_SeekTo(stream, pos)); + RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)); + + { + UInt64 totalSize = Xz_GetPackSize(p); + if (totalSize == XZ_SIZE_OVERFLOW + || totalSize >= ((UInt64)1 << 63) + || pos < totalSize + XZ_STREAM_HEADER_SIZE) + return SZ_ERROR_ARCHIVE; + pos -= (totalSize + XZ_STREAM_HEADER_SIZE); + RINOK(LookInStream_SeekTo(stream, pos)); + *startOffset = pos; + } + { + CXzStreamFlags headerFlags; + CSecToRead secToRead; + SecToRead_CreateVTable(&secToRead); + secToRead.realStream = stream; + + RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)); + return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; + } +} + + +/* ---------- Xz Streams ---------- */ + +void Xzs_Construct(CXzs *p) +{ + p->num = p->numAllocated = 0; + p->streams = 0; +} + +void Xzs_Free(CXzs *p, ISzAllocPtr alloc) +{ + size_t i; + for (i = 0; i < p->num; i++) + Xz_Free(&p->streams[i], alloc); + ISzAlloc_Free(alloc, p->streams); + p->num = p->numAllocated = 0; + p->streams = 0; +} + +UInt64 Xzs_GetNumBlocks(const CXzs *p) +{ + UInt64 num = 0; + size_t i; + for (i = 0; i < p->num; i++) + num += p->streams[i].numBlocks; + return num; +} + +UInt64 Xzs_GetUnpackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])); + return size; +} + +/* +UInt64 Xzs_GetPackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])); + return size; +} +*/ + +SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc) +{ + Int64 endOffset = 0; + RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)); + *startOffset = endOffset; + for (;;) + { + CXzStream st; + SRes res; + Xz_Construct(&st); + res = Xz_ReadBackward(&st, stream, startOffset, alloc); + st.startOffset = *startOffset; + RINOK(res); + if (p->num == p->numAllocated) + { + size_t newNum = p->num + p->num / 4 + 1; + Byte *data = (Byte *)ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream)); + if (!data) + return SZ_ERROR_MEM; + p->numAllocated = newNum; + if (p->num != 0) + memcpy(data, p->streams, p->num * sizeof(CXzStream)); + ISzAlloc_Free(alloc, p->streams); + p->streams = (CXzStream *)data; + } + p->streams[p->num++] = st; + if (*startOffset == 0) + break; + RINOK(LookInStream_SeekTo(stream, *startOffset)); + if (progress && ICompressProgress_Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK) + return SZ_ERROR_PROGRESS; + } + return SZ_OK; +} diff --git a/components/ota/common/lzma/version b/components/ota/common/lzma/version new file mode 100644 index 00000000..6bf67c19 --- /dev/null +++ b/components/ota/common/lzma/version @@ -0,0 +1 @@ +19.00 diff --git a/components/ota/common/lzma/wrapper/lzma_compress.c b/components/ota/common/lzma/wrapper/lzma_compress.c new file mode 100644 index 00000000..93c7110c --- /dev/null +++ b/components/ota/common/lzma/wrapper/lzma_compress.c @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "lzma_compress.h" + +#include "Alloc.h" +#include "LzmaDec.h" +#include "LzmaEnc.h" + +#include "stdlib.h" + +#pragma pack(push, 1) +typedef struct lzma_props_st { + uint8_t data[LZMA_PROPS_SIZE]; +} lzma_props_t; +#pragma pack(pop) + +static void *lzma_wrapper_alloc(ISzAllocPtr p, size_t size) +{ + (void)p; + if (size == 0) { + return 0; + } + return malloc(size); +} + +static void lzma_wrapper_free(ISzAllocPtr p, void *address) +{ + (void)p; + free(address); +} + +static ISzAlloc wrapper_alloc = { lzma_wrapper_alloc, lzma_wrapper_free }; + +static lzma_err_t lzma_do_compress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t src_len, lzma_props_t *props) +{ + CLzmaEncProps enc_props; + size_t props_size = LZMA_PROPS_SIZE; + + LzmaEncProps_Init(&enc_props); + enc_props.level = 9; + enc_props.lc = 0; + + return (lzma_err_t)LzmaEncode(dst, dst_len, + src, src_len, + &enc_props, + props->data, &props_size, + 0, NULL, + &wrapper_alloc, &wrapper_alloc); +} + +lzma_err_t lzma_compress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t src_len) +{ + lzma_err_t err; + lzma_props_t *out_props; + size_t compressed_len; + + if (*dst_len <= sizeof(lzma_props_t)) { + return LZMA_ERR_MEM; + } + + out_props = (lzma_props_t *)dst; + compressed_len = *dst_len - sizeof(lzma_props_t); + + err = lzma_do_compress(dst + sizeof(lzma_props_t), &compressed_len, + src, src_len, out_props); + if (err == LZMA_ERR_OK) { + *dst_len = compressed_len + sizeof(lzma_props_t); + } + + return err; +} + diff --git a/components/ota/common/lzma/wrapper/lzma_compress.h b/components/ota/common/lzma/wrapper/lzma_compress.h new file mode 100644 index 00000000..5ce79f22 --- /dev/null +++ b/components/ota/common/lzma/wrapper/lzma_compress.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _LZMA_COMPRESS_H_ +#define _LZMA_COMPRESS_H_ + +#include "stdint.h" + +#include "lzma_err.h" + +lzma_err_t lzma_compress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t src_len); + +#endif /* _LZMA_COMPRESS_H_ */ + diff --git a/components/ota/common/lzma/wrapper/lzma_err.h b/components/ota/common/lzma/wrapper/lzma_err.h new file mode 100644 index 00000000..00d89991 --- /dev/null +++ b/components/ota/common/lzma/wrapper/lzma_err.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _LZMA_ERR_H_ +#define _LZMA_ERR_H_ + +#include "7zTypes.h" + +typedef enum lzma_err_en { + LZMA_ERR_OK = SZ_OK, + + LZMA_ERR_DATA = SZ_ERROR_DATA, + LZMA_ERR_MEM = SZ_ERROR_MEM, + LZMA_ERR_CRC = SZ_ERROR_CRC, + LZMA_ERR_UNSUPPORTED = SZ_ERROR_UNSUPPORTED, + LZMA_ERR_PARAM = SZ_ERROR_PARAM, + LZMA_ERR_INPUT_EOF = SZ_ERROR_INPUT_EOF, + LZMA_ERR_OUTPUT_EOF = SZ_ERROR_OUTPUT_EOF, + LZMA_ERR_READ = SZ_ERROR_READ, + LZMA_ERR_WRITE = SZ_ERROR_WRITE, + LZMA_ERR_PROGRESS = SZ_ERROR_PROGRESS, + LZMA_ERR_FAI = SZ_ERROR_FAIL, + LZMA_ERR_THREAD = SZ_ERROR_THREAD, + + LZMA_ERR_ARCHIVE = SZ_ERROR_ARCHIVE, + LZMA_ERR_NO_ARCHIV = SZ_ERROR_NO_ARCHIVE, + + LZMA_ERR_EXCEEDED, +} lzma_err_t; + +#endif /* _LZMA_ERR_H_ */ + diff --git a/components/ota/common/lzma/wrapper/lzma_uncompress.c b/components/ota/common/lzma/wrapper/lzma_uncompress.c new file mode 100644 index 00000000..dcf9ab14 --- /dev/null +++ b/components/ota/common/lzma/wrapper/lzma_uncompress.c @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "lzma_uncompress.h" + +#include "Alloc.h" +#include "LzmaDec.h" +#include "LzmaEnc.h" + +#include "stdint.h" +#include "stdlib.h" + +#pragma pack(push, 1) +typedef struct lzma_props_st { + uint8_t data[LZMA_PROPS_SIZE]; +} lzma_props_t; +#pragma pack(pop) + +static void *lzma_wrapper_alloc(ISzAllocPtr p, size_t size) +{ + (void)p; + if (size == 0) { + return 0; + } + return malloc(size); +} + +static void lzma_wrapper_free(ISzAllocPtr p, void *address) +{ + (void)p; + free(address); +} + +static ISzAlloc wrapper_alloc = { lzma_wrapper_alloc, lzma_wrapper_free }; + +static lzma_err_t lzma_do_uncompress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t *src_len, lzma_props_t *props) +{ + ELzmaStatus status; + + return (lzma_err_t)LzmaDecode(dst, dst_len, + src, src_len, + props->data, LZMA_PROPS_SIZE, + LZMA_FINISH_ANY, &status, &wrapper_alloc); +} + +lzma_err_t lzma_uncompress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t *src_len) +{ + lzma_props_t *props; + + if (*src_len <= sizeof(lzma_props_t)) { + return LZMA_ERR_MEM; + } + + props = (lzma_props_t *)src; + *src_len = *src_len - sizeof(lzma_props_t); + + return lzma_do_uncompress(dst, dst_len, + src + sizeof(lzma_props_t), src_len, + props); +} + diff --git a/components/ota/common/lzma/wrapper/lzma_uncompress.h b/components/ota/common/lzma/wrapper/lzma_uncompress.h new file mode 100644 index 00000000..ddc5cc24 --- /dev/null +++ b/components/ota/common/lzma/wrapper/lzma_uncompress.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _LZMA_UNCOMPRESS_H_ +#define _LZMA_UNCOMPRESS_H_ + +#include "stdint.h" + +#include "lzma_err.h" + +lzma_err_t lzma_uncompress(uint8_t *dst, size_t *dst_len, const uint8_t *src, size_t *src_len); + +#endif /* _LZMA_UNCOMPRESS_H_ */ + diff --git a/components/ota/common/partition/ota_partition.c b/components/ota/common/partition/ota_partition.c new file mode 100644 index 00000000..4fdfec1b --- /dev/null +++ b/components/ota/common/partition/ota_partition.c @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "ota_flash.h" +#include "ota_partition.h" + +static ota_pt_ctrl_t ctrl; + +static int partitions_verify(ota_pt_t *pts, int n) +{ + int i = 0; + + for (i = 0; i < n; ++i) { + if (pts[i].start >= pts[i].end) { + return -1; + } + + if (!ota_flash_size_is_aligned(pts[i].end - pts[i].start)) { + return -1; + } + } + + return 0; +} + +int ota_partition_load(ota_updt_type_t updt_type, uint32_t partition_addr) +{ + uint8_t crc = 0; + ota_pt_hdr_t hdr; + + memset(&ctrl, 0, sizeof(ota_pt_ctrl_t)); + + if (ota_flash_read(partition_addr, &hdr, sizeof(ota_pt_hdr_t)) != 0) { + return -1; + } + + if (hdr.magic != OTA_PARTITION_MAGIC) { + return -1; + } + + ctrl.updt_type = updt_type; + ctrl.version = hdr.version; + + crc = partition_hdr_crc(&hdr); + + if (updt_type == OTA_UPDATE_IN_POSITION) { + if (ota_flash_read(partition_addr + sizeof(ota_pt_hdr_t), &IP_PTS, sizeof(ota_ip_pts_t)) != 0) { + return -1; + } + + if (partitions_verify(IP_PTS_ARRAY, sizeof(IP_PTS) / sizeof(ota_pt_t)) != 0) { + return -1; + } + + crc = partitions_crc(crc, IP_PTS_ARRAY, sizeof(IP_PTS) / sizeof(ota_pt_t)); + } else if (updt_type == OTA_UPDATE_PING_PONG) { + if (ota_flash_read(partition_addr + sizeof(ota_pt_hdr_t), &PP_PTS, sizeof(ota_pp_pts_t)) != 0) { + return -1; + } + + if (partitions_verify(PP_PTS_ARRAY, sizeof(PP_PTS) / sizeof(ota_pt_t)) != 0) { + return -1; + } + + crc = partitions_crc(crc, PP_PTS_ARRAY, sizeof(PP_PTS) / sizeof(ota_pt_t)); + } else { + return -1; + } + + if (crc != hdr.crc) { + return -1; + } + + return 0; +} + +uint32_t ota_partition_start(ota_pt_type_t pt_type) +{ + if (pt_type == OTA_PARTITION_ACTIVE_APP) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(active_app).start; + } else { + return PP_PT(active_app).start; + } + } else if (pt_type == OTA_PARTITION_BACKUP_APP) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return OTA_PARTITION_INVALID; + } else { + return PP_PT(backup_app).start; + } + } else if (pt_type == OTA_PARTITION_OTA) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(ota).start; + } else { + return PP_PT(ota).start; + } + } else if (pt_type == OTA_PARTITION_KV) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(kv).start; + } else { + return PP_PT(kv).start; + } + } else { + return OTA_PARTITION_INVALID; + } +} + +uint32_t ota_partition_end(ota_pt_type_t pt_type) +{ + if (pt_type == OTA_PARTITION_ACTIVE_APP) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(active_app).end; + } else { + return PP_PT(active_app).end; + } + } else if (pt_type == OTA_PARTITION_BACKUP_APP) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return OTA_PARTITION_INVALID; + } else { + return PP_PT(backup_app).end; + } + } else if (pt_type == OTA_PARTITION_OTA) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(ota).end; + } else { + return PP_PT(ota).end; + } + } else if (pt_type == OTA_PARTITION_KV) { + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION) { + return IP_PT(kv).end; + } else { + return PP_PT(kv).end; + } + } else { + return OTA_PARTITION_INVALID; + } +} + +uint32_t ota_partition_size(ota_pt_type_t pt_type) +{ + if (ctrl.updt_type == OTA_UPDATE_IN_POSITION && + pt_type == OTA_PARTITION_BACKUP_APP) { + return OTA_PARTITION_INVALID; + } + + return ota_partition_end(pt_type) - ota_partition_start(pt_type); +} + +int ota_partition_is_pingpong(void) +{ + return ctrl.updt_type == OTA_UPDATE_PING_PONG; +} + +ota_img_vs_t ota_partition_init_version_get(void) +{ + return ctrl.version; +} + diff --git a/components/ota/common/partition/ota_partition.h b/components/ota/common/partition/ota_partition.h new file mode 100644 index 00000000..d5aebb63 --- /dev/null +++ b/components/ota/common/partition/ota_partition.h @@ -0,0 +1,158 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_PARTITION_H_ +#define _OTA_PARTITION_H_ + +#include "crc8.h" +#include "ota_image.h" + +#define OTA_PARTITION_INVALID (uint32_t)-1 + +#define OTA_PARTITION_MAGIC 0x6420 + +#define IP_PTS (ctrl.pts.ip.ip_pts) +#define PP_PTS (ctrl.pts.pp.pp_pts) + +#define IP_PT(t) (IP_PTS.t) +#define PP_PT(t) (PP_PTS.t) + +#define IP_PTS_ARRAY (&ctrl.pts.ip.pts[0]) +#define PP_PTS_ARRAY (&ctrl.pts.pp.pts[0]) + +#pragma pack(push, 1) +typedef struct ota_partition_header_st { + uint16_t magic; /* a certain number */ + ota_img_vs_t version; /* the initial version of the application */ + uint8_t crc; /* crc of the whole partition table */ + uint8_t reserved[3]; +} ota_pt_hdr_t; +#pragma pack(pop) + +/* + if you have a in-position update partition, partition table should be: + 0 2 magic | + 2 2 version | + 4 1 crc | partition table header + 5 3 reserved | + + 8 4 start(active application) | active application partition + 12 4 end(active application) | + + 16 4 start(ota) | ota partition(store update firmware) + 20 4 end(ota) | + + 24 4 start(kv) | kv partition + 28 4 end(kv) | + + if you have a ping-pong update partition, partition table should be: + 0 2 magic | + 2 2 version | + 4 1 crc | partition table header + 5 3 reserved | + + 8 4 start(active application) | active application partition + 12 4 end(active application) | + + 8 4 start(backup application) | backup application partition + 12 4 end(backup application) | + + 16 4 start(ota) | ota partition(store update firmware) + 20 4 end(ota) | + + 24 4 start(kv) | kv partition + 28 4 end(kv) | + */ +typedef struct ota_partition_st { + uint32_t start; /* start address */ + uint32_t end; /* end address */ +} ota_pt_t; + +typedef enum ota_update_type_en { + OTA_UPDATE_IN_POSITION, + OTA_UPDATE_PING_PONG, +} ota_updt_type_t; + +typedef enum ota_partition_type_en { + OTA_PARTITION_ACTIVE_APP, + OTA_PARTITION_BACKUP_APP, + OTA_PARTITION_OTA, + OTA_PARTITION_KV, +} ota_pt_type_t; + +typedef struct ota_in_position_partitions_st { + ota_pt_t active_app; + ota_pt_t ota; + ota_pt_t kv; +} ota_ip_pts_t; + +typedef struct ota_ping_pong_partitions_st { + ota_pt_t active_app; + ota_pt_t backup_app; + ota_pt_t ota; + ota_pt_t kv; +} ota_pp_pts_t; + +typedef union ip_un { + ota_pt_t pts[3]; + ota_ip_pts_t ip_pts; +} ip_u; + +typedef union pp_un { + ota_pt_t pts[4]; + ota_pp_pts_t pp_pts; +} pp_u; + +typedef union ota_partitions_un { + ip_u ip; + pp_u pp; +} ota_pts_t; + +typedef struct ota_partition_control_st { + ota_updt_type_t updt_type; + ota_img_vs_t version; + ota_pts_t pts; +} ota_pt_ctrl_t; + +int ota_partition_load(ota_updt_type_t updt_type, uint32_t partition_addr); + +uint32_t ota_partition_start(ota_pt_type_t pt_type); + +uint32_t ota_partition_end(ota_pt_type_t pt_type); + +uint32_t ota_partition_size(ota_pt_type_t pt_type); + +int ota_partition_is_pingpong(void); + +ota_img_vs_t ota_partition_init_version_get(void); + +static uint8_t partitions_crc(uint8_t crc, ota_pt_t *pts, int n) +{ + return crc8(crc, (uint8_t *)pts, n * sizeof(ota_pt_t)); +} + +static uint8_t partition_hdr_crc(ota_pt_hdr_t *pt_hdr) +{ + uint8_t crc = 0; + + crc = crc8(crc, (uint8_t *)&pt_hdr->magic, sizeof(uint16_t)); + crc = crc8(crc, (uint8_t *)&pt_hdr->version, sizeof(ota_img_vs_t)); + return crc; +} + +#endif /* _OTA_PARTITION_H_ */ + diff --git a/components/ota/download/include/hal_tcp.h b/components/ota/download/include/hal_tcp.h new file mode 100644 index 00000000..f624a386 --- /dev/null +++ b/components/ota/download/include/hal_tcp.h @@ -0,0 +1,30 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _HAL_TCP_H_ +#define _HAL_TCP_H_ + +int hal_tcp_connect(const char *host, uint16_t port); + +int hal_tcp_disconnect(int fd); + +int hal_tcp_write(int fd, const unsigned char *buf, uint32_t len, uint32_t timeout_ms); + +int hal_tcp_read(uintptr_t fd, unsigned char *buf, uint32_t len, uint32_t timeout_ms); + +#endif /* _HAL_TCP_H_ */ + diff --git a/components/ota/download/include/ota_download.h b/components/ota/download/include/ota_download.h new file mode 100644 index 00000000..1b8351fd --- /dev/null +++ b/components/ota/download/include/ota_download.h @@ -0,0 +1,33 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_DOWNLOAD_H_ +#define _OTA_DOWNLOAD_H_ + +#include "tos_k.h" + +#include "crc8.h" +#include "ota_flash.h" +#include "ota_partition.h" +#include "ota_env.h" +#include "ota_image.h" +#include "ota_info.h" +#include "hal_tcp.h" +#include "ota_download_http.h" + +#endif /* _OTA_DOWNLOAD_H_ */ + diff --git a/components/ota/download/include/ota_download_http.h b/components/ota/download/include/ota_download_http.h new file mode 100644 index 00000000..bb52de08 --- /dev/null +++ b/components/ota/download/include/ota_download_http.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_DOWNLOAD_HTTP_H_ +#define _OTA_DOWNLOAD_HTTP_H_ + +#define HTTP_REQUEST_TEMPLATE \ +"GET /%s HTTP/1.1\r\nAccept:*/*\r\n\ +User-Agent: Mozilla/5.0\r\n\ +Cache-Control: no-cache\r\n\ +Connection: close\r\n\ +Host:%s:%d\r\n\r\n" + +#define HOST_MAX 32 +#define FILE_MAX 32 +#define PORT_MAX 5 +#define HTTP_REQUEST_MAX (sizeof(HTTP_REQUEST_TEMPLATE) + HOST_MAX + FILE_MAX + PORT_MAX) + +#define HTTP_RESPONSE_STATUS_CODE_OK 200 + +typedef enum http_parse_status_en { + HTTP_PARSE_STATUS_NONE, + HTTP_PARSE_STATUS_BLANK_LINE, + HTTP_PARSE_STATUS_HEADER, + HTTP_PARSE_STATUS_OVERFLOW, + HTTP_PARSE_STATUS_TIMEOUT, +} http_parse_status_t; + +__API__ int ota_download_http(const char *url); + +#endif /* _OTA_DOWNLOAD_HTTP_H_ */ + diff --git a/components/ota/download/protocol/http/ota_download_http.c b/components/ota/download/protocol/http/ota_download_http.c new file mode 100644 index 00000000..e8e1ef86 --- /dev/null +++ b/components/ota/download/protocol/http/ota_download_http.c @@ -0,0 +1,283 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos_kv.h" +#include "ota_download.h" + +__STATIC__ uint16_t ota_str2uint16(char *str) +{ + uint16_t r = 0; + + while (*str) { + r = r * 10 + *str++ - '0'; + } + + return r; +} + +__STATIC__ int ota_url_parse(char *url, char *host, uint16_t *port, char *file) +{ + /* http://39.108.190.129:8080/firmware.bin */ + char *p; + int len; + static char the_port[PORT_MAX + 1]; + + /* 1. skip http url prefix */ +#define HTTP_URL_PREFIX "http://" + if (strncmp(url, HTTP_URL_PREFIX, strlen(HTTP_URL_PREFIX)) != 0) { + return -1; + } + + url += strlen(HTTP_URL_PREFIX); + + /* 2. parse host */ + p = strstr(url, ":"); + if (!p || (len = p - url) > HOST_MAX) { /* ":" not found or host name too long */ + return -1; + } + + strncpy(host, url, len); + host[len] = '\0'; + + /* 3. parse port */ + url = p + 1; + p = strstr(url, "/"); + if (!p || (len = p - url) > PORT_MAX) { /* ":" not found or port too long */ + return -1; + } + + strncpy(the_port, url, len); + the_port[len] = '\0'; + *port = ota_str2uint16(the_port); + + /* 4. parse file */ + url = p + 1; + if (strlen(url) > FILE_MAX) { + return -1; + } + strcpy(file, url); + + return 0; +} + +__STATIC_INLINE__ void ota_http_request_construct(char *http_request, char *host, uint16_t port, char *file) +{ + snprintf(http_request, HTTP_REQUEST_MAX, HTTP_REQUEST_TEMPLATE, file, host, port); +} + +__STATIC__ http_parse_status_t ota_http_response_line_parse(int fd, char *line_buf, size_t buf_len) +{ + size_t curr_len = 0; + k_stopwatch_t stopwatch; + uint8_t data, last_data = 0; + + memset(line_buf, 0, buf_len); + + tos_stopwatch_create(&stopwatch); + tos_stopwatch_countdown_ms(&stopwatch, 8000); + while (K_TRUE) { + if (tos_stopwatch_is_expired(&stopwatch)) { + return HTTP_PARSE_STATUS_TIMEOUT; + } + + if (curr_len >= buf_len) { + return HTTP_PARSE_STATUS_OVERFLOW; + } + + if (hal_tcp_read(fd, &data, 1, 1000) <= 0) { + continue; + } + + if (data == '\n' && last_data == '\r') { + curr_len -= 1; + line_buf[curr_len] = '\0'; + + if (curr_len == 0) { + return HTTP_PARSE_STATUS_BLANK_LINE; + } + + return HTTP_PARSE_STATUS_HEADER; + } + + line_buf[curr_len++] = data; + last_data = data; + } +} + +__STATIC__ int ota_http_body_write2flash(int fd, int file_len, unsigned char *buf, size_t buf_len) +{ + uint8_t crc = 0, the_crc; + ota_img_vs_t new_version; + int remain_len = file_len, read_len; + uint32_t flash_addr = ota_partition_start(OTA_PARTITION_OTA); + + /* is the file too large? */ + if (file_len > ota_partition_size(OTA_PARTITION_OTA)) { + return -1; + } + + /* we need the buf_len to be flash write-align aligned */ + if (!ota_flash_size_is_aligned(buf_len)) { + return -1; + } + + /* 1. make flash ready */ + if (ota_flash_erase_blocks(flash_addr, file_len) < 0) { + return -1; + } + + /* 2. deal with image header */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + read_len = MIN(remain_len, buf_len); + if (hal_tcp_read(fd, buf, read_len, 2000) != read_len) { + return -1; + } + + if (read_len < sizeof(ota_img_hdr_t)) { + /* read_len at least larger than ota_img_hdr_t */ + return -1; + } + + if (ota_flash_write(flash_addr, buf, ota_flash_write_size_aligned_get(read_len)) < 0) { + return -1; + } + + /* get original image header */ + the_crc = ((ota_img_hdr_t *)buf)->patch_crc; + /* patch version */ + new_version = ((ota_img_hdr_t *)buf)->new_version; + + /* calculate image header crc */ + crc = ota_img_hdr_crc((ota_img_hdr_t *)buf); + /* calculate remain image body crc */ + crc = crc8(crc, buf + sizeof(ota_img_hdr_t), read_len - sizeof(ota_img_hdr_t)); + + flash_addr += read_len; + remain_len -= read_len; + + /* 3. read file content and write to flash */ + while (remain_len > 0) { + read_len = MIN(remain_len, buf_len); + if (hal_tcp_read(fd, buf, read_len, 2000) != read_len) { + return -1; + } + + if (ota_flash_write(flash_addr, buf, ota_flash_write_size_aligned_get(read_len)) < 0) { + return -1; + } + + crc = crc8(crc, buf, read_len); + + flash_addr += read_len; + remain_len -= read_len; + } + + /* 4. crc check */ + if (the_crc != crc) { + return -1; + } + + if (tos_kv_set("new_version", &new_version, sizeof(ota_img_vs_t)) != KV_ERR_NONE) { + return -1; + } + + return 0; +} + +__STATIC__ int ota_http_response_parse(int fd) +{ +#define HTTP_HEADER_MAX 128 +#define HEADER_FIELD_MAX 30 + static char line_buf[HTTP_HEADER_MAX]; + static char header_field[HEADER_FIELD_MAX]; + + http_parse_status_t status; + int header_value, file_len; + int is_response_status_ok = K_FALSE; + + do { + status = ota_http_response_line_parse(fd, line_buf, sizeof(line_buf)); + + if (strncmp("HTTP/", line_buf, strlen("HTTP/")) == 0) { + sscanf(line_buf, "%s %d", header_field, &header_value); + if (header_value != HTTP_RESPONSE_STATUS_CODE_OK) { + return -1; + } + + is_response_status_ok = K_TRUE; + } else if (strncmp("Content-Length:", line_buf, strlen("Content-Length:")) == 0) { + sscanf(line_buf, "%s %d", header_field, &header_value); + file_len = header_value; + } + } while (status == HTTP_PARSE_STATUS_HEADER); + + if (!is_response_status_ok) { + return -1; + } + + if (status == HTTP_PARSE_STATUS_OVERFLOW || + status == HTTP_PARSE_STATUS_TIMEOUT || + file_len <= 0) { + return -1; + } + + /* must be HTTP_PARSE_STATUS_BLANK_LINE, means the body begins */ + if (ota_http_body_write2flash(fd, file_len, (unsigned char *)line_buf, sizeof(line_buf)) < 0) { + return -1; + } + + return 0; +} + +__API__ int ota_download_http(const char *url) +{ + int fd, rc = 0; + uint16_t port; + static char host[HOST_MAX + 1], file[FILE_MAX + 1]; + static char http_request[HTTP_REQUEST_MAX]; + + if (!url) { + return -1; + } + + if (ota_url_parse((char *)url, host, &port, file) != 0) { + return -1; + } + + ota_http_request_construct(http_request, host, port, file); + + /* 1. connect to host */ + fd = hal_tcp_connect(host, port); + if (fd < 0) { + return -1; + } + + /* 2. send http request */ + if (hal_tcp_write(fd, (unsigned char *)http_request, strlen(http_request), 0) < 0) { + hal_tcp_disconnect(fd); + return -1; + } + + /* 3. parse http response */ + rc = ota_http_response_parse(fd); + + /* 4. free socket */ + hal_tcp_disconnect(fd); + + return rc; +} + diff --git a/components/ota/download/transport_layer/tcp/module/hal_tcp_module.c b/components/ota/download/transport_layer/tcp/module/hal_tcp_module.c new file mode 100644 index 00000000..4d6d92cb --- /dev/null +++ b/components/ota/download/transport_layer/tcp/module/hal_tcp_module.c @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "sal_module_wrapper.h" + +int hal_tcp_connect(const char *host, uint16_t port) +{ + int fd; +#define PORT_MAX 6 + char port_str[PORT_MAX] = { 0 }; + +#define IP_MAX 16 + char ip[16] = { 0 }; + + snprintf(port_str, PORT_MAX, "%u", port); + + if (tos_sal_module_parse_domain(host, ip, sizeof(ip)) != 0) { + return -1; + } + + fd = tos_sal_module_connect(host, port_str, TOS_SAL_PROTO_TCP); + if (fd >= 0) { + return fd; + } + + if (tos_sal_module_init() != 0) { + return -1; + } + + fd = tos_sal_module_connect(host, port_str, TOS_SAL_PROTO_TCP); + if (fd < 0) { + return -1; + } + + return fd; +} + +int hal_tcp_disconnect(int fd) +{ + (void)tos_sal_module_close(fd); + return 0; +} + +int hal_tcp_write(int fd, const unsigned char *buf, uint32_t len, uint32_t timeout_ms) +{ + return tos_sal_module_send(fd, buf, len); +} + +int hal_tcp_read(uintptr_t fd, unsigned char *buf, uint32_t len, uint32_t timeout_ms) +{ + return tos_sal_module_recv_timeout(fd, buf, len, timeout_ms); +} + diff --git a/components/ota/recovery/include/ota_patch.h b/components/ota/recovery/include/ota_patch.h new file mode 100644 index 00000000..69b652c2 --- /dev/null +++ b/components/ota/recovery/include/ota_patch.h @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_PATCH_H_ +#define _OTA_PATCH_H_ + +#include "stddef.h" +#include "stdint.h" + +#define ERROR() \ + rc = -1; \ + goto OUT; + +#define FREE(p) if (p) { free(p); } + +#define CMD_COPY 0 + +#define CMD_DIFF 1 + +#define CMD_EXTRA 2 + +#define BLK_UPPER_BOUND(off, blk_len) (ALIGN_UP((off) + 1, (blk_len))) + +#define BLK_LOWER_BOUND(idx, blk_len) ((idx) * (blk_len)) + +#define FOLD_N(x, n) ((n) * (x)) + +#define THE_BUF(buf, idx, blk_len) ((buf) + (idx) * (blk_len)) + +#define BLK_IDX(off, blk_len) ((off) / (blk_len)) + +#define ALIGN_UP(v, align) (((v) + ((align) - 1)) & ~((align) - 1)) + +#define BLK_CNT(size, blk_len) (((size) + (blk_len) - 1) / (blk_len)) + +#pragma pack(push, 1) +typedef struct patch_header_st { + uint16_t blk_len; + uint16_t blk_cnt; +} patch_hdr_t; + +typedef struct patch_for_block_header_st { + uint16_t unzipped_len; + uint16_t zipped_len; +} patch4blk_hdr_t; + +typedef struct patch_for_block_info_st { + uint16_t blk_idx; + uint16_t cmd_cnt; + uint16_t ctrl_size; + uint16_t diff_size; +} patch4blk_info_t; +#pragma pack(pop) + +typedef struct backup_map_st { + uint16_t *cache; + uint16_t backup_n; + uint16_t cursor; + uint16_t blk_len; + uint32_t start; +} bkup_map_t; + +typedef enum query_res_en { + QUERY_RESULT_OK, + QUERY_RESULT_NOT_EXIST, + QUERY_RESULT_FETCH_FAILED, +} query_res_t; + +int ota_patch(uint32_t patch, size_t patchsize, size_t ota_size); + +int ota_patch_xip(uint8_t *patch, size_t patchsize, size_t ota_size); + +#endif + diff --git a/components/ota/recovery/include/ota_recovery.h b/components/ota/recovery/include/ota_recovery.h new file mode 100644 index 00000000..eaba4788 --- /dev/null +++ b/components/ota/recovery/include/ota_recovery.h @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _OTA_RECOVERY_H_ +#define _OTA_RECOVERY_H_ + +#include "ota_env.h" +#include "ota_info.h" +#include "ota_flash.h" +#include "ota_image.h" +#include "ota_patch.h" + +int ota_recovery(void); + +int ota_recovery_xip(void); + +#endif /* _OTA_RECOVERY_H_ */ + diff --git a/components/ota/recovery/ota_patch.c b/components/ota/recovery/ota_patch.c new file mode 100644 index 00000000..ecdb4011 --- /dev/null +++ b/components/ota/recovery/ota_patch.c @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "ota_patch.h" +#include "ota_flash.h" +#include "ota_partition.h" +#include "lzma_uncompress.h" + +static uint16_t offtin_u16(uint8_t *buf) +{ + int32_t y; + + y = buf[1]; + y = y * 256; y += buf[0]; + + return y; +} + +static int backup_map_create(bkup_map_t *bkup_map, size_t ota_size, uint16_t blk_len) +{ + uint16_t i = 0; + uint16_t *cache; + uint16_t remain_blk_cnt; + uint32_t start; + size_t remain_size; + + if (ota_partition_size(OTA_PARTITION_OTA) <= ALIGN_UP(ota_size, blk_len)) { + return -1; + } + + remain_size = ota_partition_size(OTA_PARTITION_OTA) - ALIGN_UP(ota_size, blk_len); + remain_blk_cnt = BLK_CNT(remain_size, blk_len); + start = ota_partition_start(OTA_PARTITION_OTA) + ALIGN_UP(ota_size, blk_len); + + cache = malloc(remain_blk_cnt * sizeof(uint16_t)); + if (cache == NULL) { + return -1; + } + + for (i = 0; i < remain_blk_cnt; ++i) { + cache[i] = (uint16_t)-1; + } + + bkup_map->cache = cache; + bkup_map->backup_n = remain_blk_cnt; + bkup_map->blk_len = blk_len; + bkup_map->start = start; + bkup_map->cursor =0; + + return 0; +} + +static int backup_map_destroy(bkup_map_t *bkup_map) +{ + free(bkup_map->cache); + return 0; +} + +static int backup_map_add(bkup_map_t *bkup_map, uint16_t blk_idx, uint32_t backup_ed_addr, uint8_t *blk_buf) +{ + uint16_t slot = bkup_map->cursor; + uint16_t blk_len = bkup_map->blk_len; + uint32_t backup_ee_addr = THE_BUF(bkup_map->start, slot, bkup_map->blk_len); + + if (ota_flash_erase(backup_ee_addr, blk_len) != 0) { + return -1; + } + + if (ota_flash_read(backup_ed_addr, blk_buf, blk_len) != 0) { + return -1; + } + + if (ota_flash_write(backup_ee_addr, blk_buf, blk_len) != 0) { + return -1; + } + + bkup_map->cache[slot] = blk_idx; + bkup_map->cursor = (slot + 1) % bkup_map->backup_n; + + return 0; +} + +static query_res_t backup_map_query(bkup_map_t *bkup_map, uint16_t blk_idx, uint8_t *blk_buf) +{ + uint16_t i = 0; + uint32_t backup_ee_addr; + uint16_t blk_len = bkup_map->blk_len; + + for (i = 0; i < bkup_map->backup_n; ++i) { + if (bkup_map->cache[i] == blk_idx) { + backup_ee_addr = THE_BUF(bkup_map->start, i, blk_len); + + if (ota_flash_read(backup_ee_addr, blk_buf, blk_len) != 0) { + return QUERY_RESULT_FETCH_FAILED; + } + + return QUERY_RESULT_OK; + } + } + + return QUERY_RESULT_NOT_EXIST; +} + +int ota_patch(uint32_t patch, size_t patchsize, size_t ota_size) +{ + int rc = 0, i = 0; + + /* the patch information stuff */ + uint8_t *block = NULL, *blk_buf = NULL; + uint8_t *unzipped_patch = NULL, *zipped_patch = NULL; + uint16_t blk_len, blk_cnt; + uint16_t unzipped_len, zipped_len; + size_t the_unzipped_len, the_zipped_len; + + /* the backup stuff */ + bkup_map_t bkup_map; + query_res_t res; + + /* the patch4blk stuff */ + uint8_t X; + uint16_t I, N, Y, Z, C, D; + uint8_t *ctrl_blk, *diff_blk, *extra_blk; + uint16_t cursor = 0; + uint16_t old_idx, old_offset; + + patch_hdr_t patch_hdr; + patch4blk_hdr_t patch4blk_hdr; + patch4blk_info_t *patch4blk_info; + + /* + format of patch: + patch_hdr + (patch4blk_hdr + zipped(patch4blk)) * N + + patch_hdr: + 0 2 length of one block + 4 2 total count of blocks in the patch + + patch4blk_hdr: + 4 2 original length of the patch + 8 2 zipped length of the patch + */ + /* read the patch header */ + if (ota_flash_read(patch, &patch_hdr, sizeof(patch_hdr_t)) != 0) { + ERROR(); + } + patch += sizeof(patch_hdr_t); + patchsize -= sizeof(patch_hdr_t); + if (patchsize <= 0) { + ERROR(); + } + + blk_len = patch_hdr.blk_len; + blk_cnt = patch_hdr.blk_cnt; + + /* create backup map to cache old blocks */ + if (!ota_partition_is_pingpong() && + backup_map_create(&bkup_map, ota_size, blk_len) != 0) { + ERROR(); + } + + block = malloc(blk_len); + if (!block) { + ERROR(); + } + + blk_buf = malloc(blk_len); + if (!blk_buf) { + ERROR(); + } + + while (blk_cnt--) { + /* read the patch4blk header */ + if (ota_flash_read(patch, &patch4blk_hdr, sizeof(patch4blk_hdr_t)) != 0) { + ERROR(); + } + patch += sizeof(patch4blk_hdr_t); + patchsize -= sizeof(patch4blk_hdr_t); + if (patchsize <= 0) { + ERROR(); + } + + unzipped_len = patch4blk_hdr.unzipped_len; + zipped_len = patch4blk_hdr.zipped_len; + the_unzipped_len = unzipped_len; + the_zipped_len = zipped_len; + + /* some malloc */ + zipped_patch = malloc(the_zipped_len); + if (!zipped_patch) { + ERROR(); + } + + unzipped_patch = malloc(the_unzipped_len); + if (!unzipped_patch) { + ERROR(); + } + + /* read the zipped patch4blk */ + if (ota_flash_read(patch, zipped_patch, the_zipped_len) != 0) { + ERROR(); + } + patch += the_zipped_len; + patchsize -= the_zipped_len; + if (patchsize <= 0) { + ERROR(); + } + + /* do unzip */ + if (lzma_uncompress(unzipped_patch, &the_unzipped_len, zipped_patch, &the_zipped_len) != LZMA_ERR_OK) { + ERROR(); + } + + free(zipped_patch); + + /* + format of patch for one block: + 0 2 I block index of the patch + 2 2 N count of cmd + 4 2 C sizeof(control block) + 6 2 D sizeof(diff block) + + 6 C control block + 6 + C D diff block + 6 + C + D ? extra block + */ + /* control block: + with a leading 8bit domain, indicating the cmd type, 0 for DIFF, 1 for EXTRA + + if current is a CMD_COPY(X, Y, Z) cmd: + X is 0(COPY) + locate old to Z, copy Y bytes from oldfile + + if current is a CMD_DIFF(X, Y, Z) cmd: + X is 1(DIFF) + locate old to Z, add Y bytes from oldfile to Y bytes from the diff block + + if current is a CMD_EXTRA(X, Y) cmd: + X is 2(EXTRA) + copy Y bytes from the extra block + */ + /* here the show begins */ + + /* read the patch4info */ + patch4blk_info = (patch4blk_info_t *)unzipped_patch; + + I = patch4blk_info->blk_idx; + N = patch4blk_info->cmd_cnt; + C = patch4blk_info->ctrl_size; + D = patch4blk_info->diff_size; + + ctrl_blk = unzipped_patch + sizeof(patch4blk_info_t); + diff_blk = unzipped_patch + sizeof(patch4blk_info_t) + C; + extra_blk = unzipped_patch + sizeof(patch4blk_info_t) + C + D; + + cursor = 0; + memset(block, 0, blk_len); + + /* backup the old block I first */ + if (!ota_partition_is_pingpong() && + backup_map_add(&bkup_map, I, + THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len), + blk_buf) != 0) { + ERROR(); + } + + while (N--) { + X = *(uint8_t *)ctrl_blk; + ctrl_blk += 1; + + if (X == CMD_COPY || X == CMD_DIFF) { // a COPY or DIFF cmd + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + Z = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + old_idx = BLK_IDX(Z, blk_len); + old_offset = Z - BLK_LOWER_BOUND(old_idx, blk_len); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR(); + } + + if (ota_partition_is_pingpong()) { + // if pingpong, copy from OTA_PARTITION_BACKUP_APP + if (ota_flash_read(THE_BUF(ota_partition_start(OTA_PARTITION_BACKUP_APP), old_idx, blk_len), + blk_buf, blk_len) != 0) { + ERROR(); + } + } else { + res = backup_map_query(&bkup_map, old_idx, blk_buf); + if (res == QUERY_RESULT_FETCH_FAILED) { + ERROR(); + } + + if (res == QUERY_RESULT_NOT_EXIST) { + if (ota_flash_read(THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), old_idx, blk_len), + blk_buf, blk_len) != 0) { + ERROR(); + } + } + } + + memcpy(block + cursor, blk_buf + old_offset, Y); + + if (X == CMD_DIFF) { + for (i = 0; i < Y; ++i) { + (block + cursor)[i] += *(int8_t *)(diff_blk + i); + } + diff_blk += Y; + } + } else if (X == CMD_EXTRA) { + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR(); + } + + memcpy(block + cursor, extra_blk, Y); + extra_blk += Y; + } else { + ERROR(); + } + + cursor += Y; + /* sanity check */ + if (cursor > blk_len) { + ERROR(); + } + } + + free(unzipped_patch); + + if (ota_flash_erase(THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len), blk_len) != 0) { + ERROR(); + } + + if (ota_flash_write(THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len), block, blk_len) != 0) { + ERROR(); + } + } + +OUT: + FREE(block); + FREE(blk_buf); + + if (!ota_partition_is_pingpong()) { + backup_map_destroy(&bkup_map); + } + + return rc; +} + diff --git a/components/ota/recovery/ota_patch_xip.c b/components/ota/recovery/ota_patch_xip.c new file mode 100644 index 00000000..b68030cd --- /dev/null +++ b/components/ota/recovery/ota_patch_xip.c @@ -0,0 +1,334 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "ota_patch.h" +#include "ota_flash.h" +#include "ota_partition.h" +#include "lzma_uncompress.h" + +static uint16_t offtin_u16(uint8_t *buf) +{ + int32_t y; + + y = buf[1]; + y = y * 256; y += buf[0]; + + return y; +} + +static int backup_map_create(bkup_map_t *bkup_map, size_t ota_size, uint16_t blk_len) +{ + uint16_t i = 0; + uint16_t *cache; + uint16_t remain_blk_cnt; + uint32_t start; + size_t remain_size; + + if (ota_partition_size(OTA_PARTITION_OTA) <= ALIGN_UP(ota_size, blk_len)) { + return -1; + } + + remain_size = ota_partition_size(OTA_PARTITION_OTA) - ALIGN_UP(ota_size, blk_len); + remain_blk_cnt = BLK_CNT(remain_size, blk_len); + start = ota_partition_start(OTA_PARTITION_OTA) + ALIGN_UP(ota_size, blk_len); + + cache = malloc(remain_blk_cnt * sizeof(uint16_t)); + if (cache == NULL) { + return -1; + } + + for (i = 0; i < remain_blk_cnt; ++i) { + cache[i] = (uint16_t)-1; + } + + bkup_map->cache = cache; + bkup_map->backup_n = remain_blk_cnt; + bkup_map->blk_len = blk_len; + bkup_map->start = start; + bkup_map->cursor =0; + + return 0; +} + +static int backup_map_destroy(bkup_map_t *bkup_map) +{ + free(bkup_map->cache); + return 0; +} + +static int backup_map_add(bkup_map_t *bkup_map, uint16_t blk_idx, uint32_t backup_ed_addr) +{ + uint16_t slot = bkup_map->cursor; + uint16_t blk_len = bkup_map->blk_len; + uint32_t backup_ee_addr = THE_BUF(bkup_map->start, slot, bkup_map->blk_len); + + if (ota_flash_erase(backup_ee_addr, blk_len) != 0) { + return -1; + } + + if (ota_flash_write(backup_ee_addr, (uint8_t *)backup_ed_addr, blk_len) != 0) { + return -1; + } + + bkup_map->cache[slot] = blk_idx; + bkup_map->cursor = (slot + 1) % bkup_map->backup_n; + + return 0; +} + +static query_res_t backup_map_query(bkup_map_t *bkup_map, uint16_t blk_idx, uint32_t *backup_ee_addr) +{ + uint16_t i = 0; + uint16_t blk_len = bkup_map->blk_len; + + for (i = 0; i < bkup_map->backup_n; ++i) { + if (bkup_map->cache[i] == blk_idx) { + *backup_ee_addr = THE_BUF(bkup_map->start, i, blk_len); + + return QUERY_RESULT_OK; + } + } + + return QUERY_RESULT_NOT_EXIST; +} + +int ota_patch_xip(uint8_t *patch, size_t patchsize, size_t ota_size) +{ + int rc = 0, i = 0; + + /* the patch information stuff */ + uint8_t *block = NULL; + uint8_t *unzipped_patch = NULL, *zipped_patch = NULL; + uint16_t blk_len, blk_cnt; + uint16_t unzipped_len, zipped_len; + size_t the_unzipped_len, the_zipped_len; + + /* the backup stuff */ + bkup_map_t bkup_map; + query_res_t res; + uint32_t backup_ee_addr; + + /* the patch4blk stuff */ + uint8_t X; + uint16_t I, N, Y, Z, C, D; + uint8_t *ctrl_blk, *diff_blk, *extra_blk; + uint16_t cursor = 0; + uint16_t old_idx, old_offset; + + patch_hdr_t patch_hdr; + patch4blk_hdr_t patch4blk_hdr; + patch4blk_info_t *patch4blk_info; + + /* + format of patch: + patch_hdr + (patch4blk_hdr + zipped(patch4blk)) * N + + patch_hdr: + 0 2 length of one block + 4 2 total count of blocks in the patch + + patch4blk_hdr: + 4 2 original length of the patch + 8 2 zipped length of the patch + */ + /* read the patch header */ + memcpy(&patch_hdr, patch, sizeof(patch_hdr_t)); + patch += sizeof(patch_hdr_t); + patchsize -= sizeof(patch_hdr_t); + if (patchsize <= 0) { + ERROR(); + } + + blk_len = patch_hdr.blk_len; + blk_cnt = patch_hdr.blk_cnt; + + /* create backup map to cache old blocks */ + if (!ota_partition_is_pingpong() && + backup_map_create(&bkup_map, ota_size, blk_len) != 0) { + ERROR(); + } + + block = malloc(blk_len); + if (!block) { + ERROR(); + } + + while (blk_cnt--) { + /* read the patch4blk header */ + memcpy(&patch4blk_hdr, patch, sizeof(patch4blk_hdr_t)); + patch += sizeof(patch4blk_hdr_t); + patchsize -= sizeof(patch4blk_hdr_t); + if (patchsize <= 0) { + ERROR(); + } + + unzipped_len = patch4blk_hdr.unzipped_len; + zipped_len = patch4blk_hdr.zipped_len; + the_unzipped_len = unzipped_len; + the_zipped_len = zipped_len; + + /* some malloc */ + unzipped_patch = malloc(the_unzipped_len); + if (!unzipped_patch) { + ERROR(); + } + + /* read the zipped patch4blk */ + zipped_patch = patch; + patch += the_zipped_len; + patchsize -= the_zipped_len; + if (patchsize <= 0) { + ERROR(); + } + + /* do unzip */ + if (lzma_uncompress(unzipped_patch, &the_unzipped_len, zipped_patch, &the_zipped_len) != LZMA_ERR_OK) { + ERROR(); + } + + /* + format of patch for one block: + 0 2 I block index of the patch + 2 2 N count of cmd + 4 2 C sizeof(control block) + 6 2 D sizeof(diff block) + + 6 C control block + 6 + C D diff block + 6 + C + D ? extra block + */ + /* control block: + with a leading 8bit domain, indicating the cmd type, 0 for DIFF, 1 for EXTRA + + if current is a CMD_COPY(X, Y, Z) cmd: + X is 0(COPY) + locate old to Z, copy Y bytes from oldfile + + if current is a CMD_DIFF(X, Y, Z) cmd: + X is 1(DIFF) + locate old to Z, add Y bytes from oldfile to Y bytes from the diff block + + if current is a CMD_EXTRA(X, Y) cmd: + X is 2(EXTRA) + copy Y bytes from the extra block + */ + /* here the show begins */ + + /* read the patch4info */ + patch4blk_info = (patch4blk_info_t *)unzipped_patch; + + I = patch4blk_info->blk_idx; + N = patch4blk_info->cmd_cnt; + C = patch4blk_info->ctrl_size; + D = patch4blk_info->diff_size; + + ctrl_blk = unzipped_patch + sizeof(patch4blk_info_t); + diff_blk = unzipped_patch + sizeof(patch4blk_info_t) + C; + extra_blk = unzipped_patch + sizeof(patch4blk_info_t) + C + D; + + cursor = 0; + memset(block, 0, blk_len); + + /* backup the old block I first */ + if (!ota_partition_is_pingpong() && + backup_map_add(&bkup_map, I, + THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len)) != 0) { + ERROR(); + } + + while (N--) { + X = *(uint8_t *)ctrl_blk; + ctrl_blk += 1; + + if (X == CMD_COPY || X == CMD_DIFF) { // a COPY or DIFF cmd + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + Z = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + old_idx = BLK_IDX(Z, blk_len); + old_offset = Z - BLK_LOWER_BOUND(old_idx, blk_len); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR(); + } + + if (ota_partition_is_pingpong()) { + // if pingpong, copy from OTA_PARTITION_BACKUP_APP + memcpy(block + cursor, THE_BUF((uint8_t *)ota_partition_start(OTA_PARTITION_BACKUP_APP), old_idx, blk_len) + old_offset, Y); + } else { + res = backup_map_query(&bkup_map, old_idx, &backup_ee_addr); + + if (res == QUERY_RESULT_NOT_EXIST) { + // not in the backup, copy from old + memcpy(block + cursor, THE_BUF((uint8_t *)ota_partition_start(OTA_PARTITION_ACTIVE_APP), old_idx, blk_len) + old_offset, Y); + } else { // QUERY_RESULT_NOT_OK + memcpy(block + cursor, (uint8_t *)backup_ee_addr + old_offset, Y); + } + } + + if (X == CMD_DIFF) { + for (i = 0; i < Y; ++i) { + (block + cursor)[i] += *(int8_t *)(diff_blk + i); + } + diff_blk += Y; + } + } else if (X == CMD_EXTRA) { + Y = offtin_u16(ctrl_blk); + ctrl_blk += sizeof(uint16_t); + + /* sanity check */ + if (BLK_IDX(cursor + Y - 1, blk_len) != BLK_IDX(cursor, blk_len)) { + ERROR(); + } + + memcpy(block + cursor, extra_blk, Y); + extra_blk += Y; + } else { + ERROR(); + } + + cursor += Y; + /* sanity check */ + if (cursor > blk_len) { + ERROR(); + } + } + + free(unzipped_patch); + + if (ota_flash_erase(THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len), blk_len) != 0) { + ERROR(); + } + + if (ota_flash_write(THE_BUF(ota_partition_start(OTA_PARTITION_ACTIVE_APP), I, blk_len), block, blk_len) != 0) { + ERROR(); + } + } + +OUT: + FREE(block); + + if (!ota_partition_is_pingpong()) { + backup_map_destroy(&bkup_map); + } + + return rc; +} + diff --git a/components/ota/recovery/ota_recovery.c b/components/ota/recovery/ota_recovery.c new file mode 100644 index 00000000..d74bf7c7 --- /dev/null +++ b/components/ota/recovery/ota_recovery.c @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos_k.h" +#include "tos_kv.h" + +#include "crc8.h" +#include "ota_flash.h" +#include "ota_partition.h" +#include "ota_image.h" +#include "ota_info.h" +#include "ota_env.h" +#include "lzma_uncompress.h" +#include "ota_recovery.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static int patch_verify(ota_img_hdr_t *img_hdr) +{ +#define BUF_SIZE 128 + static uint8_t buf[BUF_SIZE]; + uint8_t crc = 0; + ota_img_vs_t new_version; + ota_img_vs_t cur_version; + size_t version_len, remain_len, read_len; + uint32_t active_app_start = ota_partition_start(OTA_PARTITION_ACTIVE_APP); + uint32_t patch_start = ota_partition_start(OTA_PARTITION_OTA); + + /* drag the ota_img_hdr out of the flash */ + if (ota_flash_read(patch_start, img_hdr, sizeof(ota_img_hdr_t)) < 0) { + return -1; + } + + /* 1. check whether new version patch downloaded */ + if (tos_kv_get("new_version", &new_version, sizeof(ota_img_vs_t), &version_len) != KV_ERR_NONE) { + return -1; + } + + if (new_version.major != img_hdr->new_version.major || + new_version.minor != img_hdr->new_version.minor) { + return -1; + } + + /* 2. verify magic */ + if (img_hdr->magic != OTA_IMAGE_MAGIC) { + return -1; + } + + /* 3. is this patch for current version? */ + cur_version = ota_info_curr_version(); + if (cur_version.major != img_hdr->old_version.major || + cur_version.minor != img_hdr->old_version.minor) { + return -1; + } + + /* 4. verify the patch crc checksum */ + remain_len = img_hdr->patch_size; + crc = ota_img_hdr_crc(img_hdr); + patch_start += sizeof(ota_img_hdr_t); + + while (remain_len > 0) { + read_len = MIN(sizeof(buf), remain_len); + if (ota_flash_read(patch_start, buf, read_len) < 0) { + return -1; + } + + crc = crc8(crc, buf, read_len); + + remain_len -= read_len; + patch_start += read_len; + } + + if (crc != img_hdr->patch_crc) { + return -1; + } + + /* 5. verify the old crc checksum */ + remain_len = img_hdr->old_size; + crc = 0; + + while (remain_len > 0) { + read_len = MIN(sizeof(buf), remain_len); + if (ota_flash_read(active_app_start, buf, read_len) < 0) { + return -1; + } + + crc = crc8(crc, buf, read_len); + + remain_len -= read_len; + active_app_start += read_len; + } + + if (crc != img_hdr->old_crc) { + return -1; + } + + return 0; +} + +static int do_recovery(ota_img_hdr_t *hdr) +{ + uint32_t patch = ota_partition_start(OTA_PARTITION_OTA) + sizeof(ota_img_hdr_t); + + return ota_patch(patch, hdr->patch_size - sizeof(ota_img_hdr_t), hdr->patch_size); +} + +static int app_copy(uint32_t dst, uint32_t dst_size, uint32_t src, uint32_t src_size) +{ +#define BUF_SIZE 128 + static uint8_t buf[BUF_SIZE]; + + size_t read_len = 0; + size_t remain_len = src_size; + uint32_t r_addr = src, w_addr = dst; + + if (src_size != dst_size) { + return -1; + } + + /* make flash ready */ + if (ota_flash_erase_blocks(dst, dst_size) < 0) { + return -1; + } + + while (remain_len > 0) { + read_len = MIN(sizeof(buf), remain_len); + if (ota_flash_read(r_addr, buf, read_len) < 0) { + return -1; + } + + if (ota_flash_write(w_addr, (void *)buf, ota_flash_write_size_aligned_get(read_len)) < 0) { + return -1; + } + + w_addr += read_len; + r_addr += read_len; + remain_len -= read_len; + } + + return 0; +} + +int ota_recovery(void) +{ + ota_img_hdr_t img_hdr; + + if (patch_verify(&img_hdr)) { + return -1; + } + + /* backup */ + if (ota_partition_is_pingpong() && + app_copy(ota_partition_start(OTA_PARTITION_BACKUP_APP), + ota_partition_size(OTA_PARTITION_BACKUP_APP), + ota_partition_start(OTA_PARTITION_ACTIVE_APP), + ota_partition_size(OTA_PARTITION_ACTIVE_APP)) < 0) { + return -1; + } + + if (do_recovery(&img_hdr) != 0) { + printf("recovery failed\n"); + + /* restore */ + if (ota_partition_is_pingpong()) { + app_copy(ota_partition_start(OTA_PARTITION_ACTIVE_APP), + ota_partition_size(OTA_PARTITION_ACTIVE_APP), + ota_partition_start(OTA_PARTITION_BACKUP_APP), + ota_partition_size(OTA_PARTITION_BACKUP_APP)); + } + return -1; + } + + if (ota_info_update(img_hdr.new_version) != 0) { + return -1; + } + + return 0; +} + diff --git a/components/ota/recovery/ota_recovery_xip.c b/components/ota/recovery/ota_recovery_xip.c new file mode 100644 index 00000000..f57db4d2 --- /dev/null +++ b/components/ota/recovery/ota_recovery_xip.c @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos_k.h" +#include "tos_kv.h" + +#include "crc8.h" +#include "ota_flash.h" +#include "ota_partition.h" +#include "ota_image.h" +#include "ota_info.h" +#include "ota_env.h" +#include "lzma_uncompress.h" +#include "ota_recovery.h" + +static int patch_verify(ota_img_hdr_t *img_hdr) +{ + uint8_t crc = 0; + size_t version_len; + ota_img_vs_t new_version; + ota_img_vs_t cur_version; + + /* read the ota_img_hdr */ + memcpy(img_hdr, (void *)(ota_partition_start(OTA_PARTITION_OTA)), sizeof(ota_img_hdr_t)); + + /* 1. check whether new version patch downloaded */ + if (tos_kv_get("new_version", &new_version, sizeof(new_version), &version_len) != KV_ERR_NONE) { + return -1; + } + + if (new_version.major != img_hdr->new_version.major || + new_version.minor != img_hdr->new_version.minor) { + return -1; + } + + /* 2. verify magic */ + if (img_hdr->magic != OTA_IMAGE_MAGIC) { + return -1; + } + + /* 3. is this patch for current version? */ + cur_version = ota_info_curr_version(); + if (cur_version.major != img_hdr->old_version.major || + cur_version.minor != img_hdr->old_version.minor) { + return -1; + } + + /* 4. verify the patch crc checksum */ + crc = ota_img_hdr_crc(img_hdr); + crc = crc8(crc, (uint8_t *)(ota_partition_start(OTA_PARTITION_OTA) + sizeof(ota_img_hdr_t)), img_hdr->patch_size); + + if (crc != img_hdr->patch_crc) { + return -1; + } + + /* 5. verify the old crc checksum */ + crc = crc8(0, (uint8_t *)ota_partition_start(OTA_PARTITION_ACTIVE_APP), img_hdr->old_size); + if (crc != img_hdr->old_crc) { + return -1; + } + + return 0; +} + +static int do_recovery_xip(ota_img_hdr_t *hdr) +{ + uint8_t *patch = (uint8_t *)(ota_partition_start(OTA_PARTITION_OTA) + sizeof(ota_img_hdr_t)); + + return ota_patch_xip(patch, hdr->patch_size - sizeof(ota_img_hdr_t), hdr->patch_size); +} + +static int app_copy(uint32_t dst, uint32_t dst_size, uint32_t src, uint32_t src_size) +{ + size_t read_len = 0; + size_t remain_len = src_size; + uint32_t r_addr = src, w_addr = dst; + + if (src_size != dst_size) { + return -1; + } + + /* make flash ready */ + if (ota_flash_erase_blocks(dst, dst_size) < 0) { + return -1; + } + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + while (remain_len > 0) { + read_len = MIN(remain_len, 128); + if (ota_flash_write(w_addr, (void *)r_addr, ota_flash_write_size_aligned_get(read_len)) < 0) { + return -1; + } + + w_addr += read_len; + r_addr += read_len; + remain_len -= read_len; + } + + return 0; +} + +int ota_recovery_xip(void) +{ + ota_img_hdr_t img_hdr; + + if (patch_verify(&img_hdr)) { + return -1; + } + + /* backup */ + if (ota_partition_is_pingpong() && + app_copy(ota_partition_start(OTA_PARTITION_BACKUP_APP), + ota_partition_size(OTA_PARTITION_BACKUP_APP), + ota_partition_start(OTA_PARTITION_ACTIVE_APP), + ota_partition_size(OTA_PARTITION_ACTIVE_APP)) < 0) { + return -1; + } + + if (do_recovery_xip(&img_hdr) != 0) { + printf("recovery failed\n"); + + /* restore */ + if (ota_partition_is_pingpong()) { + app_copy(ota_partition_start(OTA_PARTITION_ACTIVE_APP), + ota_partition_size(OTA_PARTITION_ACTIVE_APP), + ota_partition_start(OTA_PARTITION_BACKUP_APP), + ota_partition_size(OTA_PARTITION_BACKUP_APP)); + } + return -1; + } + + if (ota_info_update(img_hdr.new_version) != 0) { + return -1; + } + + return 0; +} + diff --git a/components/ota/tools/diff/Makefile b/components/ota/tools/diff/Makefile new file mode 100644 index 00000000..fec6ac68 --- /dev/null +++ b/components/ota/tools/diff/Makefile @@ -0,0 +1,55 @@ +TARGET ?= diff + +CC := gcc +LD := ld + +OUT_ROOT := out +OBJ_DIR := obj +LIB_DIR := lib +TARGET_DIR := target +OUT_DIR := $(OUT_ROOT)/$(OBJ_DIR) $(OUT_ROOT)/$(LIB_DIR) $(OUT_ROOT)/$(TARGET_DIR) + +NOECHO := @ + +INCDIRS := \ + ../../common/image \ + ../../common/lzma/3rdparty \ + ../../common/lzma/wrapper \ + ../../common/crc \ + ../../common/diff + +SRCDIRS := \ + ../../common/image \ + ../../common/lzma/3rdparty \ + ../../common/lzma/wrapper \ + ../../common/crc \ + ../../common/diff \ + src + +INCLUDE := $(patsubst %, -I %, $(INCDIRS)) + +CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c)) + +CFILENDIR := $(notdir $(CFILES)) + +COBJS := $(patsubst %, $(OUT_ROOT)/$(OBJ_DIR)/%, $(CFILENDIR:.c=.o)) +OBJS := $(COBJS) + +VPATH := $(SRCDIRS) + +.PHONY: clean $(OUT_DIR) + +$(TARGET): $(OUT_DIR) $(OBJS) + @echo "LD $(TARGET)" + $(NOECHO)$(CC) -o $(OUT_ROOT)/$(TARGET_DIR)/$(TARGET) $(OBJS) + +$(OUT_DIR) : + @mkdir -p $@ + +$(COBJS) : $(OUT_ROOT)/$(OBJ_DIR)/%.o : %.c + @echo "CC $(notdir $<)" + $(NOECHO)$(CC) -Wall -c -O2 $(INCLUDE) -o $@ $< + +clean: + @rm -rf $(OUT_ROOT) + diff --git a/components/ota/tools/diff/src/main.c b/components/ota/tools/diff/src/main.c new file mode 100644 index 00000000..4a7dfbdf --- /dev/null +++ b/components/ota/tools/diff/src/main.c @@ -0,0 +1,308 @@ +#include "stdio.h" +#include "stdint.h" +#include "stdlib.h" +#include "stdarg.h" +#include "string.h" + +#include "unistd.h" + +#include +#include +#include + +#include "crc8.h" +#include "ota_diff.h" +#include "lzma_compress.h" +#include "ota_image.h" + +#define ERROR(msg) \ + printf("ERROR: line number[%d], function[%s] msg[%s]\n", __LINE__, __FUNCTION__, msg); \ + rc = -1; \ + goto OUT; + +typedef struct args_param_st { + int is_verbose; + int is_safe_ignored; +} args_param_t; + +typedef struct diff_param_st { + uint16_t block_len; + ota_img_vs_t new_version; + ota_img_vs_t old_version; +} diff_param_t; + +static void usage(void) +{ + fprintf(stderr, + "Usage: diff [-h] [-v] [-s] -b block_len -n new_version -o old_version old_image new_image patch_image\n" + " -h help\n" + " -v more information\n" + " -s ingnore the safe block\n" + " -b set block size\n" + " -n version of new_image. format: two number separated by dot, {version_major.version_minor}\n" + " -o version of old_image. format: two number separated by dot, {version_major.version_minor}\n" + ); + exit(-1); +} + +static void panic(const char *format, ...) +{ + va_list args; + static char buffer[128]; + + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + fprintf(stderr, buffer); + exit(-1); +} + +static int str2int(char *p) +{ + long int v; + v = strtoll(p, &p, 0); + switch (*p) { + case 0: + if (v < -(1 << 30)) { + v = -(1 << 30); + } + if (v > (1 << 30)) { + v = (1 << 30); + } + break; + case 'k': + case 'K': + if (v < -(1 << 20)) { + v = -(1 << 20); + } + if (v > (1 << 20)) { + v = (1 << 20); + } + v *= 1024; + break; + case 'm': + case 'M': + if (v < -(1 << 10)) { + v = -(1 << 10); + } + if (v > (1 << 10)) { + v = (1 << 10); + } + v *= 1024 * 1024; + break; + case 'g': + case 'G': + if (v < -1) { + v = -1; + } + if (v > 1) { + v = 1; + } + v *= 1024 * 1024 * 1024; + break; + } + return v; +} + +static void process_command_line(int argc, char **argv, diff_param_t *param, args_param_t *args_param) +{ + int c, v; + uint32_t version_major, version_minor; + + param->block_len = 0; + + while ((c = getopt(argc, argv, "vhb:n:o:")) != -1) { + switch (c) { + case 'h': + usage(); + break; + + case 'v': + args_param->is_verbose = 1; + break; + + case 's': + args_param->is_safe_ignored = 1; + break; + + case 'b': + v = str2int(optarg); + if (v < 64 || v > (1 << 20) || (v & (v - 1))) { + panic("invalid block_len %s\n", optarg); + } + param->block_len = v; + break; + + case 'n': + if (sscanf(optarg, "%u.%u", &version_major, &version_minor) < 2) { + panic("invalid new_version format %s\n", optarg); + } + + if (version_major > (uint8_t)-1 || version_minor > (uint8_t)-1) { + panic("invalid version number: %d %d\n", version_major, version_minor); + } + + param->new_version.major = version_major; + param->new_version.minor = version_minor; + break; + + case 'o': + if (sscanf(optarg, "%u.%u", &version_major, &version_minor) < 2) { + panic("invalid new_version format %s\n", optarg); + } + + if (version_major > (uint8_t)-1 || version_minor > (uint8_t)-1) { + panic("invalid version number: %d %d\n", version_major, version_minor); + } + + param->old_version.major = version_major; + param->old_version.minor = version_minor; + break; + + default: + usage(); + break; + } + } +} + +static uint8_t img_crc(uint8_t *img, size_t img_size, ota_img_hdr_t *img_hdr) +{ + uint8_t crc = 0; + + crc = crc8(crc, (uint8_t *)&img_hdr->magic, sizeof(uint16_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->new_version, sizeof(ota_img_vs_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->old_version, sizeof(ota_img_vs_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->new_crc, sizeof(uint8_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->new_size, sizeof(uint32_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->old_crc, sizeof(uint8_t)); + crc = crc8(crc, (uint8_t *)&img_hdr->old_size, sizeof(uint32_t)); + + crc = crc8(crc, (uint8_t *)&img_hdr->patch_size, sizeof(uint32_t)); + crc = crc8(crc, img, img_size); + + return crc; +} + +int make_patch(uint8_t *new, size_t new_size, + uint8_t *old, size_t old_size, + diff_param_t *diff_param, + args_param_t *args_param, + FILE *patch_file) +{ + int rc = 0; + ota_img_hdr_t img_hdr; + uint8_t *patch = NULL; + size_t patch_size; + + if (ota_diff(old, old_size, new, new_size, diff_param->block_len, args_param->is_safe_ignored, args_param->is_verbose, &patch, &patch_size) != 0) { + ERROR("ota_diff failed\n"); + } + + img_hdr.magic = OTA_IMAGE_MAGIC; + img_hdr.new_version = diff_param->new_version; + img_hdr.old_version = diff_param->old_version; + + img_hdr.new_size = new_size; + img_hdr.new_crc = crc8(0, new, new_size); + + img_hdr.old_size = old_size; + img_hdr.old_crc = crc8(0, old, old_size); + + img_hdr.patch_size = patch_size; + img_hdr.patch_crc = img_crc(patch, patch_size, &img_hdr); + + if (fwrite(&img_hdr, 1, sizeof(ota_img_hdr_t), patch_file) != sizeof(ota_img_hdr_t)) { + ERROR("write header failed\n"); + } + + if (fwrite(patch, 1, patch_size, patch_file) != patch_size) { + ERROR("write patch failed\n"); + } + +OUT: + if (patch) { + free(patch); + } + + return rc; +} + +int main(int argc, char *argv[]) +{ + FILE *fp = NULL; + size_t new_size, old_size; + uint8_t *new = NULL, *old = NULL; + char *new_path, *old_path, *patch_path; + args_param_t args_param = { 0 }; + diff_param_t diff_param = { 0 }; + + memset(&args_param, 0, sizeof(args_param_t)); + memset(&diff_param, 0, sizeof(diff_param_t)); + + process_command_line(argc, argv, &diff_param, &args_param); + + if (optind + 3 != argc) { + usage(); + } + + old_path = argv[optind]; + new_path = argv[optind + 1]; + patch_path = argv[optind + 2]; + + if (((fp = fopen(new_path, "rb")) == NULL) || + (fseek(fp, 0, SEEK_END) == -1) || + ((new_size = ftell(fp)) == -1) || + ((new = malloc(new_size + 1)) == NULL) || + (fseek(fp, 0, SEEK_SET) != 0) || + (fread(new, 1, new_size, fp) != new_size) || + (fclose(fp) == -1)) { + printf("failed to open: %s\n", new_path); + goto errout; + } + + if (((fp = fopen(old_path, "rb")) == NULL) || + (fseek(fp, 0, SEEK_END) == -1) || + ((old_size = ftell(fp)) == -1) || + ((old = malloc(old_size + 1)) == NULL) || + (fseek(fp, 0, SEEK_SET) != 0) || + (fread(old, 1, old_size, fp) != old_size) || + (fclose(fp) == -1)) { + printf("failed to open: %s\n", old_path); + goto errout; + } + + /* Create the patch file */ + if ((fp = fopen(patch_path, "wb")) == NULL) { + printf("failed to open: %s\n", patch_path); + goto errout; + } + + if (make_patch(new, new_size, + old, old_size, + &diff_param, + &args_param, + fp) != 0) { + printf("make patch failed\n"); + goto errout; + } + +errout: + if (fp) { + fclose(fp); + } + + if (new) { + free(new); + } + + if (old) { + free(old); + } + + return 0; +} + diff --git a/components/ota/tools/partition_table/Makefile b/components/ota/tools/partition_table/Makefile new file mode 100644 index 00000000..12600943 --- /dev/null +++ b/components/ota/tools/partition_table/Makefile @@ -0,0 +1,50 @@ +TARGET ?= ptbl + +CC := gcc +LD := ld + +OUT_ROOT := out +OBJ_DIR := obj +LIB_DIR := lib +TARGET_DIR := target +OUT_DIR := $(OUT_ROOT)/$(OBJ_DIR) $(OUT_ROOT)/$(LIB_DIR) $(OUT_ROOT)/$(TARGET_DIR) + +NOECHO := @ + +INCDIRS := \ + ../../common/image \ + ../../common/crc \ + ../../common/partition + +SRCDIRS := \ + ../../common/image \ + ../../common/crc \ + src + +INCLUDE := $(patsubst %, -I %, $(INCDIRS)) + +CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c)) + +CFILENDIR := $(notdir $(CFILES)) + +COBJS := $(patsubst %, $(OUT_ROOT)/$(OBJ_DIR)/%, $(CFILENDIR:.c=.o)) +OBJS := $(COBJS) + +VPATH := $(SRCDIRS) + +.PHONY: clean $(OUT_DIR) + +$(TARGET): $(OUT_DIR) $(OBJS) + @echo "LD $(TARGET)" + $(NOECHO)$(CC) -o $(OUT_ROOT)/$(TARGET_DIR)/$(TARGET) $(OBJS) + +$(OUT_DIR) : + @mkdir -p $@ + +$(COBJS) : $(OUT_ROOT)/$(OBJ_DIR)/%.o : %.c + @echo "CC $(notdir $<)" + $(NOECHO)$(CC) -Wall -c -O2 $(INCLUDE) -o $@ $< + +clean: + @rm -rf $(OUT_ROOT) + diff --git a/components/ota/tools/partition_table/src/main.c b/components/ota/tools/partition_table/src/main.c new file mode 100644 index 00000000..89936012 --- /dev/null +++ b/components/ota/tools/partition_table/src/main.c @@ -0,0 +1,254 @@ +#include "stdio.h" +#include "stdint.h" +#include "stdlib.h" +#include "stdarg.h" +#include "string.h" + +#include "unistd.h" + +#include +#include +#include + +#include "crc8.h" +#include "ota_partition.h" + +typedef struct partition_param_st { + ota_updt_type_t updt_type; + + ota_img_vs_t version; + ota_pts_t pts; +} partition_param_t; + +static int partitions_verify(ota_pt_t *pts, int n) +{ + int i = 0; + + for (i = 0; i < n; ++i) { + if (pts[i].start == 0 || pts[i].start == (uint32_t)-1 || + pts[i].end == 0 || pts[i].end == (uint32_t)-1) { + return -1; + } + + if (pts[i].start >= pts[i].end) { + return -1; + } + } + + return 0; +} + +static void usage(void) +{ + fprintf(stderr, + "Usage: ptbl [-h] -p option -a active_app_pt [-b backup_app_pt] -o ota_pt -k kv_pt -v version pt_tbl_image\n" + " -h help\n" + " -p option[ip or pp]\n" + " if option is ip, using in-position update stragety\n" + " in this situation, MUST no backup_app_pt is supplied\n" + " if option is pp, using ping-pong update stragety\n" + " in this situation, MUST ONE backup_app_pt is supplied\n" + " -a active application partition, format: pt_start,pt_end\n" + " -b backup application partition, format: pt_start,pt_end\n" + " -o ota partition, format: pt_start,pt_end\n" + " -k kv partition, format pt_start,pt_end\n" + " -v version of the initial application, format: two number separated by dot\n" + ); + exit(-1); +} + +static void panic(const char *format, ...) +{ + va_list args; + static char buffer[128]; + + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + fprintf(stderr, buffer); + exit(-1); +} + +static void process_command_line(int argc, char **argv, partition_param_t *param) +{ + int c; + uint32_t start, end; + uint32_t version_major, version_minor; + + while ((c = getopt(argc, argv, "hp:a:b:o:k:v:")) != -1) { + switch (c) { + case 'h': + usage(); + break; + + case 'p': + if (strncmp("ip", optarg, 2) == 0) { + param->updt_type = OTA_UPDATE_IN_POSITION; + } else if (strncmp("pp", optarg, 2) == 0) { + param->updt_type = OTA_UPDATE_PING_PONG; + } else { + usage(); + } + break; + + case 'a': + if (sscanf(optarg, "%x,%x", &start, &end) < 2) { + panic("invalid partition %s\n", optarg); + } + + if (param->updt_type == OTA_UPDATE_IN_POSITION) { + param->pts.ip.ip_pts.active_app.start = start; + param->pts.ip.ip_pts.active_app.end = end; + } else if (param->updt_type == OTA_UPDATE_PING_PONG) { + param->pts.pp.pp_pts.active_app.start = start; + param->pts.pp.pp_pts.active_app.end = end; + } else { + usage(); + } + + break; + + case 'b': + if (sscanf(optarg, "%x,%x", &start, &end) < 2) { + panic("invalid partition %s\n", optarg); + } + + if (param->updt_type == OTA_UPDATE_PING_PONG) { + param->pts.pp.pp_pts.backup_app.start = start; + param->pts.pp.pp_pts.backup_app.end = end; + } else { + usage(); + } + + break; + + case 'o': + if (sscanf(optarg, "%x,%x", &start, &end) < 2) { + panic("invalid partition %s\n", optarg); + } + + if (param->updt_type == OTA_UPDATE_IN_POSITION) { + param->pts.ip.ip_pts.ota.start = start; + param->pts.ip.ip_pts.ota.end = end; + } else if (param->updt_type == OTA_UPDATE_PING_PONG) { + param->pts.pp.pp_pts.ota.start = start; + param->pts.pp.pp_pts.ota.end = end; + } else { + usage(); + } + + break; + + case 'k': + if (sscanf(optarg, "%x,%x", &start, &end) < 2) { + panic("invalid partition %s\n", optarg); + } + + if (param->updt_type == OTA_UPDATE_IN_POSITION) { + param->pts.ip.ip_pts.kv.start = start; + param->pts.ip.ip_pts.kv.end = end; + } else if (param->updt_type == OTA_UPDATE_PING_PONG) { + param->pts.pp.pp_pts.kv.start = start; + param->pts.pp.pp_pts.kv.end = end; + } else { + usage(); + } + + break; + + case 'v': + if (sscanf(optarg, "%u.%u", &version_major, &version_minor) < 2) { + panic("invalid version format %s\n", optarg); + } + + if (version_major > (uint8_t)-1 || version_minor > (uint8_t)-1) { + panic("invalid version number: %d %d\n", version_major, version_minor); + } + + param->version.major = version_major; + param->version.minor = version_minor; + break; + + default: + usage(); + break; + } + } +} + +void write_partition(partition_param_t *param, FILE *fp) +{ + uint8_t crc = 0; + ota_pt_hdr_t hdr; + + hdr.magic = OTA_PARTITION_MAGIC; + hdr.version = param->version; + + crc = partition_hdr_crc(&hdr); + + if (param->updt_type == OTA_UPDATE_IN_POSITION) { + if (partitions_verify(¶m->pts.ip.pts[0], sizeof(param->pts.ip.pts) / sizeof(ota_pt_t)) != 0) { + panic("invalid partitions\n"); + } + + crc = partitions_crc(crc, ¶m->pts.ip.pts[0], sizeof(param->pts.ip.pts) / sizeof(ota_pt_t)); + } else if (param->updt_type == OTA_UPDATE_PING_PONG) { + if (partitions_verify(¶m->pts.pp.pts[0], sizeof(param->pts.pp.pts) / sizeof(ota_pt_t)) != 0) { + panic("invalid partitions\n"); + } + + crc = partitions_crc(crc, ¶m->pts.pp.pts[0], sizeof(param->pts.pp.pts) / sizeof(ota_pt_t)); + } else { + panic("invalid partitions\n"); + } + + hdr.crc = crc; + + if (fwrite(&hdr, 1, sizeof(ota_pt_hdr_t), fp) != sizeof(ota_pt_hdr_t)) { + fclose(fp); + panic("failed to write partition header\n"); + } + + if (param->updt_type == OTA_UPDATE_IN_POSITION) { + if (fwrite(¶m->pts.ip.pts[0], 1, sizeof(param->pts.ip.pts), fp) != sizeof(param->pts.ip.pts)) { + fclose(fp); + panic("failed to write partitions\n"); + } + } else if (param->updt_type == OTA_UPDATE_PING_PONG) { + if (fwrite(¶m->pts.pp.pts[0], 1, sizeof(param->pts.pp.pts), fp) != sizeof(param->pts.pp.pts)) { + fclose(fp); + panic("failed to write partitions\n"); + } + } else { + panic("invalid partitions\n"); + } +} + +int main(int argc, char *argv[]) +{ + FILE *fp = NULL; + char *pt_tbl_path = NULL; + partition_param_t param = { 0 }; + + memset(¶m, 0, sizeof(partition_param_t)); + + process_command_line(argc, argv, ¶m); + + if (optind + 1 != argc) { + usage(); + } + + pt_tbl_path = argv[optind]; + + if ((fp = fopen(pt_tbl_path, "wb")) == NULL) { + panic("failed to open: %s\n", pt_tbl_path); + } + + write_partition(¶m, fp); + + fclose(fp); + + return 0; +} + diff --git a/components/security/mbedtls/wrapper/include/qcloud/dtls_psk_config.h b/components/security/mbedtls/wrapper/include/qcloud/dtls_psk_config.h index 44313977..684eacc5 100644 --- a/components/security/mbedtls/wrapper/include/qcloud/dtls_psk_config.h +++ b/components/security/mbedtls/wrapper/include/qcloud/dtls_psk_config.h @@ -28,6 +28,8 @@ #ifndef MBEDTLS_CONFIG_H #define MBEDTLS_CONFIG_H +#include "tos_k.h" + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) #define _CRT_SECURE_NO_DEPRECATE 1 #endif diff --git a/components/security/mbedtls/wrapper/include/qcloud/tls_psk_config.h b/components/security/mbedtls/wrapper/include/qcloud/tls_psk_config.h index 4807e8b9..79694f62 100644 --- a/components/security/mbedtls/wrapper/include/qcloud/tls_psk_config.h +++ b/components/security/mbedtls/wrapper/include/qcloud/tls_psk_config.h @@ -28,6 +28,8 @@ #ifndef MBEDTLS_CONFIG_H #define MBEDTLS_CONFIG_H +#include "tos_k.h" + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) #define _CRT_SECURE_NO_DEPRECATE 1 #endif diff --git a/examples/ota_download_through_http/ota_download_through_http_sample.c b/examples/ota_download_through_http/ota_download_through_http_sample.c new file mode 100644 index 00000000..094b24b3 --- /dev/null +++ b/examples/ota_download_through_http/ota_download_through_http_sample.c @@ -0,0 +1,65 @@ +#include "esp8266.h" +#include "mcu_init.h" +#include "sal_module_wrapper.h" +#include "cmsis_os.h" + +#include "tos_ota_download.h" + +extern ota_flash_drv_t stm32l4_norflash_onchip_drv_ota; +extern ota_flash_prop_t stm32l4_norflash_onchip_prop_ota; + +k_sem_t sem; + +#define TASK1_STK_SIZE 512 +void user_task(void *arg); +osThreadDef(user_task, osPriorityNormal, 1, TASK1_STK_SIZE); + +#define TASK2_STK_SIZE 1024 +void ota_download_task(void *arg); +osThreadDef(ota_download_task, osPriorityNormal, 1, TASK2_STK_SIZE); + +void user_task(void *arg) +{ + int iter = 0; + + while (K_TRUE) { + tos_task_delay(1000); + + printf("do sth(v1.1)...\n"); + + if (++iter == 2) { + printf("trigger ota download\n"); + tos_sem_post(&sem); + } + } +} + +void ota_download_task(void *arg) +{ + tos_sem_pend(&sem, TOS_TIME_FOREVER); + + esp8266_sal_init(HAL_UART_PORT_0); + esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0"); + + uint32_t partition_addr = 0x08024800; + + if (tos_ota_env_init(OTA_UPDATE_IN_POSITION, partition_addr, &stm32l4_norflash_onchip_drv_ota, &stm32l4_norflash_onchip_prop_ota) < 0) { + printf("env init failed!\n"); + return; + } + + if (!tos_ota_download_http("http://39.108.190.129:8000/patch.bin")) { + printf("download successfully!\n"); + } else { + printf("download failed!\n"); + } +} + +void application_entry(void *arg) +{ + tos_sem_create(&sem, 0); + + osThreadCreate(osThread(user_task), NULL); // Create task1 + osThreadCreate(osThread(ota_download_task), NULL); // Create task2 +} + diff --git a/examples/tencent_cloud_sdk_mqtt/tencent_cloud_sdk_mqtt.c b/examples/ota_download_through_qcloud_iot_explorer/entry.c similarity index 65% rename from examples/tencent_cloud_sdk_mqtt/tencent_cloud_sdk_mqtt.c rename to examples/ota_download_through_qcloud_iot_explorer/entry.c index 0b2da9ce..fc069d7f 100644 --- a/examples/tencent_cloud_sdk_mqtt/tencent_cloud_sdk_mqtt.c +++ b/examples/ota_download_through_qcloud_iot_explorer/entry.c @@ -17,16 +17,19 @@ #include "esp8266.h" #endif +#include "ota_download.h" + +extern ota_flash_drv_t stm32l4_norflash_onchip_drv_ota; +extern ota_flash_prop_t stm32l4_norflash_onchip_prop_ota; + void application_entry(void *arg) { - extern void mqtt_basic_thread(void); - #ifdef USE_LWIP dns_init(); MX_LWIP_Init(); #endif -#ifdef USE_ESP8266 +#ifdef USE_ESP8266x extern int esp8266_sal_init(hal_uart_port_t uart_port); extern int esp8266_join_ap(const char *ssid, const char *pwd); esp8266_sal_init(HAL_UART_PORT_0); @@ -38,10 +41,17 @@ void application_entry(void *arg) bc35_28_95_sal_init(HAL_UART_PORT_0); #endif - mqtt_basic_thread(); + uint32_t partition_addr = 0x08024800; + + if (ota_env_init(OTA_UPDATE_IN_POSITION, partition_addr, &stm32l4_norflash_onchip_drv_ota, &stm32l4_norflash_onchip_prop_ota) < 0) { + printf("ota env init failed!\n"); + return; + } + + ota_download_through_explorer(); while (1) { - printf("This is a mqtt demo!\r\n"); + printf("This is a qcloud explorer sdk ota demo!\r\n"); tos_task_delay(1000); } } diff --git a/examples/ota_download_through_qcloud_iot_explorer/ota_download_through_qcloud_iot_explorer_sample.c b/examples/ota_download_through_qcloud_iot_explorer/ota_download_through_qcloud_iot_explorer_sample.c new file mode 100644 index 00000000..2a85a900 --- /dev/null +++ b/examples/ota_download_through_qcloud_iot_explorer/ota_download_through_qcloud_iot_explorer_sample.c @@ -0,0 +1,503 @@ +/* + * Tencent is pleased to support the open source community by making IoT Hub available. + * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. + + * Licensed under the MIT License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include "qcloud_iot_export.h" +#include "qcloud_iot_import.h" +#include "lite-utils.h" + +#include "tos_kv.h" +#include "ota_download.h" + +#ifdef AUTH_MODE_CERT +static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file +static char sg_key_file[PATH_MAX + 1]; // full path of device key file +#endif + +static DeviceInfo sg_devInfo; + +static int sg_pub_ack = K_FALSE; +static int sg_packet_id = 0; + +static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg) +{ + uintptr_t packet_id = (uintptr_t)msg->msg; + + switch (msg->event_type) { + case MQTT_EVENT_UNDEF: + Log_i("undefined event occur."); + break; + + case MQTT_EVENT_DISCONNECT: + Log_i("MQTT disconnect."); + break; + + case MQTT_EVENT_RECONNECT: + Log_i("MQTT reconnect."); + break; + + case MQTT_EVENT_SUBCRIBE_SUCCESS: + Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id); + break; + + case MQTT_EVENT_SUBCRIBE_TIMEOUT: + Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id); + break; + + case MQTT_EVENT_SUBCRIBE_NACK: + Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id); + break; + + case MQTT_EVENT_PUBLISH_SUCCESS: + Log_i("publish success, packet-id=%u", (unsigned int)packet_id); + if (sg_packet_id == packet_id) + sg_pub_ack = K_TRUE; + break; + + case MQTT_EVENT_PUBLISH_TIMEOUT: + Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id); + break; + + case MQTT_EVENT_PUBLISH_NACK: + Log_i("publish nack, packet-id=%u", (unsigned int)packet_id); + break; + default: + Log_i("Should NOT arrive here."); + break; + } +} + +/* demo of firmware info management in device side for resuming download from break point */ +#define KEY_CURR_VERSION "c_vs" +#define KEY_MD5 "md5" +#define KEY_DOWNLOADED_SIZE "dl_sz" +#define KEY_PREV_VERSION "r_vs" + +static void local_firmware_info_get(char **local_version, char **local_md5, char **local_fw_size) +{ + char *prev_version, *json_doc = NULL; + +#define LOCAL_FW_INFO_MAX 128 + size_t info_len; + static char local_fw_info[LOCAL_FW_INFO_MAX]; + + if (tos_kv_get("local_fw", local_fw_info, sizeof(local_fw_info), &info_len) != KV_ERR_NONE) { + *local_version = NULL; + *local_md5 = NULL; + *local_fw_size = NULL; + return; + } + + json_doc = local_fw_info; + + *local_version = LITE_json_value_of(KEY_CURR_VERSION, json_doc); + *local_md5 = LITE_json_value_of(KEY_MD5, json_doc); + *local_fw_size = LITE_json_value_of(KEY_DOWNLOADED_SIZE, json_doc); + prev_version = LITE_json_value_of(KEY_PREV_VERSION, json_doc); +} + +/* update local firmware info for resuming download from break point */ +static int local_firmware_info_update(const char *curr_version, const char *prev_version, const char *md5, uint32_t downloaded_size) +{ +#define JSON_DOC_LEN 256 + static char json_doc[JSON_DOC_LEN]; + + memset(json_doc, 0, JSON_DOC_LEN); + HAL_Snprintf(json_doc, JSON_DOC_LEN, "{\"%s\":\"%s\", \"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\"}", \ + KEY_CURR_VERSION, curr_version, + KEY_MD5, md5, + KEY_DOWNLOADED_SIZE, downloaded_size, \ + KEY_PREV_VERSION, prev_version); + + if (tos_kv_set("local_fw", json_doc, strlen(json_doc)) != KV_ERR_NONE) { + Log_e("save version failed\n"); + return -1; + } + + return 0; +} + +/* get remote firmware information */ +static int remote_firmware_info_get(void *ota_client, char remote_version[], char remote_md5[], uint32_t *remote_fw_size) +{ + if (IOT_OTA_Ioctl(ota_client, IOT_OTAG_VERSION, remote_version, 128) < 0) { + return -1; + } + if (IOT_OTA_Ioctl(ota_client, IOT_OTAG_MD5SUM, remote_md5, 33) < 0) { + return -1; + } + if (IOT_OTA_Ioctl(ota_client, IOT_OTAG_FILE_SIZE, remote_fw_size, sizeof(uint32_t)) < 0) { + return -1; + } + + Log_d("remote firmware: fw_size: %d version: %s md5: %s\n", *remote_fw_size, remote_version, remote_md5); + + return 0; +} + +/* calculate left MD5 for resuming download from break point */ +static int downloaded_firmware_md5(void *ota_client, size_t size) +{ +#define BUF_SIZE 128 + static char buf[BUF_SIZE]; + size_t remain_len, read_len; + + uint32_t ota_flash_addr = ota_partition_start(OTA_PARTITION_OTA); + + remain_len = size; + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + while (remain_len > 0) { + read_len = MIN(sizeof(buf), remain_len); + if (ota_flash_read(ota_flash_addr, buf, read_len) < 0) { + return -1; + } + IOT_OTA_UpdateClientMd5(ota_client, buf, read_len); + remain_len -= read_len; + ota_flash_addr += read_len; + } + + return 0; +} + +static int connect_init_params_setup(MQTTInitParams* initParams) +{ + int ret; + + ret = HAL_GetDevInfo((void *)&sg_devInfo); + if (QCLOUD_RET_SUCCESS != ret) { + return ret; + } + + initParams->device_name = sg_devInfo.device_name; + initParams->product_id = sg_devInfo.product_id; + +#ifdef AUTH_MODE_CERT + char certs_dir[PATH_MAX + 1] = "certs"; + char current_path[PATH_MAX + 1]; + char *cwd = getcwd(current_path, sizeof(current_path)); + if (cwd == NULL) { + Log_e("getcwd return NULL"); + return QCLOUD_ERR_FAILURE; + } + sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name); + sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name); + + initParams->cert_file = sg_cert_file; + initParams->key_file = sg_key_file; +#else + initParams->device_secret = sg_devInfo.device_secret; +#endif + + + initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT; + initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL; + initParams->auto_connect_enable = 1; + initParams->event_handle.h_fp = event_handler; + + return QCLOUD_RET_SUCCESS; +} + +int ota_init(void **mqtt_client, void **ota_client) +{ + int rc = 0; + MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS; + + rc = connect_init_params_setup(&init_params); + if (rc != QCLOUD_RET_SUCCESS) { + Log_e("init params err,rc=%d", rc); + return -1; + } + + void *the_mqtt_client = IOT_MQTT_Construct(&init_params); + if (!the_mqtt_client) { + Log_e("Cloud Device Construct Failed"); + return -1; + } + + Log_i("Cloud Device Construct Success"); + + void *the_ota_client = IOT_OTA_Init(sg_devInfo.product_id, sg_devInfo.device_name, the_mqtt_client); + if (!the_ota_client) { + Log_e("initialize OTA failed"); + return -1; + } + + *mqtt_client = the_mqtt_client; + *ota_client = the_ota_client; + + return 0; +} + +int remote_firmware_download(void *ota_client, void *mqtt_client, char *running_version, uint32_t offset, uint32_t fw_size, uint32_t *downloaded_size) +{ + int rc; + uint32_t is_firmware_valid; + uint32_t received_len; + static char remote_version[128], remote_md5[33]; + +#define OTA_DOWNLOAD_BUF_LEN 128 + static char ota_download_buf[OTA_DOWNLOAD_BUF_LEN]; + + uint32_t flash_addr = ota_partition_start(OTA_PARTITION_OTA); + + //////////////////////////////////////////////// + /************* some sanity check *************/ + + /* is the file too large? */ + if (fw_size > ota_partition_size(OTA_PARTITION_OTA)) { + Log_e("OTA partition too small, fw_size: %d, ota size: %d", fw_size, ota_partition_size(OTA_PARTITION_OTA)); + return -1; + } + + /* we need the buf_len to be flash write-align aligned */ + if (!ota_flash_size_is_aligned(sizeof(ota_download_buf))) { + return -1; + } + + /* a total new firmware download, not start from a break point + we need to erase the flash to make flash ready + */ + if (offset == 0 && + ota_flash_erase_blocks(flash_addr, fw_size) < 0) { + Log_e("flash erase failed\n"); + return -1; + } + + //////////////////////////////////////////////// + + /* start http connect */ + rc = IOT_OTA_StartDownload(ota_client, offset, fw_size); + if (rc != QCLOUD_RET_SUCCESS) { + Log_e("OTA download start err, rc: %d", rc); + return -1; + } + + if (offset > 0) { + Log_d("Get offset: %x", offset); + if (downloaded_firmware_md5(ota_client, offset) < 0) { + Log_e("cal download firmware md5 failed"); + return -1; + } + } + + do { + received_len = IOT_OTA_FetchYield(ota_client, ota_download_buf, OTA_DOWNLOAD_BUF_LEN, 1); + if (received_len <= 0) { + Log_e("download fail rc = %d", received_len); + return -1; + } + + if (received_len < OTA_DOWNLOAD_BUF_LEN && + !ota_flash_size_is_aligned(received_len)) { + Log_e("size not aligned %d", received_len); + return -1; + } + + if (ota_flash_write(flash_addr, ota_download_buf, ota_flash_write_size_aligned_get(received_len)) < 0) { + return -1; + } + + /* get OTA information and update local info */ + IOT_OTA_Ioctl(ota_client, IOT_OTAG_FETCHED_SIZE, downloaded_size, sizeof(uint32_t)); +#if 0 + IOT_OTA_Ioctl(ota_client, IOT_OTAG_FILE_SIZE, &size_file, 4); +#endif + IOT_OTA_Ioctl(ota_client, IOT_OTAG_MD5SUM, remote_md5, 33); + IOT_OTA_Ioctl(ota_client, IOT_OTAG_VERSION, remote_version, 128); + + rc = local_firmware_info_update(remote_version, running_version, remote_md5, *downloaded_size); + if (rc != QCLOUD_RET_SUCCESS) { + Log_e("update local fw info err, rc: %d", rc); + return -1; + } + + IOT_MQTT_Yield(mqtt_client, 100); + } while (!IOT_OTA_IsFetchFinish(ota_client)); + + /* must check MD5 match or not */ + IOT_OTA_Ioctl(ota_client, IOT_OTAG_CHECK_FIRMWARE, &is_firmware_valid, sizeof(uint32_t)); + if (is_firmware_valid == 0) { + Log_e("The firmware is invalid"); + rc = local_firmware_info_update(NULL, running_version, NULL, 0); + if (rc != QCLOUD_RET_SUCCESS) { + Log_e("update local fw info err, rc:%d", rc); + } + + return -1; + } + + return 0; +} + +int ota_download_through_explorer(void) +{ + int rc; + void *mqtt_client, *ota_client; + + uint32_t downloadeded_size; + + uint32_t offset; + + uint32_t local_fw_size; + char *local_version = NULL, *local_md5 = NULL, *local_fw_size_str = NULL; + + uint32_t remote_fw_size; + static char remote_version[128], remote_md5[33]; + + ota_img_vs_t curr_version; + char running_version[10] = { 0 }; + + static char version[128], md5sum[33]; + + IOT_Log_Set_Level(eLOG_DEBUG); + + if (ota_init(&mqtt_client, &ota_client) < 0) { + Log_e("ota init Failed"); + return QCLOUD_ERR_FAILURE; + } + + /* 1. make sure relative topic subscribe successfully */ + IOT_MQTT_Yield(mqtt_client, 1000); + + /* 2. get local firmware information */ + local_firmware_info_get(&local_version, &local_md5, &local_fw_size_str); + + if (local_version && local_md5 && local_fw_size_str) { + Log_d("local_version: %s local_md5: %s, local_size: %s", local_version, local_md5, local_fw_size_str); + } + local_fw_size = local_fw_size_str ? atoi(local_fw_size_str) : 0; + + /* 3. get current running firmware version */ + curr_version = ota_info_curr_version(); + snprintf(running_version, sizeof(running_version), "%d.%d", curr_version.major, curr_version.minor); + Log_d("running version: %s", running_version); + + /* 4. must report local version first */ + if (IOT_OTA_ReportVersion(ota_client, running_version) < 0) { + Log_e("report OTA version failed"); + goto exit; + } + + do { + /* idle here until ota upgrate command received */ + Log_i("wait for ota upgrade command..."); + + IOT_MQTT_Yield(mqtt_client, 200); + + HAL_SleepMs(2000); + } while (!IOT_OTA_IsFetching(ota_client)); + + /* 5. get remote firmware information */ + if (remote_firmware_info_get(ota_client, remote_version, remote_md5, &remote_fw_size) < 0) { + Log_e("get remote firmware infomation failed\n"); + goto exit; + } + + /* 6. compare remote and local firmware, check whether pre-download finished or not */ + if (!local_version || !local_md5 || !local_fw_size_str) { + /* no previous downloaded firmware */ + offset = 0; + } else if (strcmp(local_version, remote_version) != 0 || + strcmp(local_md5, remote_md5) != 0 || + local_fw_size > remote_fw_size) { + /* there's a previous downloaded firmware, but not the same as current remote firmweare */ + offset = 0; + } else { + offset = local_fw_size; + } + + /* if local_firmware offset does not equal to remote_fw_size, means we have not finish firmware download */ + if (offset != remote_fw_size && + remote_firmware_download(ota_client, mqtt_client, running_version, offset, remote_fw_size, &downloadeded_size) < 0) { + goto exit; + } + + printf("new firmware downloaded!\n"); + +#if 0 + /* begin execute OTA files, should report upgrade begin */ + sg_packet_id = IOT_OTA_ReportUpgradeBegin(ota_client); + if (sg_packet_id < 0) { + Log_e("report OTA begin failed error: %d", sg_packet_id); + return QCLOUD_ERR_FAILURE; + } + + while (!sg_pub_ack) { + HAL_SleepMs(1000); + IOT_MQTT_Yield(mqtt_client, 200); + } + sg_pub_ack = K_FALSE; + + /* add your own upgrade logic here*/ + // fw_upgrade..... + + if (QCLOUD_RET_SUCCESS == rc) { + /* if upgrade success */ + /* after execute OTA files, should report upgrade result */ + sg_packet_id = IOT_OTA_ReportUpgradeSuccess(ota_client, NULL); + if (sg_packet_id < 0) { + Log_e("report OTA result failed error:%d", sg_packet_id); + return QCLOUD_ERR_FAILURE; + } + while (!sg_pub_ack) { + HAL_SleepMs(1000); + IOT_MQTT_Yield(mqtt_client, 200); + } + rc = local_firmware_info_update(version, version, md5sum, size_downloaded); // just for example, add your own logic + sg_pub_ack = K_FALSE; + + } else { + /* if upgrade fail */ + sg_packet_id = IOT_OTA_ReportUpgradeFail(ota_client, NULL); + if (0 > sg_packet_id) { + Log_e("report OTA result failed error:%d", sg_packet_id); + return QCLOUD_ERR_FAILURE; + } + while (!sg_pub_ack) { + HAL_SleepMs(1000); + IOT_MQTT_Yield(mqtt_client, 200); + } + rc = local_firmware_info_update(NULL, running_version, NULL, 0); // just for example, add your own logic + sg_pub_ack = K_FALSE; + } +#endif + +exit: + if (local_version) { + HAL_Free(local_version); + local_version = NULL; + } + + if (local_md5) { + HAL_Free(local_md5); + local_md5 = NULL; + } + + if (local_fw_size_str) { + HAL_Free(local_fw_size_str); + local_fw_size_str = NULL; + } + + IOT_OTA_Destroy(ota_client); + + IOT_MQTT_Destroy(&mqtt_client); + + return 0; +} + diff --git a/examples/qcloud_iot_explorer_sdk_ota/ota_mqtt_sample.c b/examples/qcloud_iot_explorer_sdk_ota/ota_mqtt_sample.c index 7f15b4d3..9bab8761 100644 --- a/examples/qcloud_iot_explorer_sdk_ota/ota_mqtt_sample.c +++ b/examples/qcloud_iot_explorer_sdk_ota/ota_mqtt_sample.c @@ -157,7 +157,7 @@ static int update_local_fw_info(const char *version, const char *preVer, const c FILE *fp; int wlen; int ret = QCLOUD_RET_SUCCESS; - char dataBuff[INFO_FILE_MAX_LEN]; + static char dataBuff[INFO_FILE_MAX_LEN]; memset(dataBuff, 0, INFO_FILE_MAX_LEN); HAL_Snprintf(dataBuff, INFO_FILE_MAX_LEN, "{\"%s\":\"%s\", \"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\"}", \ @@ -190,7 +190,7 @@ exit: /* get local firmware offset for resuming download from break point */ static int getFwOffset(void *h_ota, char *local_ver, char *local_md5, char *local_size, uint32_t *offset, uint32_t *size_file) { - char version[128], md5sum[33]; + static char version[128], md5sum[33]; uint32_t local_len; int Ret; @@ -217,7 +217,7 @@ static int cal_exist_fw_md5(void *h_ota, FILE *fp, size_t size) { #define BUFF_LEN 1024 - char buff[BUFF_LEN]; + static char buff[BUFF_LEN]; size_t rlen; int Ret = QCLOUD_RET_SUCCESS; @@ -273,7 +273,7 @@ static int _setup_connect_init_params(MQTTInitParams* initParams) return QCLOUD_RET_SUCCESS; } -int ota_thread(int argc, char **argv) +int ota_thread(void) { IOT_Log_Set_Level(eLOG_DEBUG); int rc; @@ -341,15 +341,15 @@ int ota_thread(int argc, char **argv) if(offset == size_file) { Log_d("download success last time without report!"); upgrade_fetch_success = true; - - /* get fw information */ + + /* get fw information */ IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33); IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128); size_downloaded = size_file; break; } - /*start http connect*/ + /*start http connect*/ rc = IOT_OTA_StartDownload(h_ota, offset, size_file); if (QCLOUD_RET_SUCCESS != rc) { Log_e("OTA download start err,rc:%d", rc); @@ -381,7 +381,7 @@ int ota_thread(int argc, char **argv) break; } } - + do { len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1); diff --git a/examples/tencent_cloud_sdk_coap/coap_sample.c b/examples/tencent_cloud_sdk_coap/coap_sample.c deleted file mode 100644 index 5b5b5018..00000000 --- a/examples/tencent_cloud_sdk_coap/coap_sample.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making IoT Hub available. - * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. - - * Licensed under the MIT License (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - - * Unless required by applicable law or agreed to in writing, software distributed under the License is - * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "tos_k.h" -#include "qcloud.h" - -static void response_message_callback(void *msg, void *context) -{ - int ret = -1; - char* payload = NULL; - int payload_len = 0; - coap_event_type_t event_type; - coap_message_t *message = NULL; - - message = msg; - event_type = qcloud_coap_event_type_get(message); - - switch (event_type) { - case COAP_EVENT_TYPE_RECEIVE_ACK: - QCLOUD_LOG_I("message received ACK, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - case COAP_EVENT_TYPE_RECEIVE_RESPCONTENT: - ret = qcloud_coap_msg_payload_get(message, &payload, &payload_len); - if (ret == QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_I("message received response, len: %d content: %s", payload_len, payload); - } else { - QCLOUD_LOG_E("message received response, content error."); - } - break; - - case COAP_EVENT_TYPE_UNAUTHORIZED: - QCLOUD_LOG_I("coap client auth token expired or invalid, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - case COAP_EVENT_TYPE_FORBIDDEN: - QCLOUD_LOG_I("coap URI is invalid for this device, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - case COAP_EVENT_TYPE_INTERNAL_SERVER_ERROR: - QCLOUD_LOG_I("coap server internal error, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - case COAP_EVENT_TYPE_ACK_TIMEOUT: - QCLOUD_LOG_I("message receive ACK timeout, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - case COAP_EVENT_TYPE_SEPRESP_TIMEOUT: - QCLOUD_LOG_I("message received ACK but receive response timeout, msgid: %d", qcloud_coap_msg_id_get(message)); - break; - - default: - break; - } -} - -static void event_handler(void *context, coap_event_t *event) -{ - switch (event->type) { - case COAP_EVENT_TYPE_RECEIVE_ACK: - QCLOUD_LOG_I("message received ACK, msgid: %d", *(uint16_t *)event->message); - break; - - case COAP_EVENT_TYPE_RECEIVE_RESPCONTENT: - QCLOUD_LOG_I("message received response, content: %s", qcloud_coap_msg_id_get(event->message)); - break; - - case COAP_EVENT_TYPE_UNAUTHORIZED: - QCLOUD_LOG_I("coap client auth token expired or invalid, msgid: %d", *(uint16_t *)event->message); - break; - - case COAP_EVENT_TYPE_FORBIDDEN: - QCLOUD_LOG_I("coap URI is invalid for this device, msgid: %d", *(uint16_t *)event->message); - break; - - case COAP_EVENT_TYPE_INTERNAL_SERVER_ERROR: - QCLOUD_LOG_I("coap server internal error, msgid: %d", *(uint16_t *)event->message); - break; - - case COAP_EVENT_TYPE_ACK_TIMEOUT: - QCLOUD_LOG_I("message receive ACK timeout, msgid: %d", *(uint16_t *)event->message); - break; - - case COAP_EVENT_TYPE_SEPRESP_TIMEOUT: - QCLOUD_LOG_I("message received ACK but receive response timeout, msgid: %d", *(uint16_t *)event->message); - break; - - default: - QCLOUD_LOG_E("unrecogonized event type: %d", event->type); - break; - } -} - -qcloud_device_t device; -qcloud_coap_client_t client; - -int coap_thread(void) -{ - char topic[128]; - qcloud_err_t rc; - coap_send_opt_t send_opt; - - qcloud_device_create(&device, "ABU45A5KT8", "dev001", "RPpqUxL03frSDSufVhjuLw=="); - - qcloud_coap_client_create(&client, &device, event_handler); - - qcloud_coap_client_connect(&client); - - do { - memset(&send_opt, 0, sizeof(coap_send_opt_t)); - send_opt.payload = "{\"name\":\"hello world\"}"; - send_opt.payload_len = strlen("{\"name\":\"hello world\"}"); - send_opt.resp_cb = response_message_callback; - - sprintf(topic, "%s/%s/data", device.product_id, device.device_name); - QCLOUD_LOG_I("topic: %s", topic); - - rc = qcloud_coap_client_msg_send(&client, topic, &send_opt); - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("client publish topic failed :%d.", rc); - } else { - QCLOUD_LOG_D("client topic has been sent, msg_id: %d", rc); - } - - rc = qcloud_coap_client_yield(&client, 200); - - if (rc != QCLOUD_ERR_SUCCESS){ - QCLOUD_LOG_E("exit with error: %d", rc); - break; - } - - osal_sleep_ms(4000); - } while (1); - - qcloud_coap_client_destroy(&client); - - return 1; -} - diff --git a/examples/tencent_cloud_sdk_coap/tencent_cloud_sdk_coap.c b/examples/tencent_cloud_sdk_coap/tencent_cloud_sdk_coap.c deleted file mode 100644 index 6318c2b2..00000000 --- a/examples/tencent_cloud_sdk_coap/tencent_cloud_sdk_coap.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "tos_k.h" - -/* 用户根据自己的底层通信链路来配置此宏 - * 如果是基于以太网lwip的链路,这里应该定义 USE_LWIP - * 如果是基于模组的通信链路,这里应该定义相应的模组宏,如使用ESP8266则定义 USE_ESP8266 - * */ -#define USE_ESP8266 - -#ifdef USE_LWIP -#include "lwip/api.h" -#include "lwip/sockets.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#endif - -#ifdef USE_ESP8266 -#include "esp8266.h" -#endif - -void application_entry(void *arg) -{ -#ifdef USE_LWIP - dns_init(); - MX_LWIP_Init(); -#endif - -#ifdef USE_ESP8266 - extern int esp8266_sal_init(hal_uart_port_t uart_port); - extern int esp8266_join_ap(const char *ssid, const char *pwd); - esp8266_sal_init(HAL_UART_PORT_0); - esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0"); -#endif - -#ifdef USE_NB_BC35 - extern int bc35_28_95_sal_init(hal_uart_port_t uart_port); - bc35_28_95_sal_init(HAL_UART_PORT_0); -#endif - - coap_thread(); - - while (1) { - printf("This is a coap demo!\r\n"); - tos_task_delay(1000); - } -} - diff --git a/examples/tencent_cloud_sdk_data_template/light_data_template_sample.c b/examples/tencent_cloud_sdk_data_template/light_data_template_sample.c deleted file mode 100644 index 82dad86d..00000000 --- a/examples/tencent_cloud_sdk_data_template/light_data_template_sample.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making IoT Hub available. - * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. - - * Licensed under the MIT License (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - - * Unless required by applicable law or agreed to in writing, software distributed under the License is - * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "qcloud.h" -#include "tos_k.h" - -#if (QCLOUD_CFG_EVENT_EN > 0u) - -#define EVENT_MESSAGE_MAX (64) -#define EVENT_NAME_MAX (64) - -typedef enum event_status_en { - EVENT_STATUS_LIGHT_OFF, - EVENT_STATUS_LIGHT_ON, -} event_status_t; - -static template_bool_t event_status; -static template_string_t event_message[EVENT_MESSAGE_MAX + 1]; -static template_float_t event_voltage; -static template_string_t event_name[EVENT_NAME_MAX + 1]; -static template_int_t event_error_code; - -static shadow_dev_property_t event_property_status[] = { - { .key = "status", .data = &event_status, .type = JSON_DATA_TYPE_BOOL }, - { .key = "message", .data = event_message, .type = JSON_DATA_TYPE_STRING }, -}; - -static shadow_dev_property_t event_property_low_voltage[] = { - { .key = "voltage", .data = &event_voltage, .type = JSON_DATA_TYPE_FLOAT }, -}; - -static shadow_dev_property_t event_property_hardware_fault[] = { - { .key = "name", .data = event_name, .type = JSON_DATA_TYPE_STRING }, - { .key = "error_code", .data = &event_error_code, .type = JSON_DATA_TYPE_INT32}, -}; - -static qcloud_event_t events[] = { - { - .event_name = "status_report", - .type = "info", - .timestamp = 0, - .event_payload_count = sizeof(event_property_status) / sizeof(event_property_status[0]), - .event_payload = event_property_status, - }, - { - .event_name = "low_voltage", - .type = "alert", - .timestamp = 0, - .event_payload_count = sizeof(event_property_low_voltage) / sizeof(event_property_low_voltage[0]), - .event_payload = event_property_low_voltage, - }, - { - .event_name = "hardware_fault", - .type = "fault", - .timestamp = 0, - .event_payload_count = sizeof(event_property_hardware_fault) / sizeof(event_property_hardware_fault[0]), - .event_payload = event_property_hardware_fault, - }, -}; - -#define EVENT_COUNTS (sizeof(events) / sizeof(events[0])) - -#define EVENT_FLAG_STATUS (1u << 0) -#define EVENT_FLAG_LOW_VOLTAGE (1u << 1) -#define EVENT_FLAG_HARDWARE_FAULT (1u << 2) - -static uint32_t event_flags = 0; - -void event_flag_set(uint32_t flag) -{ - event_flags |= flag & 0xffffffff; -} - -void event_flag_unset(uint32_t flag) -{ - event_flags &= (~flag) & 0xffffffff; -} - -uint32_t event_flag_get(void) -{ - return event_flags; -} - -void event_flag_clear(void) -{ - event_flags = 0; -} - -/*-----------------event config end -------------------*/ - -static void update_event_timestamp(qcloud_event_t *event) -{ -#ifdef EVENT_TIMESTAMP_USED - event->timestamp = (uint32_t)tos_systick_get(); //should be UTC and accurate -#else - event->timestamp = 0; -#endif -} - -static void on_event_post_handler(void *client, mqtt_incoming_msg_t *msg) -{ - QCLOUD_LOG_D("reply:%.*s", msg->payload_len, msg->payload); -} - -#endif - -///////////////////////////////////////////////////////////////////////////////////// -// dealing with product property template - -#define LIGHT_NAME_MAX 64 - -typedef enum light_color_en { - LIGHT_COLOR_RED = 0, - LIGHT_COLOR_GREEN = 1, - LIGHT_COLOR_BLUE = 2, -} light_color_t; // a enum to describe the color of a light - -typedef enum light_switch_state_en { - LIGHT_SWITCH_STATE_OFF = 0, - LIGHT_SWITCH_STATE_ON = 1, -} light_switch_state_t; // a enum to describe the switch state of a light - -typedef enum property_state_en { - PROPERTY_STATE_NOCHANGE, - PROPERTY_STATE_CHANGED, -} property_state_t; // a enum to describe whether the property state has changed - -typedef struct property_wrapper_st { - shadow_dev_property_t property; - property_state_t state; -} property_wrapper_t; // a wrapper of one property(contains the property and change state) - -/* describe a light property */ -typedef struct light_property_st { - property_wrapper_t switch_state; - property_wrapper_t color; - property_wrapper_t brightness; - property_wrapper_t name; -} light_property_t; // all the properties of a light - -// how many properties of a light? -#define LIGHT_PROPERTY_COUNT (sizeof(light_property_t) / sizeof(property_wrapper_t)) - -typedef union light_property_handler_un { - property_wrapper_t property_wrappers[LIGHT_PROPERTY_COUNT]; - light_property_t property_wrappers_of; -} light_property_handler_t; // a handler, user to iterate through all the properties - -typedef struct light_profile_st { - template_bool_t switch_state; - template_int_t color; - template_float_t brightness; - template_string_t name[LIGHT_NAME_MAX + 1]; -} light_profile_t; // just a data container - -static int is_light_property_changed = QCLOUD_FALSE; -static int is_new_property_reported = QCLOUD_FALSE; -static light_profile_t light_profile; -static light_property_handler_t light_property_handler; - -static void data_template_init(qcloud_device_t *device) -{ - memset((void *)&light_profile, 0, sizeof(light_profile_t)); - - light_profile.switch_state = LIGHT_SWITCH_STATE_OFF; - light_profile.color = LIGHT_COLOR_RED; - light_profile.brightness = 0.0; - - strncpy(light_profile.name, device->device_name, LIGHT_NAME_MAX); - light_profile.name[LIGHT_NAME_MAX] = '\0'; - - - light_property_handler.property_wrappers_of.switch_state.property.key = "power_switch"; - light_property_handler.property_wrappers_of.switch_state.property.data = &light_profile.switch_state; - light_property_handler.property_wrappers_of.switch_state.property.type = JSON_DATA_TYPE_BOOL; - - light_property_handler.property_wrappers_of.color.property.key = "color"; - light_property_handler.property_wrappers_of.color.property.data = &light_profile.color; - light_property_handler.property_wrappers_of.color.property.type = JSON_DATA_TYPE_INT32; - - light_property_handler.property_wrappers_of.brightness.property.key = "brightness"; - light_property_handler.property_wrappers_of.brightness.property.data = &light_profile.brightness; - light_property_handler.property_wrappers_of.brightness.property.type = JSON_DATA_TYPE_FLOAT; - - light_property_handler.property_wrappers_of.name.property.key = "name"; - light_property_handler.property_wrappers_of.name.property.data = &light_profile.name; - light_property_handler.property_wrappers_of.name.property.type = JSON_DATA_TYPE_STRING; -}; - -static int is_self_property(json_data_type_t property_type) -{ - return property_type == JSON_DATA_TYPE_BOOL || // power switch - property_type == JSON_DATA_TYPE_INT32|| // color - property_type == JSON_DATA_TYPE_FLOAT || // brightness - property_type == JSON_DATA_TYPE_STRING; // device name -} - -static void property_do_update(shadow_dev_property_t *property) -{ - switch (property->type) { - case JSON_DATA_TYPE_BOOL: // power switch - light_profile.switch_state = *(template_bool_t *)property->data; - break; - - case JSON_DATA_TYPE_INT32: // color - light_profile.color = *(template_int_t *)property->data; - break; - - case JSON_DATA_TYPE_FLOAT: // brightness - light_profile.brightness = *(template_float_t *)property->data; - break; - - case JSON_DATA_TYPE_STRING: // device name - /* 如果多个字符串属性,根据pProperty->key值匹配,处理字符串 */ - if (strcmp("name", property->key) != 0) { - break; - } - - memset(light_profile.name, 0, sizeof(light_profile.name)); - strncpy(light_profile.name, property->data, LIGHT_NAME_MAX); - light_profile.name[LIGHT_NAME_MAX] = '\0'; - break; - } -} - -/* 如果有自定义的字符串或者json,需要在这里解析 */ -static qcloud_err_t property_update(const char *json_doc, shadow_dev_property_t *property) -{ - QCLOUD_POINTER_SANITY_CHECK(json_doc, QCLOUD_ERR_INVAL); - QCLOUD_POINTER_SANITY_CHECK(property, QCLOUD_ERR_INVAL); - - char *json_doc_mutable = NULL, *property_data = NULL; - - /* convert const char * to char * */ - json_doc_mutable = osal_malloc(strlen(json_doc)); - if(!json_doc_mutable) - { - return QCLOUD_ERR_FAILURE; - } - QCLOUD_FUNC_EXIT_RC_IF(json_doc_mutable, NULL, QCLOUD_ERR_FAILURE); - strcpy(json_doc_mutable, json_doc); - - property_data = LITE_json_value_of((char *)property->key, json_doc_mutable); - if (!property_data) { - QCLOUD_LOG_D("property:%s no matched", property->key); - osal_free(json_doc_mutable); - return QCLOUD_ERR_FAILURE; - } - - property_do_update(property); - - osal_free(property_data); - osal_free(json_doc_mutable); - - return QCLOUD_ERR_SUCCESS; -} - -/* 服务端有控制消息下发,会触发这里的delta回调 */ -static void on_property_delta_handler(void *client, const char *json_doc, uint32_t json_doc_len, shadow_dev_property_t *property) -{ - int i = 0; - - for (i = 0; i < LIGHT_PROPERTY_COUNT; ++i) { - /* 其他数据类型已经在_handle_delta流程统一处理了,字符串和json串需要在这里处理,因为只有产品自己才知道string/json的自定义解析 */ - if (strcmp(light_property_handler.property_wrappers[i].property.key, property->key) != 0) { - continue; - } - - light_property_handler.property_wrappers[i].state = PROPERTY_STATE_CHANGED; - - if (is_self_property(light_property_handler.property_wrappers[i].property.type)) { - property_update(json_doc, &(light_property_handler.property_wrappers[i].property)); - } - - QCLOUD_LOG_I("property=%s changed", property->key); - is_light_property_changed = QCLOUD_TRUE; - return; - } - - QCLOUD_LOG_E("property=%s changed no match", property->key); -} - -/* 注册数据模板属性 */ -static qcloud_err_t data_template_property_register(qcloud_shadow_client_t *client) -{ - int i = 0; - qcloud_err_t rc; - - for (i = 0; i < LIGHT_PROPERTY_COUNT; ++i) { - rc = qcloud_shadow_device_property_register(client, &light_property_handler.property_wrappers[i].property, on_property_delta_handler); - - if (rc != QCLOUD_ERR_SUCCESS) { - rc = qcloud_shadow_client_destroy(client); - QCLOUD_LOG_E("device template property register failed, err: %d", rc); - return rc; - } - - QCLOUD_LOG_I("data template property=%s registered.", light_property_handler.property_wrappers[i].property.key); - } - - return QCLOUD_ERR_SUCCESS; -} -///////////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////////////// -__weak void OLED_Clear(void) -{ - printf("OLED Clear\n"); -} - -__weak void OLED_ShowString(int x, int y, uint8_t *str, int bold) -{ - printf("OLED ShowString: %s\n", (char *)str); -} - -// handle the light(simulated) -static void light_change_color(const char *color) -{ - // 作为demo,这里用oled屏字符显示来模拟灯颜色的切换 - // 这里应该由用户实现硬件操作代码,来改变智能灯的颜色 - // 此处demo,在开发板显示屏上显示具体的颜色 - OLED_ShowString(0, 0, (uint8_t *)color, 8); -} - -static void light_change_brightness(template_float_t brightness) -{ - // 作为demo,这里用oled屏字符显示来模拟灯颜色的切换 - // 这里应该由用户实现硬件操作代码,来改变智能灯的颜色 - // 此处demo,在开发板显示屏上显示具体的颜色 - char brightness_str[12]; - - snprintf(brightness_str, sizeof(brightness_str), "%f", brightness); - brightness_str[sizeof(brightness_str) - 1] = '\0'; - OLED_ShowString(0, 2, (uint8_t *)brightness_str, 8); -} - -static void light_power_on(void) -{ - // 作为demo,这里用oled屏字符显示来模拟灯颜色的切换 - OLED_Clear(); -} - -static void light_power_off(void) -{ - // 作为demo,这里用oled屏字符显示来模拟灯颜色的切换 - char *info = "light off"; - OLED_Clear(); - OLED_ShowString(0, 0, (uint8_t *)info, 16); -} -///////////////////////////////////////////////////////////////////////////////////// - -static void incoming_messsage_handler(void *client, void *context, mqtt_event_t *event) -{ - uint16_t packet_id = *(uint16_t *)event->message; - - switch (event->type) { - case MQTT_EVENT_UNDEF: - QCLOUD_LOG_I("undefined event occur."); - break; - - case MQTT_EVENT_DISCONNECT: - QCLOUD_LOG_I("MQTT disconnect."); - break; - - case MQTT_EVENT_RECONNECT: - QCLOUD_LOG_I("MQTT reconnect."); - break; - - case MQTT_EVENT_SUBCRIBE_SUCCESS: - QCLOUD_LOG_I("subscribe success, packet-id=%u", (uint32_t)packet_id); - break; - - case MQTT_EVENT_SUBCRIBE_TIMEOUT: - QCLOUD_LOG_I("subscribe wait ack timeout, packet-id=%u", (uint32_t)packet_id); - break; - - case MQTT_EVENT_SUBCRIBE_NACK: - QCLOUD_LOG_I("subscribe nack, packet-id=%u", (uint32_t)packet_id); - break; - - case MQTT_EVENT_PUBLISH_SUCCESS: - QCLOUD_LOG_I("publish success, packet-id=%u", (uint32_t)packet_id); - break; - - case MQTT_EVENT_PUBLISH_TIMEOUT: - QCLOUD_LOG_I("publish timeout, packet-id=%u", (uint32_t)packet_id); - break; - - case MQTT_EVENT_PUBLISH_NACK: - QCLOUD_LOG_I("publish nack, packet-id=%u", (uint32_t)packet_id); - break; - default: - QCLOUD_LOG_I("Should NOT arrive here."); - break; - } -} - -/* 示例灯光控制处理逻辑 */ -static void deal_down_stream_user_logic(void) -{ - char *color_name; - - /* 灯光颜色 */ - switch (light_profile.color) { - case LIGHT_COLOR_RED: - color_name = " RED "; - break; - - case LIGHT_COLOR_GREEN: - color_name = "GREEN"; - break; - - case LIGHT_COLOR_BLUE: - color_name = "BLUE"; - break; - } - - if (light_profile.switch_state == LIGHT_SWITCH_STATE_ON) { - /* 灯光开启式,按照控制参数展示 */ - light_power_on(); - light_change_color(color_name); - light_change_brightness(light_profile.brightness); - } else { - /* 灯光关闭展示 */ - light_power_off(); - } - -#if (QCLOUD_CFG_EVENT_EN > 0u) - if (light_property_handler.property_wrappers_of.switch_state.state == PROPERTY_STATE_CHANGED) { - if (light_profile.switch_state == LIGHT_SWITCH_STATE_ON) { - strcpy(event_message, "light on"); - event_status = EVENT_STATUS_LIGHT_ON; - } else { - strcpy(event_message, "light off"); - event_status = EVENT_STATUS_LIGHT_OFF; - } - - event_flag_set(EVENT_FLAG_STATUS); - } -#endif -} - -/* 用户需要实现的上行数据的业务逻辑,此处仅供示例 */ -static void deal_up_stream_user_logic(shadow_dev_property_t *properties_report[], int *count) -{ - int i, j; - - *count = 0; - - for (i = 0, j = 0; i < LIGHT_PROPERTY_COUNT; ++i) { - if (light_property_handler.property_wrappers[i].state == PROPERTY_STATE_CHANGED) { - properties_report[j++] = &(light_property_handler.property_wrappers[i].property); - light_property_handler.property_wrappers[i].state = PROPERTY_STATE_NOCHANGE; - } - } - *count = j; -} - -static void on_shadow_update_handler(void *client, - qcloud_shadow_req_method_t method, - qcloud_shadow_req_state_t req_state, - const char *json_doc, - void *context) -{ - QCLOUD_LOG_I("recv shadow update response, request state: %d", req_state); -} - -/* 5s定时上报属性状态,可根据业务裁剪,此处仅供示例 */ -qcloud_err_t timely_reporting(shadow_dev_property_t *properties_report[], osal_timer_t *report_timer) -{ - int i; - - if (osal_timer_is_expired(report_timer)){ - for (i = 0; i < LIGHT_PROPERTY_COUNT; ++i) { - properties_report[i] = &(light_property_handler.property_wrappers[i].property); - osal_timer_countdown_ms(report_timer, 5000); - } - return QCLOUD_ERR_SUCCESS; - } - - return QCLOUD_ERR_INVAL; -} - -static qcloud_device_t device; -static qcloud_shadow_client_t shadow_client; -static char shadow_update_buffer[2048]; -static shadow_dev_property_t *properties_report[LIGHT_PROPERTY_COUNT]; - -#if (QCLOUD_CFG_EVENT_EN > 0u) -static qcloud_event_client_t event_client; -#endif - -int data_template_light_thread(void) -{ - qcloud_err_t rc; - int properties_report_count = 0; - osal_timer_t report_timer; - -#if (QCLOUD_CFG_EVENT_EN > 0u) - uint32_t event_flag; - int event_count; - qcloud_event_t *events2report[EVENT_COUNTS]; -#endif - - QCLOUD_LOG_I("data template sample start"); - - qcloud_device_create(&device, "XC31USKYPL", "dev001", "Pz1wK0fVJHxSojqxDuuvmg=="); - - // init connection - qcloud_shadow_client_create(&shadow_client, &device, incoming_messsage_handler, SHADOW_TYPE_TEMPLATE); - - light_power_off(); - - // init data template - data_template_init(&device); - -#if (QCLOUD_CFG_EVENT_EN > 0u) - rc = qcloud_event_client_create(&event_client, &shadow_client, &device); - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("event init failed: %d", rc); - return rc; - } -#endif - - // register data template propertys here - rc = data_template_property_register(&shadow_client); - if (rc == QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_I("data template propertys register success"); - } else { - QCLOUD_LOG_E("data template propertys register failed: %d", rc); - return rc; - } - -#define SHADOW_REQUEST_TIMEOUT (10) // in seconds - // 离线期间服务端可能有下行命令,此处实现同步。version同步后台非必要 - rc = qcloud_shadow_client_get_sync(&shadow_client, SHADOW_REQUEST_TIMEOUT); - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("device shadow get failed, err: %d", rc); - return rc; - } - - // 属性定时上报timer,可以根据业务需要裁剪。 - osal_timer_init(&report_timer); - - while (qcloud_shadow_client_is_connected(&shadow_client) || - rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT || - rc == QCLOUD_ERR_MQTT_RECONNECTED || - rc == QCLOUD_ERR_SUCCESS) { - - rc = qcloud_shadow_client_yield(&shadow_client, 200); - if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) { - osal_sleep_ms(1000); - continue; - } else if (rc != QCLOUD_ERR_SUCCESS && rc != QCLOUD_ERR_MQTT_RECONNECTED) { - QCLOUD_LOG_E("exit with error: %d", rc); - break; - } - - /* 服务端下行消息,业务处理逻辑1入口 */ - if (is_light_property_changed) { - deal_down_stream_user_logic(); - - /* 业务逻辑处理完后需要同步通知服务端:设备数据已更新,删除dseire数据 */ - rc = qcloud_shadow_client_desire_null_construct(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer)); - if (rc == QCLOUD_ERR_SUCCESS) { - rc = qcloud_shadow_client_update_sync(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer), 5); - if (rc == QCLOUD_ERR_SUCCESS) { - is_light_property_changed = QCLOUD_FALSE; - - // 用户需要根据业务情况修改上报flag的赋值位置,此处仅为示例。 - is_new_property_reported = QCLOUD_TRUE; - QCLOUD_LOG_I("shadow update(desired) success"); - } else { - QCLOUD_LOG_E("shadow update(desired) failed, err: %d", rc); - } - } else { - QCLOUD_LOG_E("construct desire failed, err: %d", rc); - } - } - - /* 设备上行消息,业务逻辑2入口 */ - if (is_new_property_reported) { - /* delta消息是属性的desire和属性的report的差异集,收到deseire消息处理后,要report属性的状态 */ - deal_up_stream_user_logic(properties_report, &properties_report_count); - if (properties_report_count > 0) { - rc = qcloud_shadow_client_report_construct_array(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer), - properties_report_count, properties_report); - if (rc == QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_D("report: %s", shadow_update_buffer); - rc = qcloud_shadow_client_update_async(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer), - on_shadow_update_handler, NULL, 5); - if (rc == QCLOUD_ERR_SUCCESS) { - is_new_property_reported = QCLOUD_FALSE; - QCLOUD_LOG_I("shadow update(reported) success"); - } else { - QCLOUD_LOG_E("shadow update(reported) failed, err: %d", rc); - } - - } else { - QCLOUD_LOG_E("construct reported failed, err: %d", rc); - } - } else { - QCLOUD_LOG_D("no data need to be reported or someting goes wrong"); - } - } - - - if (QCLOUD_ERR_SUCCESS == timely_reporting(properties_report, &report_timer)){ - rc = qcloud_shadow_client_report_construct_array(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer), - LIGHT_PROPERTY_COUNT, properties_report); - if (rc == QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_D("cycle report:%s", shadow_update_buffer); - rc = qcloud_shadow_client_update_async(&shadow_client, shadow_update_buffer, sizeof(shadow_update_buffer), - on_shadow_update_handler, NULL, 5); - if (rc == QCLOUD_ERR_SUCCESS) { - is_new_property_reported = QCLOUD_FALSE; - QCLOUD_LOG_I("shadow update(reported) success"); - } else { - QCLOUD_LOG_E("shadow update(reported) failed, err: %d", rc); - } - } else { - QCLOUD_LOG_E("construct reported failed, err: %d", rc); - } - } - -#if (QCLOUD_CFG_EVENT_EN > 0u) - // 事件上报 - event_count = 0; - event_flag = event_flag_get(); - if (EVENT_COUNTS > 0 && event_flag > 0) { - int i = 0; - for (i = 0; i < EVENT_COUNTS; ++i) { - if (event_flag & (1 << i)) { // i-th event is set - events2report[event_count++] = &events[i]; - update_event_timestamp(&events[i]); - } - } - - rc = qcloud_event_client_post(&event_client, shadow_update_buffer, sizeof(shadow_update_buffer), \ - event_count, events2report, on_event_post_handler); - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("event post failed: %d", rc); - } - - event_flag_clear(); - } -#endif - - osal_sleep_ms(3000); - } - - qcloud_shadow_client_destroy(&shadow_client); -#if (QCLOUD_CFG_EVENT_EN > 0u) - qcloud_event_client_destroy(&event_client); -#endif - - return -1; -} - diff --git a/examples/tencent_cloud_sdk_data_template/tencent_cloud_sdk_explorer.c b/examples/tencent_cloud_sdk_data_template/tencent_cloud_sdk_explorer.c deleted file mode 100644 index 533a7a72..00000000 --- a/examples/tencent_cloud_sdk_data_template/tencent_cloud_sdk_explorer.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "tos_k.h" - -/* 用户根据自己的底层通信链路来配置此宏 - * 如果是基于以太网lwip的链路,这里应该定义 USE_LWIP - * 如果是基于模组的通信链路,这里应该定义相应的模组宏,如使用ESP8266则定义 USE_ESP8266 - * */ -#define USE_ESP8266 - -#ifdef USE_LWIP -#include "lwip/api.h" -#include "lwip/sockets.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#endif - -#ifdef USE_ESP8266 -#include "esp8266.h" -#endif - -void application_entry(void *arg) -{ -#ifdef USE_LWIP - dns_init(); - MX_LWIP_Init(); -#endif - -#ifdef USE_ESP8266 - extern int esp8266_sal_init(hal_uart_port_t uart_port); - extern int esp8266_join_ap(const char *ssid, const char *pwd); - esp8266_sal_init(HAL_UART_PORT_0); - esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0"); -#endif - -#ifdef USE_NB_BC35 - extern int bc35_28_95_sal_init(hal_uart_port_t uart_port); - bc35_28_95_sal_init(HAL_UART_PORT_0); -#endif - - data_template_light_thread(); - - while (1) { - printf("This is a tencent cloud sdk data template demo!\r\n"); - tos_task_delay(1000); - } -} - diff --git a/examples/tencent_cloud_sdk_mqtt/mqtt_sample.c b/examples/tencent_cloud_sdk_mqtt/mqtt_sample.c deleted file mode 100644 index 33c66a18..00000000 --- a/examples/tencent_cloud_sdk_mqtt/mqtt_sample.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making IoT Hub available. - * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. - - * Licensed under the MIT License (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - - * Unless required by applicable law or agreed to in writing, software distributed under the License is - * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "tos_k.h" -#include "qcloud.h" - - -static int sg_count = 0; -static int sg_sub_packet_id = -1; - -void event_handler(void *client, void *context, mqtt_event_t *event) { - mqtt_incoming_msg_t* mqtt_messge = NULL; - uint16_t packet_id = *(uint16_t *)event->message; - - switch(event->type) { - case MQTT_EVENT_UNDEF: - QCLOUD_LOG_I("undefined event occur."); - break; - - case MQTT_EVENT_DISCONNECT: - QCLOUD_LOG_I("MQTT disconnect."); - break; - - case MQTT_EVENT_RECONNECT: - QCLOUD_LOG_I("MQTT reconnect."); - break; - - case MQTT_EVENT_PUBLISH_RECVEIVED: - mqtt_messge = (mqtt_incoming_msg_t*)event->message; - QCLOUD_LOG_I("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s", - mqtt_messge->topic_len, - mqtt_messge->topic, - mqtt_messge->payload_len, - mqtt_messge->payload); - break; - case MQTT_EVENT_SUBCRIBE_SUCCESS: - QCLOUD_LOG_I("subscribe success, packet-id=%u", (unsigned int)packet_id); - sg_sub_packet_id = packet_id; - break; - - case MQTT_EVENT_SUBCRIBE_TIMEOUT: - QCLOUD_LOG_I("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id); - sg_sub_packet_id = packet_id; - break; - - case MQTT_EVENT_SUBCRIBE_NACK: - QCLOUD_LOG_I("subscribe nack, packet-id=%u", (unsigned int)packet_id); - sg_sub_packet_id = packet_id; - break; - - case MQTT_EVENT_UNSUBCRIBE_SUCCESS: - QCLOUD_LOG_I("unsubscribe success, packet-id=%u", (unsigned int)packet_id); - break; - - case MQTT_EVENT_UNSUBCRIBE_TIMEOUT: - QCLOUD_LOG_I("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id); - break; - - case MQTT_EVENT_UNSUBCRIBE_NACK: - QCLOUD_LOG_I("unsubscribe nack, packet-id=%u", (unsigned int)packet_id); - break; - - case MQTT_EVENT_PUBLISH_SUCCESS: - QCLOUD_LOG_I("publish success, packet-id=%u", (unsigned int)packet_id); - break; - - case MQTT_EVENT_PUBLISH_TIMEOUT: - QCLOUD_LOG_I("publish timeout, packet-id=%u", (unsigned int)packet_id); - break; - - case MQTT_EVENT_PUBLISH_NACK: - QCLOUD_LOG_I("publish nack, packet-id=%u", (unsigned int)packet_id); - break; - default: - QCLOUD_LOG_I("Should NOT arrive here."); - break; - } -} - -/** - * MQTTϢմ - * - * @param topicName topic - * @param topicNameLen topic - * @param message ѶϢĽṹ - * @param userData Ϣ - */ -static void on_message_callback(void *client, mqtt_incoming_msg_t *message, void *private_data) -{ - if (!message) { - return; - } - - QCLOUD_LOG_I("Receive Message With topicName:%.*s, payload:%.*s", - (int) message->topic_len, message->topic, (int) message->payload_len, (char *)message->payload); -} - -static qcloud_device_t device; -static mqtt_connect_opt_t connect_opt; -static qcloud_mqtt_client_t client; - -static char topic_filter[128] = {0}; - -#define MAX_SIZE_OF_TOPIC_CONTENT 100 -static char topic_payload[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0}; - -void mqtt_basic_thread(void) -{ - qcloud_err_t rc; - mqtt_publish_opt_t publish_opt; - mqtt_subscribe_opt_t subscribe_opt; - - QCLOUD_LOG_I("mqtt_sample start"); - - qcloud_device_create(&device, "XC31USKYPL", "dev001", "Pz1wK0fVJHxSojqxDuuvmg=="); - - qcloud_mqtt_connect_opt_create(&connect_opt, &device, MQTT_VERSION_3_1_1, 240, MQTT_CLEAN_SESSION_STATE_ENABLED); - - qcloud_mqtt_client_create(&client, &device, event_handler, NULL, QCLOUD_AUTO_CONN_STATE_ENABLED); - - qcloud_mqtt_client_connect(&client, &connect_opt); - - osal_snprintf(topic_filter, sizeof(topic_filter), "%s/%s/%s", device.product_id, device.device_name, "data"); - - subscribe_opt.message_handler = on_message_callback; - subscribe_opt.private_data = NULL; - subscribe_opt.qos = MQTT_QOS0; - - rc = qcloud_mqtt_client_subscribe(&client, topic_filter, &subscribe_opt); - - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("Subscribe Failed: %d", rc); - } else { - QCLOUD_LOG_D("Subscribe success"); - } - - do { - rc = qcloud_mqtt_client_yield(&client, &connect_opt, 3000); - if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) { - osal_sleep_ms(1000); - continue; - } else if (rc != QCLOUD_ERR_SUCCESS && rc != QCLOUD_ERR_MQTT_RECONNECTED) { - QCLOUD_LOG_E("exit with error: %d", rc); - break; - } - - // ȴĽ - if (sg_sub_packet_id > 0) { - sprintf(topic_filter, "%s/%s/%s", device.product_id, device.device_name, "data"); - osal_snprintf(topic_payload, sizeof(topic_payload), "{\"action\": \"publish_test\", \"count\": \"%d\"}", sg_count++); - - memset(&publish_opt, 0, sizeof(mqtt_publish_opt_t)); - publish_opt.qos = MQTT_QOS1; - publish_opt.payload = topic_payload; - publish_opt.payload_len = strlen(topic_payload); - - rc = qcloud_mqtt_client_publish(&client, topic_filter, &publish_opt); - if (rc != QCLOUD_ERR_SUCCESS) { - QCLOUD_LOG_E("client publish topic failed :%d.", rc); - } - } - - osal_sleep_ms(1000); - } while (1); - - qcloud_mqtt_client_destroy(&client); - - return; -} - diff --git a/kernel/core/include/tos_binary_heap.h b/kernel/core/include/tos_binary_heap.h index fd9b425b..0a121361 100644 --- a/kernel/core/include/tos_binary_heap.h +++ b/kernel/core/include/tos_binary_heap.h @@ -71,8 +71,6 @@ __API__ k_err_t tos_bin_heap_create(k_bin_heap_t *bin_heap, void *pool, size_t i */ __API__ k_err_t tos_bin_heap_destroy(k_bin_heap_t *bin_heap); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a binary heap with a dynamic allocated pool. * create a binary heap with a dynamic allocated pool. @@ -102,8 +100,6 @@ __API__ k_err_t tos_bin_heap_create_dyn(k_bin_heap_t *bin_heap, size_t item_cnt, */ __API__ k_err_t tos_bin_heap_destroy_dyn(k_bin_heap_t *bin_heap); -#endif - /** * @brief Push an item. * push an item into the binary heap. diff --git a/kernel/core/include/tos_char_fifo.h b/kernel/core/include/tos_char_fifo.h index 1580b0b0..c8635217 100644 --- a/kernel/core/include/tos_char_fifo.h +++ b/kernel/core/include/tos_char_fifo.h @@ -57,8 +57,6 @@ __API__ k_err_t tos_chr_fifo_create(k_chr_fifo_t *chr_fifo, void *buffer, size_t */ __API__ k_err_t tos_chr_fifo_destroy(k_chr_fifo_t *chr_fifo); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a character fifo with a dynamic allocated buffer. * Create a character fifo with a dynamic allocated buffer. @@ -89,8 +87,6 @@ __API__ k_err_t tos_chr_fifo_create_dyn(k_chr_fifo_t *chr_fifo, size_t fifo_size */ __API__ k_err_t tos_chr_fifo_destroy_dyn(k_chr_fifo_t *chr_fifo); -#endif - /** * @brief Push data into character fifo. * Push one single data into the character fifo. diff --git a/kernel/core/include/tos_config_check.h b/kernel/core/include/tos_config_check.h index 087e6ccf..3e4b1e2b 100644 --- a/kernel/core/include/tos_config_check.h +++ b/kernel/core/include/tos_config_check.h @@ -20,10 +20,6 @@ #if TOS_CFG_EVENT_DRIVEN_EN > 0u -#if TOS_CFG_MMHEAP_EN == 0u -#error "INVALID config, must enable tos_mmheap to use event-driven" -#endif - #if TOS_CFG_TICKLESS_EN == 1u #error "INVALID config, tickless not supported in event-driven yet" #endif diff --git a/kernel/core/include/tos_config_default.h b/kernel/core/include/tos_config_default.h index 6fefdbfa..369554e9 100644 --- a/kernel/core/include/tos_config_default.h +++ b/kernel/core/include/tos_config_default.h @@ -90,7 +90,7 @@ ///////////////////////////////////////// // enable mmheap #ifndef TOS_CFG_MMHEAP_EN -#define TOS_CFG_MMHEAP_EN 1u +#define TOS_CFG_MMHEAP_EN 0u #endif #ifndef TOS_CFG_MMHEAP_DEFAULT_POOL_EN diff --git a/kernel/core/include/tos_mail_queue.h b/kernel/core/include/tos_mail_queue.h index 61391f01..1371166c 100644 --- a/kernel/core/include/tos_mail_queue.h +++ b/kernel/core/include/tos_mail_queue.h @@ -58,8 +58,6 @@ __API__ k_err_t tos_mail_q_create(k_mail_q_t *mail_q, void *pool, size_t mail_cn */ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a mail queue with dynamic allocated pool. * create a mail queue with dynamic allocated pool. @@ -88,8 +86,6 @@ __API__ k_err_t tos_mail_q_create_dyn(k_mail_q_t *mail_q, size_t mail_cnt, size_ */ __API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q); -#endif - /** * @brief Flush the mail queue. * flush the mail queue. diff --git a/kernel/core/include/tos_message_queue.h b/kernel/core/include/tos_message_queue.h index be2d4d20..78a6f96c 100644 --- a/kernel/core/include/tos_message_queue.h +++ b/kernel/core/include/tos_message_queue.h @@ -57,8 +57,6 @@ __API__ k_err_t tos_msg_q_create(k_msg_q_t *msg_q, void *pool, size_t msg_cnt); */ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a message queue with dynamic allocated pool. * create a message queue with dynamic allocated pool. @@ -86,8 +84,6 @@ __API__ k_err_t tos_msg_q_create_dyn(k_msg_q_t *msg_q, size_t msg_cnt); */ __API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q); -#endif - /** * @brief Flush the message queue. * flush the message queue. diff --git a/kernel/core/include/tos_priority_queue.h b/kernel/core/include/tos_priority_queue.h index 580b58ce..4c75ebc1 100644 --- a/kernel/core/include/tos_priority_queue.h +++ b/kernel/core/include/tos_priority_queue.h @@ -99,8 +99,6 @@ __API__ k_err_t tos_prio_q_create(k_prio_q_t *prio_q, void *mgr_array, void *poo */ __API__ k_err_t tos_prio_q_destroy(k_prio_q_t *prio_q); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a priority queue with dynamic allocated mgr array and data pool. * create a priority queue with dynamic allocated mgr array and data pool. @@ -131,8 +129,6 @@ __API__ k_err_t tos_prio_q_create_dyn(k_prio_q_t *prio_q, size_t item_cnt, size_ */ __API__ k_err_t tos_prio_q_destroy_dyn(k_prio_q_t *prio_q); -#endif - /** * @brief Enqueue an priority queue. * enqueue an item into the priority queue. diff --git a/kernel/core/include/tos_ring_queue.h b/kernel/core/include/tos_ring_queue.h index 3ed6b856..0c5c2e82 100644 --- a/kernel/core/include/tos_ring_queue.h +++ b/kernel/core/include/tos_ring_queue.h @@ -65,8 +65,6 @@ __API__ k_err_t tos_ring_q_create(k_ring_q_t *ring_q, void *pool, size_t item_cn */ __API__ k_err_t tos_ring_q_destroy(k_ring_q_t *ring_q); -#if TOS_CFG_MMHEAP_EN > 0u - /** * @brief Create a ring queue with dynamic allocated pool. * create a ring queue with dynamic allocated pool. @@ -97,9 +95,6 @@ __API__ k_err_t tos_ring_q_create_dyn(k_ring_q_t *ring_q, size_t item_cnt, size_ */ __API__ k_err_t tos_ring_q_destroy_dyn(k_ring_q_t *ring_q); -#endif - - /** * @brief Enqueue an item. * enqueue an item into the ring queue. diff --git a/kernel/core/include/tos_sys.h b/kernel/core/include/tos_sys.h index b54b4653..6dbbe3a2 100644 --- a/kernel/core/include/tos_sys.h +++ b/kernel/core/include/tos_sys.h @@ -196,8 +196,6 @@ __KNL__ __STATIC_INLINE__ void knl_object_deinit(knl_obj_t *knl_obj) #endif -#if TOS_CFG_MMHEAP_EN > 0u - __KNL__ __STATIC_INLINE__ void knl_object_alloc_reset(knl_obj_t *knl_obj) { knl_obj->alloc_type = KNL_OBJ_ALLOC_TYPE_NONE; @@ -223,8 +221,6 @@ __KNL__ __STATIC_INLINE__ int knl_object_alloc_is_static(knl_obj_t *knl_obj) return knl_obj->alloc_type == KNL_OBJ_ALLOC_TYPE_STATIC; } -#endif - __CDECLS_END #endif /* _TOS_SYS_H_ */ diff --git a/kernel/core/tos_binary_heap.c b/kernel/core/tos_binary_heap.c index 5ccd11f8..4c4e6a29 100644 --- a/kernel/core/tos_binary_heap.c +++ b/kernel/core/tos_binary_heap.c @@ -127,9 +127,7 @@ __API__ k_err_t tos_bin_heap_create(k_bin_heap_t *bin_heap, void *pool, size_t i bin_heap->pool = (uint8_t *)pool; TOS_OBJ_INIT(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&bin_heap->knl_obj); -#endif return K_ERR_NONE; } @@ -139,11 +137,9 @@ __API__ k_err_t tos_bin_heap_destroy(k_bin_heap_t *bin_heap) TOS_PTR_SANITY_CHECK(bin_heap); TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&bin_heap->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif bin_heap->total = 0; bin_heap->cmp = K_NULL; @@ -152,15 +148,11 @@ __API__ k_err_t tos_bin_heap_destroy(k_bin_heap_t *bin_heap) bin_heap->pool = K_NULL; TOS_OBJ_DEINIT(bin_heap); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&bin_heap->knl_obj); -#endif return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_bin_heap_create_dyn(k_bin_heap_t *bin_heap, size_t item_cnt, size_t item_size, k_bin_heap_cmp cmp) { void *pool; @@ -208,8 +200,6 @@ __API__ k_err_t tos_bin_heap_destroy_dyn(k_bin_heap_t *bin_heap) return K_ERR_NONE; } -#endif - __API__ k_err_t tos_bin_heap_push(k_bin_heap_t *bin_heap, void *item, size_t item_size) { TOS_CPU_CPSR_ALLOC(); @@ -298,7 +288,7 @@ __API__ int tos_bin_heap_is_full(k_bin_heap_t *bin_heap) TOS_OBJ_VERIFY_RC(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP, K_FALSE); TOS_CPU_INT_DISABLE(); - is_full = (bin_heap->total == bin_heap->item_cnt); + is_full = (bin_heap->total == bin_heap->item_cnt ? K_TRUE : K_FALSE); TOS_CPU_INT_ENABLE(); return is_full; diff --git a/kernel/core/tos_char_fifo.c b/kernel/core/tos_char_fifo.c index 4d6cca7f..7dc3bc47 100644 --- a/kernel/core/tos_char_fifo.c +++ b/kernel/core/tos_char_fifo.c @@ -30,9 +30,7 @@ __API__ k_err_t tos_chr_fifo_create(k_chr_fifo_t *chr_fifo, void *buffer, size_t } TOS_OBJ_INIT(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&chr_fifo->knl_obj); -#endif return K_ERR_NONE; } @@ -44,11 +42,9 @@ __API__ k_err_t tos_chr_fifo_destroy(k_chr_fifo_t *chr_fifo) TOS_PTR_SANITY_CHECK(chr_fifo); TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&chr_fifo->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif err = tos_ring_q_destroy(&chr_fifo->ring_q); if (err != K_ERR_NONE) { @@ -56,15 +52,11 @@ __API__ k_err_t tos_chr_fifo_destroy(k_chr_fifo_t *chr_fifo) } TOS_OBJ_DEINIT(chr_fifo); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&chr_fifo->knl_obj); -#endif return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_chr_fifo_create_dyn(k_chr_fifo_t *chr_fifo, size_t fifo_size) { k_err_t err; @@ -104,8 +96,6 @@ __API__ k_err_t tos_chr_fifo_destroy_dyn(k_chr_fifo_t *chr_fifo) return K_ERR_NONE; } -#endif - __API__ k_err_t tos_chr_fifo_push(k_chr_fifo_t *chr_fifo, uint8_t data) { TOS_PTR_SANITY_CHECK(chr_fifo); diff --git a/kernel/core/tos_mail_queue.c b/kernel/core/tos_mail_queue.c index 57065974..033d9b4d 100644 --- a/kernel/core/tos_mail_queue.c +++ b/kernel/core/tos_mail_queue.c @@ -33,9 +33,7 @@ __API__ k_err_t tos_mail_q_create(k_mail_q_t *mail_q, void *pool, size_t mail_cn pend_object_init(&mail_q->pend_obj); TOS_OBJ_INIT(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&mail_q->knl_obj); -#endif return K_ERR_NONE; } @@ -48,11 +46,9 @@ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q) TOS_PTR_SANITY_CHECK(mail_q); TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&mail_q->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif TOS_CPU_INT_DISABLE(); @@ -67,9 +63,7 @@ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q) pend_object_deinit(&mail_q->pend_obj); TOS_OBJ_DEINIT(mail_q); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&mail_q->knl_obj); -#endif TOS_CPU_INT_ENABLE(); knl_sched(); @@ -77,8 +71,6 @@ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q) return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_mail_q_create_dyn(k_mail_q_t *mail_q, size_t mail_cnt, size_t mail_size) { k_err_t err; @@ -131,8 +123,6 @@ __API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q) return K_ERR_NONE; } -#endif - __API__ k_err_t tos_mail_q_flush(k_mail_q_t *mail_q) { TOS_PTR_SANITY_CHECK(mail_q); diff --git a/kernel/core/tos_message_queue.c b/kernel/core/tos_message_queue.c index ca91a36f..0f3cee21 100644 --- a/kernel/core/tos_message_queue.c +++ b/kernel/core/tos_message_queue.c @@ -34,9 +34,7 @@ __API__ k_err_t tos_msg_q_create(k_msg_q_t *msg_q, void *pool, size_t msg_cnt) pend_object_init(&msg_q->pend_obj); TOS_OBJ_INIT(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&msg_q->knl_obj); -#endif return K_ERR_NONE; } @@ -49,11 +47,9 @@ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q) TOS_PTR_SANITY_CHECK(msg_q); TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&msg_q->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif TOS_CPU_INT_DISABLE(); @@ -68,9 +64,7 @@ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q) pend_object_deinit(&msg_q->pend_obj); TOS_OBJ_DEINIT(msg_q); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&msg_q->knl_obj); -#endif TOS_CPU_INT_ENABLE(); knl_sched(); @@ -78,8 +72,6 @@ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q) return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_msg_q_create_dyn(k_msg_q_t *msg_q, size_t msg_cnt) { k_err_t err; @@ -132,8 +124,6 @@ __API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q) return K_ERR_NONE; } -#endif - __API__ k_err_t tos_msg_q_flush(k_msg_q_t *msg_q) { TOS_PTR_SANITY_CHECK(msg_q); diff --git a/kernel/core/tos_priority_queue.c b/kernel/core/tos_priority_queue.c index 4d07d43f..e6dc6b66 100644 --- a/kernel/core/tos_priority_queue.c +++ b/kernel/core/tos_priority_queue.c @@ -180,9 +180,7 @@ __API__ k_err_t tos_prio_q_create(k_prio_q_t *prio_q, void *mgr_array, void *poo prio_q->data_pool = (uint8_t *)pool; TOS_OBJ_INIT(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&prio_q->knl_obj); -#endif return K_ERR_NONE; } @@ -192,11 +190,9 @@ __API__ k_err_t tos_prio_q_destroy(k_prio_q_t *prio_q) TOS_PTR_SANITY_CHECK(prio_q); TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&prio_q->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif prio_q_pool_mgr_deinit(&prio_q->pool_mgr); prio_q_prio_mgr_deinit(&prio_q->prio_mgr); @@ -208,15 +204,11 @@ __API__ k_err_t tos_prio_q_destroy(k_prio_q_t *prio_q) prio_q->data_pool = K_NULL; TOS_OBJ_DEINIT(prio_q); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&prio_q->knl_obj); -#endif return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_prio_q_create_dyn(k_prio_q_t *prio_q, size_t item_cnt, size_t item_size) { k_err_t err; @@ -273,8 +265,6 @@ __API__ k_err_t tos_prio_q_destroy_dyn(k_prio_q_t *prio_q) return K_ERR_NONE; } -#endif - __STATIC__ void prio_q_do_enqueue(k_prio_q_t *prio_q, void *item, prio_q_slot_t slot, k_prio_t prio) { prio_q_item_copy_from(prio_q, item, slot); diff --git a/kernel/core/tos_ring_queue.c b/kernel/core/tos_ring_queue.c index 9ebe12ec..fd3f8b74 100644 --- a/kernel/core/tos_ring_queue.c +++ b/kernel/core/tos_ring_queue.c @@ -56,9 +56,7 @@ __STATIC_INLINE__ void ring_q_item_decrease(k_ring_q_t *ring_q) ring_q->item_cnt = item_cnt; TOS_OBJ_INIT(ring_q, KNL_OBJ_TYPE_RING_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_set_static(&ring_q->knl_obj); -#endif return K_ERR_NONE; } @@ -68,11 +66,9 @@ __API__ k_err_t tos_ring_q_destroy(k_ring_q_t *ring_q) TOS_PTR_SANITY_CHECK(ring_q); TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE); -#if TOS_CFG_MMHEAP_EN > 0u if (!knl_object_alloc_is_static(&ring_q->knl_obj)) { return K_ERR_OBJ_INVALID_ALLOC_TYPE; } -#endif ring_q->head = 0u; ring_q->tail = 0u; @@ -83,15 +79,11 @@ __API__ k_err_t tos_ring_q_destroy(k_ring_q_t *ring_q) ring_q->item_cnt = 0u; TOS_OBJ_DEINIT(ring_q); -#if TOS_CFG_MMHEAP_EN > 0u knl_object_alloc_reset(&ring_q->knl_obj); -#endif return K_ERR_NONE; } -#if TOS_CFG_MMHEAP_EN > 0u - __API__ k_err_t tos_ring_q_create_dyn(k_ring_q_t *ring_q, size_t item_cnt, size_t item_size) { void *pool; @@ -142,8 +134,6 @@ __API__ k_err_t tos_ring_q_destroy_dyn(k_ring_q_t *ring_q) return K_ERR_NONE; } -#endif - __API__ k_err_t tos_ring_q_enqueue(k_ring_q_t *ring_q, void *item, size_t item_size) { TOS_CPU_CPSR_ALLOC(); diff --git a/kernel/core/tos_task.c b/kernel/core/tos_task.c index bbd07809..b91f8360 100644 --- a/kernel/core/tos_task.c +++ b/kernel/core/tos_task.c @@ -255,7 +255,7 @@ __API__ k_err_t tos_task_create_dyn(k_task_t **task, return K_ERR_TASK_OUT_OF_MEMORY; } - stk_base = tos_mmheap_aligned_alloc(stk_size, sizeof(cpu_addr_t)); + stk_base = tos_mmheap_alloc(stk_size); if (!stk_base) { tos_mmheap_free(the_task); return K_ERR_TASK_OUT_OF_MEMORY; @@ -349,9 +349,9 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new) k_prio_t highest_pending_prio; #endif + TOS_IN_IRQ_CHECK(); TOS_PTR_SANITY_CHECK(task); TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK); - TOS_IN_IRQ_CHECK(); if (unlikely(prio_new >= K_TASK_PRIO_IDLE)) { return K_ERR_TASK_PRIO_INVALID; @@ -497,9 +497,9 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task) { TOS_CPU_CPSR_ALLOC(); + TOS_IN_IRQ_CHECK(); TOS_PTR_SANITY_CHECK(task); TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK); - TOS_IN_IRQ_CHECK(); TOS_CPU_INT_DISABLE(); diff --git a/kernel/evtdrv/include/tos_evtdrv_err.h b/kernel/evtdrv/include/tos_evtdrv_err.h index f2f1d8f0..38310754 100644 --- a/kernel/evtdrv/include/tos_evtdrv_err.h +++ b/kernel/evtdrv/include/tos_evtdrv_err.h @@ -24,7 +24,7 @@ typedef enum evtdrv_err_en { EVTDRV_ERR_PTR_NULL = 0x2u, EVTDRV_ERR_MSG_BUSY = 0x3u, EVTDRV_ERR_TASK_INVALID = 0x4u, - EVTDRV_ERR_MMHEAP_NOT_ENABLED = 0x5u, + EVTDRV_ERR_MMHEAP_INIT_FAILED = 0x5u, EVTDRV_ERR_EVENT_INVALID = 0x10u, EVTDRV_ERR_EVENT_OVERFLOW = 0x11u, diff --git a/kernel/evtdrv/include/tos_evtdrv_sys.h b/kernel/evtdrv/include/tos_evtdrv_sys.h index 43ce8128..76dd1d39 100644 --- a/kernel/evtdrv/include/tos_evtdrv_sys.h +++ b/kernel/evtdrv/include/tos_evtdrv_sys.h @@ -26,7 +26,6 @@ typedef void (*k_evtdrv_poll_t)(void); * @brief Initialize the event-driven system. * * @attention event-driven is a simplified schedule model to support the none-context-switch-based multi-task programming.("the big while 1") - * must enable TOS_CFG_MMHEAP_EN to use event-driven. * * @param[in] tasks array of the tasks. * @param[in] task_table_size size of the tasks. diff --git a/kernel/evtdrv/tos_evtdrv_sys.c b/kernel/evtdrv/tos_evtdrv_sys.c index 3d78e657..448185c1 100644 --- a/kernel/evtdrv/tos_evtdrv_sys.c +++ b/kernel/evtdrv/tos_evtdrv_sys.c @@ -21,6 +21,7 @@ __API__ evtdrv_err_t tos_evtdrv_sys_init(evtdrv_task_entry_t tasks[], evtdrv_ttb_sz_t task_table_size, k_evtdrv_poll_t poll) { + k_err_t kerr; evtdrv_err_t err; evtdrv_task_table = &tasks[0]; @@ -30,12 +31,13 @@ __API__ evtdrv_err_t tos_evtdrv_sys_init(evtdrv_task_entry_t tasks[], evtdrv_ttb #if TOS_CFG_MMHEAP_EN > 0 #if TOS_CFG_MMHEAP_DEFAULT_POOL_EN > 0u - mmheap_init_with_pool(k_mmheap_default_pool, TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE); + kerr = mmheap_init_with_pool(k_mmheap_default_pool, TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE); #else - mmheap_init(); + kerr = mmheap_init(); #endif -#else - return EVTDRV_ERR_MMHEAP_NOT_ENABLED; + if (kerr != K_ERR_NONE) { + return EVTDRV_ERR_MMHEAP_INIT_FAILED; + } #endif err = evtdrv_event_init(); diff --git a/osal/posix/include/private/posix_config_check.h b/osal/posix/include/private/posix_config_check.h index c80387a3..ccfd45b0 100644 --- a/osal/posix/include/private/posix_config_check.h +++ b/osal/posix/include/private/posix_config_check.h @@ -21,10 +21,6 @@ #include "tos_config.h" #include "private/posix_config_default.h" -#if (TOS_CFG_MMHEAP_EN == 0u) -#error "INVALID config, Must enable TOS_CFG_MMHEAP_EN to use posix stuff" -#endif - #if (POSIX_CFG_PTHREAD_COND_EN > 0u) && (TOS_CFG_SEM_EN == 0u) #error "INVALID config, Must enable TOS_CFG_SEM_EN to use pthread_cond" #endif