From 5b51d50adef1679a24b29e424e7a8ac8f4601983 Mon Sep 17 00:00:00 2001 From: daishengdong Date: Tue, 2 Jun 2020 15:03:42 +0800 Subject: [PATCH] add ota algorithm for device 1. effective "Differential Upgrade" patch algorithm with high compression rate 2. effective recovery algorithm support recovery firmware in blocks which has low memory consumption and wear-leveling strategies, especially suitable for embeded devices with low RAM. 3. add sample ota bootloader project, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_bootloader_recovery 4. add sample application project for download firmware through http, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_application_download_through_http 5. add sample application project for download firmware through qcloud explorer console, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_application_download_through_qcloud_iot_explorer 6. an OTA markdown document is pending --- board/STM8L052R8T6/IAR/shell/README.md | 6 +- .../BSP/Hardware/ONCHIP_FLASH/onchip_flash.c | 1 + .../Hardware/ONCHIP_FLASH/onchip_flash_ota.c | 6 +- .../TencentOS_tiny.uvoptx | 1412 ++++++++ .../TencentOS_tiny.uvprojx | 922 +++++ .../startup_stm32l431xx.s | 404 +++ .../system_stm32l4xx.c | 337 ++ .../TencentOS_tiny.uvoptx | 3007 +++++++++++++++++ .../TencentOS_tiny.uvprojx | 1577 +++++++++ .../startup_stm32l431xx.s | 404 +++ .../Inc/stm32l4xx_hal_conf.h | 450 +++ .../Inc/stm32l4xx_it.h | 69 + .../MDK-ARM/TencentOS_tiny.uvoptx | 1801 ++++++++++ .../MDK-ARM/TencentOS_tiny.uvprojx | 1037 ++++++ .../MDK-ARM/startup_stm32l431xx.s | 404 +++ .../ota/ota_bootloader_recovery/Src/main.c | 181 + .../Src/stm32l4xx_hal_msp.c | 155 + .../Src/stm32l4xx_it.c | 202 ++ .../Src/system_stm32l4xx.c | 337 ++ .../TOS-CONFIG/event_driven/tos_config.h | 19 + .../TOS-CONFIG/mqtt_config.h | 48 + .../TOS-CONFIG/tickless/tos_config.h | 41 + .../TOS-CONFIG/tos_config.h | 55 + components/ota/common/crc/crc8.c | 42 + components/ota/common/crc/crc8.h | 26 + components/ota/common/diff/bsdiff.c | 496 +++ components/ota/common/diff/bsdiff.h | 26 + components/ota/common/diff/graph.c | 561 +++ components/ota/common/diff/graph.h | 161 + components/ota/common/diff/list.h | 150 + components/ota/common/diff/ota_diff.c | 1364 ++++++++ components/ota/common/diff/ota_diff.h | 154 + components/ota/common/diff/proc_bar.c | 60 + components/ota/common/diff/proc_bar.h | 32 + components/ota/common/diff/segment_tree.c | 233 ++ components/ota/common/diff/segment_tree.h | 50 + components/ota/common/diff/stack.c | 137 + components/ota/common/diff/stack.h | 51 + components/ota/common/diff/topo_sorting.c | 148 + components/ota/common/diff/topo_sorting.h | 44 + components/ota/common/diff/version | 1 + components/ota/common/diff/wstream.c | 126 + components/ota/common/diff/wstream.h | 58 + components/ota/common/env/ota_env.c | 41 + components/ota/common/env/ota_env.h | 28 + components/ota/common/flash/ota_flash.c | 83 + components/ota/common/flash/ota_flash.h | 85 + components/ota/common/image/ota_image.c | 22 + components/ota/common/image/ota_image.h | 32 + components/ota/common/info/ota_info.c | 53 + components/ota/common/info/ota_info.h | 26 + components/ota/common/lzma/3rdparty/7z.h | 202 ++ components/ota/common/lzma/3rdparty/7zAlloc.c | 80 + components/ota/common/lzma/3rdparty/7zAlloc.h | 19 + components/ota/common/lzma/3rdparty/7zArcIn.c | 1771 ++++++++++ components/ota/common/lzma/3rdparty/7zBuf.c | 36 + components/ota/common/lzma/3rdparty/7zBuf.h | 35 + components/ota/common/lzma/3rdparty/7zBuf2.c | 52 + components/ota/common/lzma/3rdparty/7zCrc.c | 128 + components/ota/common/lzma/3rdparty/7zCrc.h | 25 + .../ota/common/lzma/3rdparty/7zCrcOpt.c | 115 + components/ota/common/lzma/3rdparty/7zDec.c | 591 ++++ components/ota/common/lzma/3rdparty/7zFile.c | 286 ++ components/ota/common/lzma/3rdparty/7zFile.h | 83 + .../ota/common/lzma/3rdparty/7zStream.c | 176 + components/ota/common/lzma/3rdparty/7zTypes.h | 375 ++ .../ota/common/lzma/3rdparty/7zVersion.h | 27 + .../ota/common/lzma/3rdparty/7zVersion.rc | 55 + components/ota/common/lzma/3rdparty/Aes.c | 306 ++ components/ota/common/lzma/3rdparty/Aes.h | 38 + components/ota/common/lzma/3rdparty/AesOpt.c | 184 + components/ota/common/lzma/3rdparty/Alloc.c | 455 +++ components/ota/common/lzma/3rdparty/Alloc.h | 51 + components/ota/common/lzma/3rdparty/Bcj2.c | 257 ++ components/ota/common/lzma/3rdparty/Bcj2.h | 146 + components/ota/common/lzma/3rdparty/Bcj2Enc.c | 311 ++ components/ota/common/lzma/3rdparty/Bra.c | 230 ++ components/ota/common/lzma/3rdparty/Bra.h | 64 + components/ota/common/lzma/3rdparty/Bra86.c | 82 + components/ota/common/lzma/3rdparty/BraIA64.c | 53 + .../ota/common/lzma/3rdparty/Compiler.h | 33 + components/ota/common/lzma/3rdparty/CpuArch.c | 218 ++ components/ota/common/lzma/3rdparty/CpuArch.h | 336 ++ components/ota/common/lzma/3rdparty/Delta.c | 64 + components/ota/common/lzma/3rdparty/Delta.h | 19 + .../ota/common/lzma/3rdparty/DllSecur.c | 108 + .../ota/common/lzma/3rdparty/DllSecur.h | 20 + components/ota/common/lzma/3rdparty/LzFind.c | 1127 ++++++ components/ota/common/lzma/3rdparty/LzFind.h | 121 + components/ota/common/lzma/3rdparty/LzHash.h | 57 + .../ota/common/lzma/3rdparty/Lzma2Dec.c | 488 +++ .../ota/common/lzma/3rdparty/Lzma2Dec.h | 120 + .../ota/common/lzma/3rdparty/Lzma2Enc.c | 803 +++++ .../ota/common/lzma/3rdparty/Lzma2Enc.h | 55 + components/ota/common/lzma/3rdparty/Lzma86.h | 111 + .../ota/common/lzma/3rdparty/Lzma86Dec.c | 54 + .../ota/common/lzma/3rdparty/Lzma86Enc.c | 106 + components/ota/common/lzma/3rdparty/LzmaDec.c | 1185 +++++++ components/ota/common/lzma/3rdparty/LzmaDec.h | 234 ++ components/ota/common/lzma/3rdparty/LzmaEnc.c | 2978 ++++++++++++++++ components/ota/common/lzma/3rdparty/LzmaEnc.h | 76 + components/ota/common/lzma/3rdparty/LzmaLib.c | 40 + components/ota/common/lzma/3rdparty/LzmaLib.h | 131 + components/ota/common/lzma/3rdparty/Ppmd.h | 85 + components/ota/common/lzma/3rdparty/Ppmd7.c | 712 ++++ components/ota/common/lzma/3rdparty/Ppmd7.h | 142 + .../ota/common/lzma/3rdparty/Ppmd7Dec.c | 191 ++ .../ota/common/lzma/3rdparty/Ppmd7Enc.c | 187 + components/ota/common/lzma/3rdparty/Precomp.h | 10 + .../ota/common/lzma/3rdparty/RotateDefs.h | 30 + components/ota/common/lzma/3rdparty/Sha256.c | 248 ++ components/ota/common/lzma/3rdparty/Sha256.h | 26 + components/ota/common/lzma/3rdparty/Sort.c | 141 + components/ota/common/lzma/3rdparty/Sort.h | 18 + components/ota/common/lzma/3rdparty/Xz.c | 90 + components/ota/common/lzma/3rdparty/Xz.h | 460 +++ components/ota/common/lzma/3rdparty/XzCrc64.c | 86 + components/ota/common/lzma/3rdparty/XzCrc64.h | 26 + .../ota/common/lzma/3rdparty/XzCrc64Opt.c | 69 + components/ota/common/lzma/3rdparty/XzDec.c | 2768 +++++++++++++++ components/ota/common/lzma/3rdparty/XzEnc.c | 1329 ++++++++ components/ota/common/lzma/3rdparty/XzEnc.h | 60 + components/ota/common/lzma/3rdparty/XzIn.c | 319 ++ components/ota/common/lzma/version | 1 + .../ota/common/lzma/wrapper/lzma_compress.c | 87 + .../ota/common/lzma/wrapper/lzma_compress.h | 28 + components/ota/common/lzma/wrapper/lzma_err.h | 46 + .../ota/common/lzma/wrapper/lzma_uncompress.c | 75 + .../ota/common/lzma/wrapper/lzma_uncompress.h | 28 + .../ota/common/partition/ota_partition.c | 172 + .../ota/common/partition/ota_partition.h | 158 + components/ota/download/include/hal_tcp.h | 30 + .../ota/download/include/ota_download.h | 33 + .../ota/download/include/ota_download_http.h | 46 + .../protocol/http/ota_download_http.c | 283 ++ .../tcp/module/hal_tcp_module.c | 67 + components/ota/recovery/include/ota_patch.h | 88 + .../ota/recovery/include/ota_recovery.h | 32 + components/ota/recovery/ota_patch.c | 370 ++ components/ota/recovery/ota_patch_xip.c | 334 ++ components/ota/recovery/ota_recovery.c | 193 ++ components/ota/recovery/ota_recovery_xip.c | 152 + components/ota/tools/diff/Makefile | 55 + components/ota/tools/diff/src/main.c | 308 ++ components/ota/tools/partition_table/Makefile | 50 + .../ota/tools/partition_table/src/main.c | 254 ++ .../wrapper/include/qcloud/dtls_psk_config.h | 2 + .../wrapper/include/qcloud/tls_psk_config.h | 2 + .../ota_download_through_http_sample.c | 65 + .../entry.c} | 20 +- ...nload_through_qcloud_iot_explorer_sample.c | 503 +++ .../ota_mqtt_sample.c | 16 +- examples/tencent_cloud_sdk_coap/coap_sample.c | 151 - .../tencent_cloud_sdk_coap.c | 46 - .../light_data_template_sample.c | 671 ---- .../tencent_cloud_sdk_explorer.c | 46 - examples/tencent_cloud_sdk_mqtt/mqtt_sample.c | 189 -- kernel/core/include/tos_binary_heap.h | 4 - kernel/core/include/tos_char_fifo.h | 4 - kernel/core/include/tos_config_check.h | 4 - kernel/core/include/tos_config_default.h | 2 +- kernel/core/include/tos_mail_queue.h | 4 - kernel/core/include/tos_message_queue.h | 4 - kernel/core/include/tos_priority_queue.h | 4 - kernel/core/include/tos_ring_queue.h | 5 - kernel/core/include/tos_sys.h | 4 - kernel/core/tos_binary_heap.c | 12 +- kernel/core/tos_char_fifo.c | 10 - kernel/core/tos_mail_queue.c | 10 - kernel/core/tos_message_queue.c | 10 - kernel/core/tos_priority_queue.c | 10 - kernel/core/tos_ring_queue.c | 10 - kernel/core/tos_task.c | 6 +- kernel/evtdrv/include/tos_evtdrv_err.h | 2 +- kernel/evtdrv/include/tos_evtdrv_sys.h | 1 - kernel/evtdrv/tos_evtdrv_sys.c | 10 +- .../include/private/posix_config_check.h | 4 - 177 files changed, 42367 insertions(+), 1233 deletions(-) create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvoptx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/TencentOS_tiny.uvprojx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/startup_stm32l431xx.s create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_http/system_stm32l4xx.c create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvoptx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/TencentOS_tiny.uvprojx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_application_download_through_qcloud_iot_explorer/startup_stm32l431xx.s create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_hal_conf.h create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Inc/stm32l4xx_it.h create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvoptx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/TencentOS_tiny.uvprojx create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/MDK-ARM/startup_stm32l431xx.s create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/main.c create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_hal_msp.c create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/stm32l4xx_it.c create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/Src/system_stm32l4xx.c create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/event_driven/tos_config.h create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/mqtt_config.h create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tickless/tos_config.h create mode 100644 board/TencentOS_tiny_EVB_MX_Plus/KEIL/ota/ota_bootloader_recovery/TOS-CONFIG/tos_config.h create mode 100644 components/ota/common/crc/crc8.c create mode 100644 components/ota/common/crc/crc8.h create mode 100644 components/ota/common/diff/bsdiff.c create mode 100644 components/ota/common/diff/bsdiff.h create mode 100644 components/ota/common/diff/graph.c create mode 100644 components/ota/common/diff/graph.h create mode 100644 components/ota/common/diff/list.h create mode 100644 components/ota/common/diff/ota_diff.c create mode 100644 components/ota/common/diff/ota_diff.h create mode 100644 components/ota/common/diff/proc_bar.c create mode 100644 components/ota/common/diff/proc_bar.h create mode 100644 components/ota/common/diff/segment_tree.c create mode 100644 components/ota/common/diff/segment_tree.h create mode 100644 components/ota/common/diff/stack.c create mode 100644 components/ota/common/diff/stack.h create mode 100644 components/ota/common/diff/topo_sorting.c create mode 100644 components/ota/common/diff/topo_sorting.h create mode 100644 components/ota/common/diff/version create mode 100644 components/ota/common/diff/wstream.c create mode 100644 components/ota/common/diff/wstream.h create mode 100644 components/ota/common/env/ota_env.c create mode 100644 components/ota/common/env/ota_env.h create mode 100644 components/ota/common/flash/ota_flash.c create mode 100644 components/ota/common/flash/ota_flash.h create mode 100644 components/ota/common/image/ota_image.c create mode 100644 components/ota/common/image/ota_image.h create mode 100644 components/ota/common/info/ota_info.c create mode 100644 components/ota/common/info/ota_info.h create mode 100644 components/ota/common/lzma/3rdparty/7z.h create mode 100644 components/ota/common/lzma/3rdparty/7zAlloc.c create mode 100644 components/ota/common/lzma/3rdparty/7zAlloc.h create mode 100644 components/ota/common/lzma/3rdparty/7zArcIn.c create mode 100644 components/ota/common/lzma/3rdparty/7zBuf.c create mode 100644 components/ota/common/lzma/3rdparty/7zBuf.h create mode 100644 components/ota/common/lzma/3rdparty/7zBuf2.c create mode 100644 components/ota/common/lzma/3rdparty/7zCrc.c create mode 100644 components/ota/common/lzma/3rdparty/7zCrc.h create mode 100644 components/ota/common/lzma/3rdparty/7zCrcOpt.c create mode 100644 components/ota/common/lzma/3rdparty/7zDec.c create mode 100644 components/ota/common/lzma/3rdparty/7zFile.c create mode 100644 components/ota/common/lzma/3rdparty/7zFile.h create mode 100644 components/ota/common/lzma/3rdparty/7zStream.c create mode 100644 components/ota/common/lzma/3rdparty/7zTypes.h create mode 100644 components/ota/common/lzma/3rdparty/7zVersion.h create mode 100644 components/ota/common/lzma/3rdparty/7zVersion.rc create mode 100644 components/ota/common/lzma/3rdparty/Aes.c create mode 100644 components/ota/common/lzma/3rdparty/Aes.h create mode 100644 components/ota/common/lzma/3rdparty/AesOpt.c create mode 100644 components/ota/common/lzma/3rdparty/Alloc.c create mode 100644 components/ota/common/lzma/3rdparty/Alloc.h create mode 100644 components/ota/common/lzma/3rdparty/Bcj2.c create mode 100644 components/ota/common/lzma/3rdparty/Bcj2.h create mode 100644 components/ota/common/lzma/3rdparty/Bcj2Enc.c create mode 100644 components/ota/common/lzma/3rdparty/Bra.c create mode 100644 components/ota/common/lzma/3rdparty/Bra.h create mode 100644 components/ota/common/lzma/3rdparty/Bra86.c create mode 100644 components/ota/common/lzma/3rdparty/BraIA64.c create mode 100644 components/ota/common/lzma/3rdparty/Compiler.h create mode 100644 components/ota/common/lzma/3rdparty/CpuArch.c create mode 100644 components/ota/common/lzma/3rdparty/CpuArch.h create mode 100644 components/ota/common/lzma/3rdparty/Delta.c create mode 100644 components/ota/common/lzma/3rdparty/Delta.h create mode 100644 components/ota/common/lzma/3rdparty/DllSecur.c create mode 100644 components/ota/common/lzma/3rdparty/DllSecur.h create mode 100644 components/ota/common/lzma/3rdparty/LzFind.c create mode 100644 components/ota/common/lzma/3rdparty/LzFind.h create mode 100644 components/ota/common/lzma/3rdparty/LzHash.h create mode 100644 components/ota/common/lzma/3rdparty/Lzma2Dec.c create mode 100644 components/ota/common/lzma/3rdparty/Lzma2Dec.h create mode 100644 components/ota/common/lzma/3rdparty/Lzma2Enc.c create mode 100644 components/ota/common/lzma/3rdparty/Lzma2Enc.h create mode 100644 components/ota/common/lzma/3rdparty/Lzma86.h create mode 100644 components/ota/common/lzma/3rdparty/Lzma86Dec.c create mode 100644 components/ota/common/lzma/3rdparty/Lzma86Enc.c create mode 100644 components/ota/common/lzma/3rdparty/LzmaDec.c create mode 100644 components/ota/common/lzma/3rdparty/LzmaDec.h create mode 100644 components/ota/common/lzma/3rdparty/LzmaEnc.c create mode 100644 components/ota/common/lzma/3rdparty/LzmaEnc.h create mode 100644 components/ota/common/lzma/3rdparty/LzmaLib.c create mode 100644 components/ota/common/lzma/3rdparty/LzmaLib.h create mode 100644 components/ota/common/lzma/3rdparty/Ppmd.h create mode 100644 components/ota/common/lzma/3rdparty/Ppmd7.c create mode 100644 components/ota/common/lzma/3rdparty/Ppmd7.h create mode 100644 components/ota/common/lzma/3rdparty/Ppmd7Dec.c create mode 100644 components/ota/common/lzma/3rdparty/Ppmd7Enc.c create mode 100644 components/ota/common/lzma/3rdparty/Precomp.h create mode 100644 components/ota/common/lzma/3rdparty/RotateDefs.h create mode 100644 components/ota/common/lzma/3rdparty/Sha256.c create mode 100644 components/ota/common/lzma/3rdparty/Sha256.h create mode 100644 components/ota/common/lzma/3rdparty/Sort.c create mode 100644 components/ota/common/lzma/3rdparty/Sort.h create mode 100644 components/ota/common/lzma/3rdparty/Xz.c create mode 100644 components/ota/common/lzma/3rdparty/Xz.h create mode 100644 components/ota/common/lzma/3rdparty/XzCrc64.c create mode 100644 components/ota/common/lzma/3rdparty/XzCrc64.h create mode 100644 components/ota/common/lzma/3rdparty/XzCrc64Opt.c create mode 100644 components/ota/common/lzma/3rdparty/XzDec.c create mode 100644 components/ota/common/lzma/3rdparty/XzEnc.c create mode 100644 components/ota/common/lzma/3rdparty/XzEnc.h create mode 100644 components/ota/common/lzma/3rdparty/XzIn.c create mode 100644 components/ota/common/lzma/version create mode 100644 components/ota/common/lzma/wrapper/lzma_compress.c create mode 100644 components/ota/common/lzma/wrapper/lzma_compress.h create mode 100644 components/ota/common/lzma/wrapper/lzma_err.h create mode 100644 components/ota/common/lzma/wrapper/lzma_uncompress.c create mode 100644 components/ota/common/lzma/wrapper/lzma_uncompress.h create mode 100644 components/ota/common/partition/ota_partition.c create mode 100644 components/ota/common/partition/ota_partition.h create mode 100644 components/ota/download/include/hal_tcp.h create mode 100644 components/ota/download/include/ota_download.h create mode 100644 components/ota/download/include/ota_download_http.h create mode 100644 components/ota/download/protocol/http/ota_download_http.c create mode 100644 components/ota/download/transport_layer/tcp/module/hal_tcp_module.c create mode 100644 components/ota/recovery/include/ota_patch.h create mode 100644 components/ota/recovery/include/ota_recovery.h create mode 100644 components/ota/recovery/ota_patch.c create mode 100644 components/ota/recovery/ota_patch_xip.c create mode 100644 components/ota/recovery/ota_recovery.c create mode 100644 components/ota/recovery/ota_recovery_xip.c create mode 100644 components/ota/tools/diff/Makefile create mode 100644 components/ota/tools/diff/src/main.c create mode 100644 components/ota/tools/partition_table/Makefile create mode 100644 components/ota/tools/partition_table/src/main.c create mode 100644 examples/ota_download_through_http/ota_download_through_http_sample.c rename examples/{tencent_cloud_sdk_mqtt/tencent_cloud_sdk_mqtt.c => ota_download_through_qcloud_iot_explorer/entry.c} (65%) create mode 100644 examples/ota_download_through_qcloud_iot_explorer/ota_download_through_qcloud_iot_explorer_sample.c delete mode 100644 examples/tencent_cloud_sdk_coap/coap_sample.c delete mode 100644 examples/tencent_cloud_sdk_coap/tencent_cloud_sdk_coap.c delete mode 100644 examples/tencent_cloud_sdk_data_template/light_data_template_sample.c delete mode 100644 examples/tencent_cloud_sdk_data_template/tencent_cloud_sdk_explorer.c delete mode 100644 examples/tencent_cloud_sdk_mqtt/mqtt_sample.c 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