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